package model //排行榜数据 import ( "github.com/globalsign/mgo/bson" "mongo.games.com/goserver/core/logger" "sort" "time" ) type RankPlayerData struct { SnId int32 Name string Val int64 } type RankData struct { Id bson.ObjectId Key string Data []*RankPlayerData //排行榜内已排好顺序的玩家信息 } // 适用于小榜,比如总榜数量<=100,大榜适合用跳表实现 func (rd *RankData) Insert(data *RankPlayerData, add bool) { cnt := len(rd.Data) idx := sort.Search(cnt, func(i int) bool { return rd.Data[i].Val <= data.Val }) if add { rd.Data = append(rd.Data, nil) } if idx != cnt { copy(rd.Data[idx+1:], rd.Data[idx:cnt]) } cnt = len(rd.Data) //索引确保 if idx >= cnt { idx = cnt - 1 } //当前数据放到idx位置 rd.Data[idx] = data } func (rd *RankData) Sort() { less := func(i, j int) bool { //倒序 return rd.Data[i].Val > rd.Data[j].Val } if !sort.SliceIsSorted(rd.Data, less) { sort.Slice(rd.Data, less) } } func (rd *RankData) Clone() *RankData { nrd := &RankData{ Id: rd.Id, Key: rd.Key, Data: make([]*RankPlayerData, len(rd.Data)), } copy(nrd.Data, rd.Data) return nrd } func InitRankData(plt string) []*RankData { if rpcCli == nil { return nil } var data []*RankData err := rpcCli.CallWithTimeout("RankDataSvc.InitRankData", plt, &data, time.Second*30) if err != nil { logger.Logger.Errorf("InitRankDBData err:%v", err) return nil } return data } type SaveRankDataArgs struct { Plt string Key string Data *RankData } func SaveRankData(plt, key string, data *RankData) error { if rpcCli == nil { return ErrRPClientNoConn } args := &SaveRankDataArgs{ Plt: plt, Key: key, Data: data, } var ret bool return rpcCli.CallWithTimeout("RankDataSvc.SaveRankData", args, &ret, time.Second*30) }