[手游项目3]-5-游戏登录排队

游戏登录排队主要是考虑排名的性能问题,很多插入删除查询操作
go的map是无序的不好做排名而数组查询效率低
需要一个有序的map,有序的map可以保证先进先出,顺序不会被打乱
但是名次问题需要一个的算法

login_que.go 实现有序map

package service

import (
	"container/list"
	"time"
)

var MapService = NewMapList()

type MapList struct {
	dataMap    map[string]*list.Element
	dataList   *list.List
	QueueIndex int32
}

func NewMapList() *MapList {
	return &MapList{
		dataMap:    make(map[string]*list.Element),
		dataList:   list.New(),
		QueueIndex: 1,
	}
}

func (mapList *MapList) Exists(key string) bool {
	_, exists := mapList.dataMap[key]
	return exists
}

func (mapList *MapList) UpDateTime(key string) {
	info, exists := mapList.dataMap[key]
	if exists {
		return
	}
	info.Value.(*AccountLogin).time = time.Now().Unix()
}

func (mapList *MapList) GetRank(key string) int32 {
	info, exists := mapList.dataMap[key]
	if exists {
		return info.Value.(*AccountLogin).rank
	}
	return 999
}

func (mapList *MapList) Push(data AccountLogin) bool {
	if mapList.Exists(data.account) {
		return false
	}
	elem := mapList.dataList.PushBack(data)
	mapList.dataMap[data.account] = elem
	return true
}

func (mapList *MapList) Remove(key string) {
	if !mapList.Exists(key) {
		return
	}
	mapList.dataList.Remove(mapList.dataMap[key])
	delete(mapList.dataMap, key)
}

func (mapList *MapList) Size() int {
	return mapList.dataList.Len()
}

type AccountLogin struct {
	account string
	rank    int32
	time    int64
}

func (e AccountLogin) GetAccount() string {
	return e.account
}

下面排队算法

	//排队逻辑
	nOnlineNum := rolemanager.RoleManager.GetOnlineNum()
	if service.Maxlimit <= nOnlineNum {
		//取消排队 不用返回协议
		if reqMsg.LoginType == 2 {
			MapService.Remove(accountId)
			return nil
		}
		nSize := int32(MapService.Size())
		for i := int32(0); i < nSize; i++ {
			//第一名的掉线了
			first := MapService.dataList.Front()
			if first == nil {
				break
			}
			heartTime := first.Value.(*AccountLogin).time
			if 10 < time.Now().Unix()-heartTime {
				MapService.Remove(first.Value.(*AccountLogin).account)
			} else {
				break
			}
		}
		if MapService.Exists(accountId) { //已经在队列里面
			nRank := MapService.GetRank(accountId)                           //名次编号
			loginResult.QueueIndex = nRank - (MapService.QueueIndex - nSize) //真实名次
			if loginResult.QueueIndex < 1 {
				loginResult.QueueIndex = 1
			}
			if loginResult.QueueIndex <= 1 { //我是第一名
				MapService.Remove(accountId)
			} else { //排队
				MapService.UpDateTime(accountId)
				loginResult.LoginResult = message.Growth_ResRoleLogin_LOGIN_QUEUE
				return session.Send(message.MSGID_Growth_ResRoleLoginE, loginResult)
			}
		} else { //排队
			loginResult.QueueIndex = nSize + 1
			Ele := AccountLogin{accountId, MapService.QueueIndex, time.Now().Unix()}
			MapService.Push(Ele)
			MapService.QueueIndex++
			loginResult.LoginResult = message.Growth_ResRoleLogin_LOGIN_QUEUE
			return session.Send(message.MSGID_Growth_ResRoleLoginE, loginResult)
		}
	}

猜你喜欢

转载自blog.csdn.net/q277055799/article/details/88526524