From 95b4e2f8dea287f118d1d95303288bda30139ef8 Mon Sep 17 00:00:00 2001 From: orgin Date: Fri, 18 Nov 2022 15:45:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=8E=92=E8=A1=8C=E6=A6=9C?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rpc/rank.pb.go | 3000 +++++++++++++++++++++++ sysservice/rankservice/RankData.go | 96 + sysservice/rankservice/RankFunc.go | 52 + sysservice/rankservice/RankInterface.go | 52 + sysservice/rankservice/RankService.go | 195 ++ sysservice/rankservice/RankSkip.go | 262 ++ sysservice/rankservice/rank.proto | 76 + util/algorithms/skip/interface.go | 47 + util/algorithms/skip/iterator.go | 86 + util/algorithms/skip/node.go | 50 + util/algorithms/skip/skip.go | 494 ++++ 11 files changed, 4410 insertions(+) create mode 100644 rpc/rank.pb.go create mode 100644 sysservice/rankservice/RankData.go create mode 100644 sysservice/rankservice/RankFunc.go create mode 100644 sysservice/rankservice/RankInterface.go create mode 100644 sysservice/rankservice/RankService.go create mode 100644 sysservice/rankservice/RankSkip.go create mode 100644 sysservice/rankservice/rank.proto create mode 100644 util/algorithms/skip/interface.go create mode 100644 util/algorithms/skip/iterator.go create mode 100644 util/algorithms/skip/node.go create mode 100644 util/algorithms/skip/skip.go diff --git a/rpc/rank.pb.go b/rpc/rank.pb.go new file mode 100644 index 0000000..46a9bbc --- /dev/null +++ b/rpc/rank.pb.go @@ -0,0 +1,3000 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: proto/rpcproto/rank.proto + +package rpc + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// RankData 排行数据 +type RankData struct { + Key uint64 `protobuf:"varint,1,opt,name=Key,proto3" json:"Key,omitempty"` + SortData []int64 `protobuf:"varint,2,rep,packed,name=SortData,proto3" json:"SortData,omitempty"` + Data []byte `protobuf:"bytes,3,opt,name=Data,proto3" json:"Data,omitempty"` + ExpireMs int64 `protobuf:"varint,4,opt,name=expireMs,proto3" json:"expireMs,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RankData) Reset() { *m = RankData{} } +func (m *RankData) String() string { return proto.CompactTextString(m) } +func (*RankData) ProtoMessage() {} +func (*RankData) Descriptor() ([]byte, []int) { + return fileDescriptor_d5b64eda47521620, []int{0} +} +func (m *RankData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RankData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RankData.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RankData) XXX_Merge(src proto.Message) { + xxx_messageInfo_RankData.Merge(m, src) +} +func (m *RankData) XXX_Size() int { + return m.Size() +} +func (m *RankData) XXX_DiscardUnknown() { + xxx_messageInfo_RankData.DiscardUnknown(m) +} + +var xxx_messageInfo_RankData proto.InternalMessageInfo + +func (m *RankData) GetKey() uint64 { + if m != nil { + return m.Key + } + return 0 +} + +func (m *RankData) GetSortData() []int64 { + if m != nil { + return m.SortData + } + return nil +} + +func (m *RankData) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func (m *RankData) GetExpireMs() int64 { + if m != nil { + return m.ExpireMs + } + return 0 +} + +// RankPosData 排行数据——查询返回 +type RankPosData struct { + Key uint64 `protobuf:"varint,1,opt,name=Key,proto3" json:"Key,omitempty"` + RankPos uint64 `protobuf:"varint,2,opt,name=RankPos,proto3" json:"RankPos,omitempty"` + SortData []int64 `protobuf:"varint,3,rep,packed,name=SortData,proto3" json:"SortData,omitempty"` + Data []byte `protobuf:"bytes,4,opt,name=Data,proto3" json:"Data,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RankPosData) Reset() { *m = RankPosData{} } +func (m *RankPosData) String() string { return proto.CompactTextString(m) } +func (*RankPosData) ProtoMessage() {} +func (*RankPosData) Descriptor() ([]byte, []int) { + return fileDescriptor_d5b64eda47521620, []int{1} +} +func (m *RankPosData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RankPosData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RankPosData.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RankPosData) XXX_Merge(src proto.Message) { + xxx_messageInfo_RankPosData.Merge(m, src) +} +func (m *RankPosData) XXX_Size() int { + return m.Size() +} +func (m *RankPosData) XXX_DiscardUnknown() { + xxx_messageInfo_RankPosData.DiscardUnknown(m) +} + +var xxx_messageInfo_RankPosData proto.InternalMessageInfo + +func (m *RankPosData) GetKey() uint64 { + if m != nil { + return m.Key + } + return 0 +} + +func (m *RankPosData) GetRankPos() uint64 { + if m != nil { + return m.RankPos + } + return 0 +} + +func (m *RankPosData) GetSortData() []int64 { + if m != nil { + return m.SortData + } + return nil +} + +func (m *RankPosData) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +// RankList 排行榜数据 +type RankList struct { + RankId uint64 `protobuf:"varint,1,opt,name=RankId,proto3" json:"RankId,omitempty"` + SkipListLevel int32 `protobuf:"varint,2,opt,name=SkipListLevel,proto3" json:"SkipListLevel,omitempty"` + IsDec bool `protobuf:"varint,3,opt,name=IsDec,proto3" json:"IsDec,omitempty"` + MaxRank uint64 `protobuf:"varint,4,opt,name=MaxRank,proto3" json:"MaxRank,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RankList) Reset() { *m = RankList{} } +func (m *RankList) String() string { return proto.CompactTextString(m) } +func (*RankList) ProtoMessage() {} +func (*RankList) Descriptor() ([]byte, []int) { + return fileDescriptor_d5b64eda47521620, []int{2} +} +func (m *RankList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RankList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RankList.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RankList) XXX_Merge(src proto.Message) { + xxx_messageInfo_RankList.Merge(m, src) +} +func (m *RankList) XXX_Size() int { + return m.Size() +} +func (m *RankList) XXX_DiscardUnknown() { + xxx_messageInfo_RankList.DiscardUnknown(m) +} + +var xxx_messageInfo_RankList proto.InternalMessageInfo + +func (m *RankList) GetRankId() uint64 { + if m != nil { + return m.RankId + } + return 0 +} + +func (m *RankList) GetSkipListLevel() int32 { + if m != nil { + return m.SkipListLevel + } + return 0 +} + +func (m *RankList) GetIsDec() bool { + if m != nil { + return m.IsDec + } + return false +} + +func (m *RankList) GetMaxRank() uint64 { + if m != nil { + return m.MaxRank + } + return 0 +} + +// UpsetRankData 更新排行榜数据 +type UpsetRankData struct { + RankId uint64 `protobuf:"varint,1,opt,name=RankId,proto3" json:"RankId,omitempty"` + RankDataList []*RankData `protobuf:"bytes,2,rep,name=RankDataList,proto3" json:"RankDataList,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UpsetRankData) Reset() { *m = UpsetRankData{} } +func (m *UpsetRankData) String() string { return proto.CompactTextString(m) } +func (*UpsetRankData) ProtoMessage() {} +func (*UpsetRankData) Descriptor() ([]byte, []int) { + return fileDescriptor_d5b64eda47521620, []int{3} +} +func (m *UpsetRankData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *UpsetRankData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_UpsetRankData.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *UpsetRankData) XXX_Merge(src proto.Message) { + xxx_messageInfo_UpsetRankData.Merge(m, src) +} +func (m *UpsetRankData) XXX_Size() int { + return m.Size() +} +func (m *UpsetRankData) XXX_DiscardUnknown() { + xxx_messageInfo_UpsetRankData.DiscardUnknown(m) +} + +var xxx_messageInfo_UpsetRankData proto.InternalMessageInfo + +func (m *UpsetRankData) GetRankId() uint64 { + if m != nil { + return m.RankId + } + return 0 +} + +func (m *UpsetRankData) GetRankDataList() []*RankData { + if m != nil { + return m.RankDataList + } + return nil +} + +// DeleteByKey 更新排行榜数据 +type DeleteByKey struct { + RankId uint64 `protobuf:"varint,1,opt,name=RankId,proto3" json:"RankId,omitempty"` + KeyList []uint64 `protobuf:"varint,2,rep,packed,name=KeyList,proto3" json:"KeyList,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeleteByKey) Reset() { *m = DeleteByKey{} } +func (m *DeleteByKey) String() string { return proto.CompactTextString(m) } +func (*DeleteByKey) ProtoMessage() {} +func (*DeleteByKey) Descriptor() ([]byte, []int) { + return fileDescriptor_d5b64eda47521620, []int{4} +} +func (m *DeleteByKey) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DeleteByKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DeleteByKey.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DeleteByKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeleteByKey.Merge(m, src) +} +func (m *DeleteByKey) XXX_Size() int { + return m.Size() +} +func (m *DeleteByKey) XXX_DiscardUnknown() { + xxx_messageInfo_DeleteByKey.DiscardUnknown(m) +} + +var xxx_messageInfo_DeleteByKey proto.InternalMessageInfo + +func (m *DeleteByKey) GetRankId() uint64 { + if m != nil { + return m.RankId + } + return 0 +} + +func (m *DeleteByKey) GetKeyList() []uint64 { + if m != nil { + return m.KeyList + } + return nil +} + +// AddRankList 新增排行榜 +type AddRankList struct { + AddList []*RankList `protobuf:"bytes,1,rep,name=AddList,proto3" json:"AddList,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AddRankList) Reset() { *m = AddRankList{} } +func (m *AddRankList) String() string { return proto.CompactTextString(m) } +func (*AddRankList) ProtoMessage() {} +func (*AddRankList) Descriptor() ([]byte, []int) { + return fileDescriptor_d5b64eda47521620, []int{5} +} +func (m *AddRankList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AddRankList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AddRankList.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *AddRankList) XXX_Merge(src proto.Message) { + xxx_messageInfo_AddRankList.Merge(m, src) +} +func (m *AddRankList) XXX_Size() int { + return m.Size() +} +func (m *AddRankList) XXX_DiscardUnknown() { + xxx_messageInfo_AddRankList.DiscardUnknown(m) +} + +var xxx_messageInfo_AddRankList proto.InternalMessageInfo + +func (m *AddRankList) GetAddList() []*RankList { + if m != nil { + return m.AddList + } + return nil +} + +// FindRankDataByKey 查找排行信息 +type FindRankDataByKey struct { + RankId uint64 `protobuf:"varint,1,opt,name=RankId,proto3" json:"RankId,omitempty"` + Key uint64 `protobuf:"varint,2,opt,name=Key,proto3" json:"Key,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FindRankDataByKey) Reset() { *m = FindRankDataByKey{} } +func (m *FindRankDataByKey) String() string { return proto.CompactTextString(m) } +func (*FindRankDataByKey) ProtoMessage() {} +func (*FindRankDataByKey) Descriptor() ([]byte, []int) { + return fileDescriptor_d5b64eda47521620, []int{6} +} +func (m *FindRankDataByKey) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *FindRankDataByKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_FindRankDataByKey.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *FindRankDataByKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_FindRankDataByKey.Merge(m, src) +} +func (m *FindRankDataByKey) XXX_Size() int { + return m.Size() +} +func (m *FindRankDataByKey) XXX_DiscardUnknown() { + xxx_messageInfo_FindRankDataByKey.DiscardUnknown(m) +} + +var xxx_messageInfo_FindRankDataByKey proto.InternalMessageInfo + +func (m *FindRankDataByKey) GetRankId() uint64 { + if m != nil { + return m.RankId + } + return 0 +} + +func (m *FindRankDataByKey) GetKey() uint64 { + if m != nil { + return m.Key + } + return 0 +} + +// FindRankDataByPos 查找排行信息 +type FindRankDataByPos struct { + RankId uint64 `protobuf:"varint,1,opt,name=RankId,proto3" json:"RankId,omitempty"` + Pos uint64 `protobuf:"varint,2,opt,name=Pos,proto3" json:"Pos,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FindRankDataByPos) Reset() { *m = FindRankDataByPos{} } +func (m *FindRankDataByPos) String() string { return proto.CompactTextString(m) } +func (*FindRankDataByPos) ProtoMessage() {} +func (*FindRankDataByPos) Descriptor() ([]byte, []int) { + return fileDescriptor_d5b64eda47521620, []int{7} +} +func (m *FindRankDataByPos) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *FindRankDataByPos) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_FindRankDataByPos.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *FindRankDataByPos) XXX_Merge(src proto.Message) { + xxx_messageInfo_FindRankDataByPos.Merge(m, src) +} +func (m *FindRankDataByPos) XXX_Size() int { + return m.Size() +} +func (m *FindRankDataByPos) XXX_DiscardUnknown() { + xxx_messageInfo_FindRankDataByPos.DiscardUnknown(m) +} + +var xxx_messageInfo_FindRankDataByPos proto.InternalMessageInfo + +func (m *FindRankDataByPos) GetRankId() uint64 { + if m != nil { + return m.RankId + } + return 0 +} + +func (m *FindRankDataByPos) GetPos() uint64 { + if m != nil { + return m.Pos + } + return 0 +} + +// FindRankDataListStartTo 查找排行信息,StartPos开始Count个 +type FindRankDataListStartTo struct { + RankId uint64 `protobuf:"varint,1,opt,name=RankId,proto3" json:"RankId,omitempty"` + StartPos uint64 `protobuf:"varint,2,opt,name=StartPos,proto3" json:"StartPos,omitempty"` + Count uint64 `protobuf:"varint,3,opt,name=Count,proto3" json:"Count,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FindRankDataListStartTo) Reset() { *m = FindRankDataListStartTo{} } +func (m *FindRankDataListStartTo) String() string { return proto.CompactTextString(m) } +func (*FindRankDataListStartTo) ProtoMessage() {} +func (*FindRankDataListStartTo) Descriptor() ([]byte, []int) { + return fileDescriptor_d5b64eda47521620, []int{8} +} +func (m *FindRankDataListStartTo) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *FindRankDataListStartTo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_FindRankDataListStartTo.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *FindRankDataListStartTo) XXX_Merge(src proto.Message) { + xxx_messageInfo_FindRankDataListStartTo.Merge(m, src) +} +func (m *FindRankDataListStartTo) XXX_Size() int { + return m.Size() +} +func (m *FindRankDataListStartTo) XXX_DiscardUnknown() { + xxx_messageInfo_FindRankDataListStartTo.DiscardUnknown(m) +} + +var xxx_messageInfo_FindRankDataListStartTo proto.InternalMessageInfo + +func (m *FindRankDataListStartTo) GetRankId() uint64 { + if m != nil { + return m.RankId + } + return 0 +} + +func (m *FindRankDataListStartTo) GetStartPos() uint64 { + if m != nil { + return m.StartPos + } + return 0 +} + +func (m *FindRankDataListStartTo) GetCount() uint64 { + if m != nil { + return m.Count + } + return 0 +} + +// RankDataList +type RankDataList struct { + RankDataCount uint64 `protobuf:"varint,1,opt,name=RankDataCount,proto3" json:"RankDataCount,omitempty"` + RankPosDataList []*RankPosData `protobuf:"bytes,2,rep,name=RankPosDataList,proto3" json:"RankPosDataList,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RankDataList) Reset() { *m = RankDataList{} } +func (m *RankDataList) String() string { return proto.CompactTextString(m) } +func (*RankDataList) ProtoMessage() {} +func (*RankDataList) Descriptor() ([]byte, []int) { + return fileDescriptor_d5b64eda47521620, []int{9} +} +func (m *RankDataList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RankDataList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RankDataList.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RankDataList) XXX_Merge(src proto.Message) { + xxx_messageInfo_RankDataList.Merge(m, src) +} +func (m *RankDataList) XXX_Size() int { + return m.Size() +} +func (m *RankDataList) XXX_DiscardUnknown() { + xxx_messageInfo_RankDataList.DiscardUnknown(m) +} + +var xxx_messageInfo_RankDataList proto.InternalMessageInfo + +func (m *RankDataList) GetRankDataCount() uint64 { + if m != nil { + return m.RankDataCount + } + return 0 +} + +func (m *RankDataList) GetRankPosDataList() []*RankPosData { + if m != nil { + return m.RankPosDataList + } + return nil +} + +// RankResult +type RankResult struct { + AddCount int32 `protobuf:"varint,1,opt,name=AddCount,proto3" json:"AddCount,omitempty"` + RemoveCount int32 `protobuf:"varint,2,opt,name=RemoveCount,proto3" json:"RemoveCount,omitempty"` + ModifyCount int32 `protobuf:"varint,3,opt,name=ModifyCount,proto3" json:"ModifyCount,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RankResult) Reset() { *m = RankResult{} } +func (m *RankResult) String() string { return proto.CompactTextString(m) } +func (*RankResult) ProtoMessage() {} +func (*RankResult) Descriptor() ([]byte, []int) { + return fileDescriptor_d5b64eda47521620, []int{10} +} +func (m *RankResult) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RankResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RankResult.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RankResult) XXX_Merge(src proto.Message) { + xxx_messageInfo_RankResult.Merge(m, src) +} +func (m *RankResult) XXX_Size() int { + return m.Size() +} +func (m *RankResult) XXX_DiscardUnknown() { + xxx_messageInfo_RankResult.DiscardUnknown(m) +} + +var xxx_messageInfo_RankResult proto.InternalMessageInfo + +func (m *RankResult) GetAddCount() int32 { + if m != nil { + return m.AddCount + } + return 0 +} + +func (m *RankResult) GetRemoveCount() int32 { + if m != nil { + return m.RemoveCount + } + return 0 +} + +func (m *RankResult) GetModifyCount() int32 { + if m != nil { + return m.ModifyCount + } + return 0 +} + +func init() { + proto.RegisterType((*RankData)(nil), "rpc.RankData") + proto.RegisterType((*RankPosData)(nil), "rpc.RankPosData") + proto.RegisterType((*RankList)(nil), "rpc.RankList") + proto.RegisterType((*UpsetRankData)(nil), "rpc.UpsetRankData") + proto.RegisterType((*DeleteByKey)(nil), "rpc.DeleteByKey") + proto.RegisterType((*AddRankList)(nil), "rpc.AddRankList") + proto.RegisterType((*FindRankDataByKey)(nil), "rpc.FindRankDataByKey") + proto.RegisterType((*FindRankDataByPos)(nil), "rpc.FindRankDataByPos") + proto.RegisterType((*FindRankDataListStartTo)(nil), "rpc.FindRankDataListStartTo") + proto.RegisterType((*RankDataList)(nil), "rpc.RankDataList") + proto.RegisterType((*RankResult)(nil), "rpc.RankResult") +} + +func init() { proto.RegisterFile("proto/rpcproto/rank.proto", fileDescriptor_d5b64eda47521620) } + +var fileDescriptor_d5b64eda47521620 = []byte{ + // 468 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x54, 0xdf, 0x8b, 0xd3, 0x40, + 0x10, 0x26, 0x4d, 0x72, 0x2d, 0x93, 0x2b, 0x9e, 0xab, 0x68, 0xf4, 0xa1, 0x84, 0x45, 0xb0, 0x4f, + 0x15, 0x15, 0x7c, 0x50, 0x44, 0x7a, 0x16, 0xe1, 0xb8, 0x2b, 0xc8, 0x54, 0x5f, 0xee, 0x2d, 0x66, + 0x57, 0x0c, 0xad, 0xcd, 0x92, 0xec, 0x1d, 0xed, 0x7f, 0xe8, 0xa3, 0x7f, 0x82, 0xf4, 0x2f, 0x91, + 0xd9, 0x64, 0xf3, 0xe3, 0x8e, 0xf4, 0x6d, 0xbe, 0x6f, 0xbe, 0xcc, 0x37, 0x3b, 0x33, 0x04, 0x9e, + 0xa9, 0x3c, 0xd3, 0xd9, 0xab, 0x5c, 0x25, 0x55, 0x10, 0x6f, 0xd7, 0x33, 0x13, 0x32, 0x37, 0x57, + 0x09, 0xff, 0x05, 0x23, 0x8c, 0xb7, 0xeb, 0x45, 0xac, 0x63, 0x76, 0x06, 0xee, 0xa5, 0xdc, 0x87, + 0x4e, 0xe4, 0x4c, 0x3d, 0xa4, 0x90, 0x3d, 0x87, 0xd1, 0x2a, 0xcb, 0x35, 0x65, 0xc3, 0x41, 0xe4, + 0x4e, 0x5d, 0xac, 0x31, 0x63, 0xe0, 0x19, 0xde, 0x8d, 0x9c, 0xe9, 0x29, 0x9a, 0x98, 0xf4, 0x72, + 0xa7, 0xd2, 0x5c, 0x2e, 0x8b, 0xd0, 0x8b, 0x1c, 0xd2, 0x5b, 0xcc, 0x53, 0x08, 0xc8, 0xe9, 0x6b, + 0x56, 0xf4, 0x98, 0x85, 0x30, 0xac, 0x04, 0xe1, 0xc0, 0xb0, 0x16, 0x76, 0xda, 0x70, 0x7b, 0xda, + 0xf0, 0x9a, 0x36, 0xf8, 0xae, 0x7c, 0xd4, 0x55, 0x5a, 0x68, 0xf6, 0x04, 0x4e, 0x28, 0xbe, 0x10, + 0x95, 0x55, 0x85, 0xd8, 0x0b, 0x18, 0xaf, 0xd6, 0xa9, 0x22, 0xcd, 0x95, 0xbc, 0x95, 0x1b, 0xe3, + 0xe9, 0x63, 0x97, 0x64, 0x8f, 0xc1, 0xbf, 0x28, 0x16, 0x32, 0x31, 0xaf, 0x1c, 0x61, 0x09, 0xa8, + 0xd3, 0x65, 0xbc, 0xa3, 0x42, 0xc6, 0xd6, 0x43, 0x0b, 0xf9, 0x35, 0x8c, 0xbf, 0xab, 0x42, 0xea, + 0x7a, 0xa6, 0x7d, 0xf6, 0xaf, 0xe1, 0xd4, 0x6a, 0xc8, 0xcd, 0x4c, 0x37, 0x78, 0x33, 0x9e, 0xe5, + 0x2a, 0x99, 0xd9, 0x04, 0x76, 0x24, 0xfc, 0x13, 0x04, 0x0b, 0xb9, 0x91, 0x5a, 0x9e, 0xef, 0x69, + 0x5c, 0x7d, 0x95, 0x43, 0x18, 0x5e, 0xca, 0x7d, 0x5d, 0xd4, 0x43, 0x0b, 0xf9, 0x3b, 0x08, 0xe6, + 0x42, 0xd4, 0x93, 0x79, 0x09, 0xc3, 0xb9, 0x10, 0x46, 0xe8, 0xdc, 0x71, 0x27, 0x12, 0x6d, 0x96, + 0x7f, 0x84, 0x87, 0x5f, 0xd2, 0xad, 0xb0, 0xcd, 0x1c, 0xb7, 0xaf, 0xf6, 0x3a, 0xa8, 0xf7, 0x7a, + 0xff, 0x73, 0x5a, 0xe9, 0x91, 0xcf, 0x9b, 0x03, 0xa0, 0x90, 0x27, 0xf0, 0xb4, 0xfd, 0x39, 0x75, + 0xb4, 0xd2, 0x71, 0xae, 0xbf, 0x65, 0xbd, 0x45, 0xe8, 0x5e, 0x48, 0xd2, 0x54, 0xaa, 0x31, 0x6d, + 0xf4, 0x73, 0x76, 0xb3, 0xd5, 0x66, 0xa3, 0x1e, 0x96, 0x80, 0xab, 0xee, 0x3a, 0xe8, 0x3a, 0x2c, + 0x2e, 0xd5, 0xa5, 0x41, 0x97, 0x64, 0xef, 0xe1, 0x41, 0xeb, 0xa4, 0x5b, 0x7b, 0x3c, 0xab, 0x27, + 0x59, 0xe5, 0xf0, 0xae, 0x90, 0x6f, 0x00, 0x88, 0x42, 0x59, 0xdc, 0x6c, 0x34, 0x75, 0x3c, 0x17, + 0xa2, 0xb1, 0xf2, 0xb1, 0xc6, 0x2c, 0x82, 0x00, 0xe5, 0xef, 0xec, 0x56, 0x96, 0xe9, 0xf2, 0x4e, + 0xdb, 0x14, 0x29, 0x96, 0x99, 0x48, 0x7f, 0xee, 0x9b, 0x97, 0xf9, 0xd8, 0xa6, 0xce, 0x1f, 0xfd, + 0x39, 0x4c, 0x9c, 0xbf, 0x87, 0x89, 0xf3, 0xef, 0x30, 0x71, 0xae, 0xfd, 0xd9, 0x87, 0x5c, 0x25, + 0x3f, 0x4e, 0xcc, 0x7f, 0xe0, 0xed, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x4b, 0x0e, 0xaf, 0x42, + 0x24, 0x04, 0x00, 0x00, +} + +func (m *RankData) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RankData) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RankData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.ExpireMs != 0 { + i = encodeVarintRank(dAtA, i, uint64(m.ExpireMs)) + i-- + dAtA[i] = 0x20 + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintRank(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x1a + } + if len(m.SortData) > 0 { + dAtA2 := make([]byte, len(m.SortData)*10) + var j1 int + for _, num1 := range m.SortData { + num := uint64(num1) + for num >= 1<<7 { + dAtA2[j1] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j1++ + } + dAtA2[j1] = uint8(num) + j1++ + } + i -= j1 + copy(dAtA[i:], dAtA2[:j1]) + i = encodeVarintRank(dAtA, i, uint64(j1)) + i-- + dAtA[i] = 0x12 + } + if m.Key != 0 { + i = encodeVarintRank(dAtA, i, uint64(m.Key)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *RankPosData) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RankPosData) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RankPosData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintRank(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x22 + } + if len(m.SortData) > 0 { + dAtA4 := make([]byte, len(m.SortData)*10) + var j3 int + for _, num1 := range m.SortData { + num := uint64(num1) + for num >= 1<<7 { + dAtA4[j3] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j3++ + } + dAtA4[j3] = uint8(num) + j3++ + } + i -= j3 + copy(dAtA[i:], dAtA4[:j3]) + i = encodeVarintRank(dAtA, i, uint64(j3)) + i-- + dAtA[i] = 0x1a + } + if m.RankPos != 0 { + i = encodeVarintRank(dAtA, i, uint64(m.RankPos)) + i-- + dAtA[i] = 0x10 + } + if m.Key != 0 { + i = encodeVarintRank(dAtA, i, uint64(m.Key)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *RankList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RankList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RankList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.MaxRank != 0 { + i = encodeVarintRank(dAtA, i, uint64(m.MaxRank)) + i-- + dAtA[i] = 0x20 + } + if m.IsDec { + i-- + if m.IsDec { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } + if m.SkipListLevel != 0 { + i = encodeVarintRank(dAtA, i, uint64(m.SkipListLevel)) + i-- + dAtA[i] = 0x10 + } + if m.RankId != 0 { + i = encodeVarintRank(dAtA, i, uint64(m.RankId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *UpsetRankData) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *UpsetRankData) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UpsetRankData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.RankDataList) > 0 { + for iNdEx := len(m.RankDataList) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.RankDataList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRank(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if m.RankId != 0 { + i = encodeVarintRank(dAtA, i, uint64(m.RankId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *DeleteByKey) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DeleteByKey) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DeleteByKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.KeyList) > 0 { + dAtA6 := make([]byte, len(m.KeyList)*10) + var j5 int + for _, num := range m.KeyList { + for num >= 1<<7 { + dAtA6[j5] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j5++ + } + dAtA6[j5] = uint8(num) + j5++ + } + i -= j5 + copy(dAtA[i:], dAtA6[:j5]) + i = encodeVarintRank(dAtA, i, uint64(j5)) + i-- + dAtA[i] = 0x12 + } + if m.RankId != 0 { + i = encodeVarintRank(dAtA, i, uint64(m.RankId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *AddRankList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AddRankList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AddRankList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.AddList) > 0 { + for iNdEx := len(m.AddList) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.AddList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRank(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *FindRankDataByKey) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *FindRankDataByKey) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *FindRankDataByKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Key != 0 { + i = encodeVarintRank(dAtA, i, uint64(m.Key)) + i-- + dAtA[i] = 0x10 + } + if m.RankId != 0 { + i = encodeVarintRank(dAtA, i, uint64(m.RankId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *FindRankDataByPos) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *FindRankDataByPos) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *FindRankDataByPos) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Pos != 0 { + i = encodeVarintRank(dAtA, i, uint64(m.Pos)) + i-- + dAtA[i] = 0x10 + } + if m.RankId != 0 { + i = encodeVarintRank(dAtA, i, uint64(m.RankId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *FindRankDataListStartTo) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *FindRankDataListStartTo) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *FindRankDataListStartTo) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Count != 0 { + i = encodeVarintRank(dAtA, i, uint64(m.Count)) + i-- + dAtA[i] = 0x18 + } + if m.StartPos != 0 { + i = encodeVarintRank(dAtA, i, uint64(m.StartPos)) + i-- + dAtA[i] = 0x10 + } + if m.RankId != 0 { + i = encodeVarintRank(dAtA, i, uint64(m.RankId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *RankDataList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RankDataList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RankDataList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.RankPosDataList) > 0 { + for iNdEx := len(m.RankPosDataList) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.RankPosDataList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRank(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if m.RankDataCount != 0 { + i = encodeVarintRank(dAtA, i, uint64(m.RankDataCount)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *RankResult) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RankResult) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RankResult) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.ModifyCount != 0 { + i = encodeVarintRank(dAtA, i, uint64(m.ModifyCount)) + i-- + dAtA[i] = 0x18 + } + if m.RemoveCount != 0 { + i = encodeVarintRank(dAtA, i, uint64(m.RemoveCount)) + i-- + dAtA[i] = 0x10 + } + if m.AddCount != 0 { + i = encodeVarintRank(dAtA, i, uint64(m.AddCount)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintRank(dAtA []byte, offset int, v uint64) int { + offset -= sovRank(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *RankData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Key != 0 { + n += 1 + sovRank(uint64(m.Key)) + } + if len(m.SortData) > 0 { + l = 0 + for _, e := range m.SortData { + l += sovRank(uint64(e)) + } + n += 1 + sovRank(uint64(l)) + l + } + l = len(m.Data) + if l > 0 { + n += 1 + l + sovRank(uint64(l)) + } + if m.ExpireMs != 0 { + n += 1 + sovRank(uint64(m.ExpireMs)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *RankPosData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Key != 0 { + n += 1 + sovRank(uint64(m.Key)) + } + if m.RankPos != 0 { + n += 1 + sovRank(uint64(m.RankPos)) + } + if len(m.SortData) > 0 { + l = 0 + for _, e := range m.SortData { + l += sovRank(uint64(e)) + } + n += 1 + sovRank(uint64(l)) + l + } + l = len(m.Data) + if l > 0 { + n += 1 + l + sovRank(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *RankList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.RankId != 0 { + n += 1 + sovRank(uint64(m.RankId)) + } + if m.SkipListLevel != 0 { + n += 1 + sovRank(uint64(m.SkipListLevel)) + } + if m.IsDec { + n += 2 + } + if m.MaxRank != 0 { + n += 1 + sovRank(uint64(m.MaxRank)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *UpsetRankData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.RankId != 0 { + n += 1 + sovRank(uint64(m.RankId)) + } + if len(m.RankDataList) > 0 { + for _, e := range m.RankDataList { + l = e.Size() + n += 1 + l + sovRank(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *DeleteByKey) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.RankId != 0 { + n += 1 + sovRank(uint64(m.RankId)) + } + if len(m.KeyList) > 0 { + l = 0 + for _, e := range m.KeyList { + l += sovRank(uint64(e)) + } + n += 1 + sovRank(uint64(l)) + l + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *AddRankList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.AddList) > 0 { + for _, e := range m.AddList { + l = e.Size() + n += 1 + l + sovRank(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *FindRankDataByKey) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.RankId != 0 { + n += 1 + sovRank(uint64(m.RankId)) + } + if m.Key != 0 { + n += 1 + sovRank(uint64(m.Key)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *FindRankDataByPos) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.RankId != 0 { + n += 1 + sovRank(uint64(m.RankId)) + } + if m.Pos != 0 { + n += 1 + sovRank(uint64(m.Pos)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *FindRankDataListStartTo) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.RankId != 0 { + n += 1 + sovRank(uint64(m.RankId)) + } + if m.StartPos != 0 { + n += 1 + sovRank(uint64(m.StartPos)) + } + if m.Count != 0 { + n += 1 + sovRank(uint64(m.Count)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *RankDataList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.RankDataCount != 0 { + n += 1 + sovRank(uint64(m.RankDataCount)) + } + if len(m.RankPosDataList) > 0 { + for _, e := range m.RankPosDataList { + l = e.Size() + n += 1 + l + sovRank(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *RankResult) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.AddCount != 0 { + n += 1 + sovRank(uint64(m.AddCount)) + } + if m.RemoveCount != 0 { + n += 1 + sovRank(uint64(m.RemoveCount)) + } + if m.ModifyCount != 0 { + n += 1 + sovRank(uint64(m.ModifyCount)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovRank(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozRank(x uint64) (n int) { + return sovRank(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *RankData) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RankData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RankData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + m.Key = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Key |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType == 0 { + var v int64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.SortData = append(m.SortData, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthRank + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthRank + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.SortData) == 0 { + m.SortData = make([]int64, 0, elementCount) + } + for iNdEx < postIndex { + var v int64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.SortData = append(m.SortData, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field SortData", wireType) + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRank + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthRank + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ExpireMs", wireType) + } + m.ExpireMs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ExpireMs |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipRank(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RankPosData) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RankPosData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RankPosData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + m.Key = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Key |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RankPos", wireType) + } + m.RankPos = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RankPos |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType == 0 { + var v int64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.SortData = append(m.SortData, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthRank + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthRank + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.SortData) == 0 { + m.SortData = make([]int64, 0, elementCount) + } + for iNdEx < postIndex { + var v int64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.SortData = append(m.SortData, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field SortData", wireType) + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRank + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthRank + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRank(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RankList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RankList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RankList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RankId", wireType) + } + m.RankId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RankId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SkipListLevel", wireType) + } + m.SkipListLevel = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SkipListLevel |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsDec", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsDec = bool(v != 0) + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxRank", wireType) + } + m.MaxRank = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxRank |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipRank(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *UpsetRankData) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UpsetRankData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UpsetRankData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RankId", wireType) + } + m.RankId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RankId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RankDataList", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRank + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRank + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RankDataList = append(m.RankDataList, &RankData{}) + if err := m.RankDataList[len(m.RankDataList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRank(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeleteByKey) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeleteByKey: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeleteByKey: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RankId", wireType) + } + m.RankId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RankId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType == 0 { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.KeyList = append(m.KeyList, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthRank + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthRank + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.KeyList) == 0 { + m.KeyList = make([]uint64, 0, elementCount) + } + for iNdEx < postIndex { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.KeyList = append(m.KeyList, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field KeyList", wireType) + } + default: + iNdEx = preIndex + skippy, err := skipRank(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AddRankList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AddRankList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AddRankList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AddList", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRank + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRank + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AddList = append(m.AddList, &RankList{}) + if err := m.AddList[len(m.AddList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRank(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *FindRankDataByKey) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: FindRankDataByKey: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FindRankDataByKey: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RankId", wireType) + } + m.RankId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RankId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + m.Key = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Key |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipRank(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *FindRankDataByPos) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: FindRankDataByPos: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FindRankDataByPos: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RankId", wireType) + } + m.RankId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RankId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Pos", wireType) + } + m.Pos = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Pos |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipRank(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *FindRankDataListStartTo) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: FindRankDataListStartTo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FindRankDataListStartTo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RankId", wireType) + } + m.RankId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RankId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StartPos", wireType) + } + m.StartPos = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StartPos |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Count", wireType) + } + m.Count = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Count |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipRank(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RankDataList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RankDataList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RankDataList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RankDataCount", wireType) + } + m.RankDataCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RankDataCount |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RankPosDataList", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRank + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRank + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RankPosDataList = append(m.RankPosDataList, &RankPosData{}) + if err := m.RankPosDataList[len(m.RankPosDataList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRank(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RankResult) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RankResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RankResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AddCount", wireType) + } + m.AddCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.AddCount |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RemoveCount", wireType) + } + m.RemoveCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RemoveCount |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ModifyCount", wireType) + } + m.ModifyCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ModifyCount |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipRank(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRank + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipRank(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRank + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRank + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRank + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthRank + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupRank + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthRank + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthRank = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowRank = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupRank = fmt.Errorf("proto: unexpected end of group") +) diff --git a/sysservice/rankservice/RankData.go b/sysservice/rankservice/RankData.go new file mode 100644 index 0000000..772ccbb --- /dev/null +++ b/sysservice/rankservice/RankData.go @@ -0,0 +1,96 @@ +package rankservice + +import ( + "github.com/duanhf2012/origin/rpc" + "github.com/duanhf2012/origin/util/algorithms/skip" + "github.com/duanhf2012/origin/util/sync" +) + +var emptyRankData RankData + +var RankDataPool = sync.NewPoolEx(make(chan sync.IPoolData, 10240), func() sync.IPoolData { + var newRankData RankData + return &newRankData +}) + +type RankData struct { + *rpc.RankData + + ref bool + compareFunc func(other skip.Comparator) int +} + +func NewRankData(isDec bool, data *rpc.RankData) *RankData { + ret := RankDataPool.Get().(*RankData) + ret.compareFunc = ret.ascCompare + if isDec { + ret.compareFunc = ret.desCompare + } + ret.RankData = data + + return ret +} + +func ReleaseRankData(rankData *RankData) { + RankDataPool.Put(rankData) +} + +func (p *RankData) Reset() { + *p = emptyRankData +} + +func (p *RankData) IsRef() bool { + return p.ref +} + +func (p *RankData) Ref() { + p.ref = true +} + +func (p *RankData) UnRef() { + p.ref = false +} + +func (p *RankData) Compare(other skip.Comparator) int { + return p.compareFunc(other) +} + +func (p *RankData) GetKey() uint64 { + return p.Key +} + +func (p *RankData) ascCompare(other skip.Comparator) int { + otherRankData := other.(*RankData) + + if otherRankData.Key == p.Key { + return 0 + } + + retFlg := compareMoreThan(p.SortData, otherRankData.SortData) + if retFlg == 0 { + if p.Key > otherRankData.Key { + retFlg = 1 + } else { + retFlg = -1 + } + } + return retFlg +} + +func (p *RankData) desCompare(other skip.Comparator) int { + otherRankData := other.(*RankData) + + if otherRankData.Key == p.Key { + return 0 + } + + retFlg := compareMoreThan(otherRankData.SortData, p.SortData) + if retFlg == 0 { + if p.Key > otherRankData.Key { + retFlg = -1 + } else { + retFlg = 1 + } + } + return retFlg +} diff --git a/sysservice/rankservice/RankFunc.go b/sysservice/rankservice/RankFunc.go new file mode 100644 index 0000000..60ca549 --- /dev/null +++ b/sysservice/rankservice/RankFunc.go @@ -0,0 +1,52 @@ +package rankservice + +func transformLevel(level int32) interface{} { + switch level { + case 8: + return uint8(0) + case 16: + return uint16(0) + case 32: + return uint32(0) + case 64: + return uint64(0) + default: + return uint32(0) + } +} + +func compareIsEqual(firstSortData, secondSortData []int64) bool { + firstLen := len(firstSortData) + if firstLen != len(secondSortData) { + return false + } + + for i := firstLen - 1; i >= 0; i-- { + if firstSortData[i] != secondSortData[i] { + return false + } + } + + return true +} + +func compareMoreThan(firstSortData, secondSortData []int64) int { + firstLen := len(firstSortData) + secondLen := len(secondSortData) + minLen := firstLen + if firstLen > secondLen { + minLen = secondLen + } + + for i := 0; i < minLen; i++ { + if firstSortData[i] > secondSortData[i] { + return 1 + } + + if firstSortData[i] < secondSortData[i] { + return -1 + } + } + + return 0 +} diff --git a/sysservice/rankservice/RankInterface.go b/sysservice/rankservice/RankInterface.go new file mode 100644 index 0000000..8c78f55 --- /dev/null +++ b/sysservice/rankservice/RankInterface.go @@ -0,0 +1,52 @@ +package rankservice + +import "github.com/duanhf2012/origin/service" + +type RankDataChangeType int8 + +const ( + RankDataNone RankDataChangeType = 0 + RankDataAdd RankDataChangeType = 1 //数据插入 + RankDataUpdate RankDataChangeType = 2 //数据更新 + RankDataDelete RankDataChangeType = 3 //数据删除 +) + +type IRankSkip interface { + GetRankID() uint64 + GetRankLen() uint64 +} + +// RankDataChangeCallBack 排行数据变化时调用 +//type RankDataChangeCallBack interface { +// CB(iRankService service.IService, rankSkip IRankSkip, changeType RankDataChangeType, changed []*RankData) +//} + +type IRankModule interface { + service.IModule + + OnStart(mapRankSkip map[uint64]*RankSkip) error //服务开启时回调 + OnEnterRank(rankSkip IRankSkip, enterData []*RankData) //进入排行 + OnLeaveRank(rankSkip IRankSkip, leaveData []*RankData) //离开排行 + OnChangeRankData(rankSkip IRankSkip, changeData []*RankData) //当排行数据变化时 + OnStop(mapRankSkip map[uint64]*RankSkip) //服务结束时回调 +} + +type DefaultRankModule struct { + service.Module +} + +func (dr *DefaultRankModule) OnStart(mapRankSkip map[uint64]*RankSkip) error { + return nil +} + +func (dr *DefaultRankModule) OnEnterRank(rankSkip IRankSkip, enterData []*RankData) { +} + +func (dr *DefaultRankModule) OnLeaveRank(rankSkip IRankSkip, leaveData []*RankData) { +} + +func (dr *DefaultRankModule) OnChangeRankData(rankSkip IRankSkip, changeData []*RankData) { +} + +func (dr *DefaultRankModule) OnStop(mapRankSkip map[uint64]*RankSkip) { +} diff --git a/sysservice/rankservice/RankService.go b/sysservice/rankservice/RankService.go new file mode 100644 index 0000000..744d289 --- /dev/null +++ b/sysservice/rankservice/RankService.go @@ -0,0 +1,195 @@ +package rankservice + +import ( + "fmt" + "github.com/duanhf2012/origin/log" + "github.com/duanhf2012/origin/node" + "github.com/duanhf2012/origin/rpc" + "github.com/duanhf2012/origin/service" +) + +func init() { + node.Setup(&RankService{}) +} + +const PreMapRankSkipLen = 10 +const ManualAddRankSkip = "RPC_ManualAddRankSkip" +const UpsetRank = "RPC_UpsetRank" +const DeleteRankDataByKey = "RPC_DeleteRankDataByKey" +const FindRankDataByKey = "RPC_FindRankDataByKey" +const FindRankDataByPos = "RPC_FindRankDataByPos" +const FindRankDataListStartTo = "RPC_FindRankDataListStartTo" + +type RankService struct { + service.Service + + mapRankSkip map[uint64]*RankSkip + rankModule IRankModule +} + +func (rs *RankService) OnInit() error { + rs.mapRankSkip = make(map[uint64]*RankSkip, PreMapRankSkipLen) + err := rs.dealCfg() + if err != nil { + return err + } + + if rs.rankModule != nil { + _, err = rs.AddModule(rs.rankModule) + if err != nil { + return err + } + } else { + rs.AddModule(&DefaultRankModule{}) + } + + return nil +} + +func (rs *RankService) OnStart() { + rs.rankModule.OnStart(rs.mapRankSkip) +} + +func (rs *RankService) OnRelease() { + rs.rankModule.OnStop(rs.mapRankSkip) +} + +// 安装排行模块 +func (rs *RankService) SetupRankModule(rankModule IRankModule) { + rs.rankModule = rankModule +} + +// RPC_ManualAddRankSkip 提供手动添加排行榜 +func (rs *RankService) RPC_ManualAddRankSkip(addInfo *rpc.AddRankList, addResult *rpc.RankResult) error { + addList := make([]uint64, 0, PreMapRankSkipLen) + for _, addRankListData := range addInfo.AddList { + if addRankListData.RankId == 0 { + rs.deleteRankList(addList) + return fmt.Errorf("RPC_AddRankSkip must has rank id") + } + + newSkip := NewRankSkip(addRankListData.IsDec, transformLevel(addRankListData.SkipListLevel), addRankListData.MaxRank) + rs.mapRankSkip[addRankListData.RankId] = newSkip + addList = append(addList, addRankListData.RankId) + } + + addResult.AddCount = 1 + + return nil +} + +// RPC_UpsetRank 更新排行榜 +func (rs *RankService) RPC_UpsetRank(upsetInfo *rpc.UpsetRankData, upsetResult *rpc.RankResult) error { + rankSkip, ok := rs.mapRankSkip[upsetInfo.RankId] + if ok == false || rankSkip == nil { + return fmt.Errorf("RPC_UpsetRank[", upsetInfo.RankId, "] no this rank id") + } + + addCount, updateCount := rankSkip.UpsetRank(upsetInfo.RankDataList) + upsetResult.AddCount = addCount + upsetResult.ModifyCount = updateCount + return nil +} + +// RPC_DeleteRankDataByKey 按排行的key进行删除 +func (rs *RankService) RPC_DeleteRankDataByKey(delInfo *rpc.DeleteByKey, delResult *rpc.RankResult) error { + rankSkip, ok := rs.mapRankSkip[delInfo.RankId] + if ok == false || rankSkip == nil { + return fmt.Errorf("RPC_DeleteRankDataByKey[", delInfo.RankId, "] no this rank type") + } + + removeCount := rankSkip.DeleteRankData(delInfo.KeyList) + if removeCount == 0 { + log.SError("remove count is zero") + } + + delResult.RemoveCount = removeCount + return nil +} + +// RPC_FindRankDataByKey 按key查找 +func (rs *RankService) RPC_FindRankDataByKey(findInfo *rpc.FindRankDataByKey, findResult *rpc.RankPosData) error { + rankObj, ok := rs.mapRankSkip[findInfo.RankId] + if ok == false || rankObj == nil { + return fmt.Errorf("RPC_FindRankDataByKey[", findInfo.RankId, "] no this rank type") + } + + findRankData, rankPos := rankObj.GetRankNodeData(findInfo.Key) + if findRankData != nil { + findResult.Data = findRankData.Data + findResult.Key = findRankData.Key + findResult.SortData = findRankData.SortData + findResult.RankPos = rankPos + } + return nil +} + +// RPC_FindRankDataByPos 按pos查找 +func (rs *RankService) RPC_FindRankDataByPos(findInfo *rpc.FindRankDataByPos, findResult *rpc.RankPosData) error { + rankObj, ok := rs.mapRankSkip[findInfo.RankId] + if ok == false || rankObj == nil { + return fmt.Errorf("RPC_FindRankDataByKey[", findInfo.RankId, "] no this rank type") + } + + findRankData, rankPos := rankObj.GetRankNodeDataByPos(findInfo.Pos) + if findRankData != nil { + findResult.Data = findRankData.Data + findResult.Key = findRankData.Key + findResult.SortData = findRankData.SortData + findResult.RankPos = rankPos + } + return nil +} + +// RPC_FindRankDataListStartTo 按pos查找,start开始count个排行数据 +func (rs *RankService) RPC_FindRankDataListStartTo(findInfo *rpc.FindRankDataListStartTo, findResult *rpc.RankDataList) error { + rankObj, ok := rs.mapRankSkip[findInfo.RankId] + if ok == false || rankObj == nil { + return fmt.Errorf("RPC_FindRankDataListStartTo[", findInfo.RankId, "] no this rank type") + } + + findResult.RankDataCount = rankObj.GetRankLen() + return rankObj.GetRankDataFromToLimit(findInfo.StartPos, findInfo.Count, findResult) +} + +func (rs *RankService) deleteRankList(delIdList []uint64) { + if rs.mapRankSkip == nil { + return + } + + for _, id := range delIdList { + delete(rs.mapRankSkip, id) + } +} + +func (rs *RankService) dealCfg() error { + mapDBServiceCfg, ok := rs.GetServiceCfg().(map[string]interface{}) + if ok == false { + return nil + } + + cfgList, okList := mapDBServiceCfg["SortCfg"].([]interface{}) + if okList == false { + return fmt.Errorf("RankService SortCfg must be list") + } + + for _, cfg := range cfgList { + mapCfg, okCfg := cfg.(map[string]interface{}) + if okCfg == false { + return fmt.Errorf("RankService SortCfg data must be map or struct") + } + + rankId, okId := mapCfg["RankID"].(float64) + if okId == false { + return fmt.Errorf("RankService SortCfg data must has RankID[number]") + } + + level, _ := mapCfg["SkipListLevel"].(float64) + isDec, _ := mapCfg["IsDec"].(bool) + maxRank, _ := mapCfg["MaxRank"].(float64) + + newSkip := NewRankSkip(isDec, transformLevel(int32(level)), uint64(maxRank)) + rs.mapRankSkip[uint64(rankId)] = newSkip + } + return nil +} diff --git a/sysservice/rankservice/RankSkip.go b/sysservice/rankservice/RankSkip.go new file mode 100644 index 0000000..89731c6 --- /dev/null +++ b/sysservice/rankservice/RankSkip.go @@ -0,0 +1,262 @@ +package rankservice + +import ( + "fmt" + "github.com/duanhf2012/origin/rpc" + "github.com/duanhf2012/origin/util/algorithms/skip" +) + +type RankSkip struct { + rankId uint64 //排行榜ID + isDes bool //是否为降序 true:降序 false:升序 + skipList *skip.SkipList //跳表 + mapRankData map[uint64]*RankData //排行数据map + maxLen uint64 //排行数据长度 + rankModule IRankModule +} + +// NewRankSkip 创建排行榜 +func NewRankSkip(isDes bool, level interface{}, maxLen uint64) *RankSkip { + ret := &RankSkip{} + + ret.isDes = isDes + ret.skipList = skip.New(level) + ret.mapRankData = make(map[uint64]*RankData, 10240) + ret.maxLen = maxLen + + return ret +} + +func (rs *RankSkip) SetupRankModule(rankModule IRankModule) { + rs.rankModule = rankModule +} + +// GetRankID 获取排行榜Id +func (rs *RankSkip) GetRankID() uint64 { + return rs.rankId +} + +// GetRankLen 获取排行榜长度 +func (rs *RankSkip) GetRankLen() uint64 { + return rs.skipList.Len() +} + +func (rs *RankSkip) UpsetRank(upsetRankData []*rpc.RankData) (addCount int32, modifyCount int32) { + addList := make([]*RankData, 0, 1) + updateList := make([]*RankData, 0, 1) + for _, upsetData := range upsetRankData { + changeData, changeType := rs.upsetRank(upsetData) + if changeData == nil { + continue + } + + switch changeType { + case RankDataAdd: + addList = append(addList, changeData) + case RankDataUpdate: + updateList = append(updateList, changeData) + } + } + + if len(addList) > 0 { + rs.rankModule.OnEnterRank(rs, addList) + } + + if len(updateList) > 0 { + rs.rankModule.OnChangeRankData(rs, updateList) + } + + addCount = int32(len(addList)) + modifyCount = int32(len(updateList)) + return +} + +// UpsetRank 更新玩家排行数据,返回变化后的数据及变化类型 +func (rs *RankSkip) upsetRank(upsetData *rpc.RankData) (*RankData, RankDataChangeType) { + rankNode, ok := rs.mapRankData[upsetData.Key] + if ok == true { + //找到的情况对比排名数据是否有变化,无变化进行data更新,有变化则进行删除更新 + if compareIsEqual(rankNode.SortData, upsetData.SortData) { + rankNode.Data = upsetData.GetData() + return nil, RankDataNone + } + + if upsetData.Data == nil { + upsetData.Data = rankNode.Data + } + rs.skipList.Delete(rankNode) + ReleaseRankData(rankNode) + + newRankData := NewRankData(rs.isDes, upsetData) + rs.skipList.Insert(newRankData) + rs.mapRankData[upsetData.Key] = newRankData + return newRankData, RankDataUpdate + } + + if rs.checkCanInsert(upsetData) { + newRankData := NewRankData(rs.isDes, upsetData) + rs.skipList.Insert(newRankData) + rs.mapRankData[upsetData.Key] = newRankData + return newRankData, RankDataAdd + } + + return nil, RankDataNone +} + +// DeleteRankData 删除排行数据 +func (rs *RankSkip) DeleteRankData(delKeys []uint64) int32 { + removeRankData := make([]*RankData, 0, 1) + //预统计处理,进行回调 + for _, key := range delKeys { + rankData, ok := rs.mapRankData[key] + if ok == false { + continue + } + + removeRankData = append(removeRankData, rankData) + } + rs.rankModule.OnLeaveRank(rs, removeRankData) + + //从排行榜中删除 + for _, rankData := range removeRankData { + rs.skipList.Delete(rankData) + ReleaseRankData(rankData) + delete(rs.mapRankData, rankData.Key) + } + + return int32(len(removeRankData)) +} + +// GetRankNodeData 获取,返回排名节点与名次 +func (rs *RankSkip) GetRankNodeData(findKey uint64) (*RankData, uint64) { + rankNode, ok := rs.mapRankData[findKey] + if ok == false { + return nil, 0 + } + + _, index := rs.skipList.GetWithPosition(rankNode) + return rankNode, index +} + +// GetRankNodeDataByPos 获取,返回排名节点与名次 +func (rs *RankSkip) GetRankNodeDataByPos(pos uint64) (*RankData, uint64) { + rankNode := rs.skipList.ByPosition(pos) + if rankNode == nil { + return nil, 0 + } + + return rankNode.(*RankData), pos +} + +// GetRankKeyPrevToLimit 获取key前count名的数据 +func (rs *RankSkip) GetRankKeyPrevToLimit(findKey, count uint64, result *rpc.RankDataList) error { + if rs.GetRankLen() <= 0 { + return fmt.Errorf("rank[", rs.rankId, "] no data") + } + + findData, ok := rs.mapRankData[findKey] + if ok == false { + return fmt.Errorf("rank[", rs.rankId, "] no data") + } + + _, rankPos := rs.skipList.GetWithPosition(findData) + iter := rs.skipList.Iter(findData) + iterCount := uint64(0) + for iter.Prev() && iterCount < count { + rankData := iter.Value().(*RankData) + result.RankPosDataList = append(result.RankPosDataList, &rpc.RankPosData{ + Key: rankData.Key, + RankPos: rankPos - iterCount, + SortData: rankData.SortData, + Data: rankData.Data, + }) + iterCount++ + } + + return nil +} + +// GetRankKeyPrevToLimit 获取key前count名的数据 +func (rs *RankSkip) GetRankKeyNextToLimit(findKey, count uint64, result *rpc.RankDataList) error { + if rs.GetRankLen() <= 0 { + return fmt.Errorf("rank[", rs.rankId, "] no data") + } + + findData, ok := rs.mapRankData[findKey] + if ok == false { + return fmt.Errorf("rank[", rs.rankId, "] no data") + } + + _, rankPos := rs.skipList.GetWithPosition(findData) + iter := rs.skipList.Iter(findData) + iterCount := uint64(0) + for iter.Next() && iterCount < count { + rankData := iter.Value().(*RankData) + result.RankPosDataList = append(result.RankPosDataList, &rpc.RankPosData{ + Key: rankData.Key, + RankPos: rankPos + iterCount, + SortData: rankData.SortData, + Data: rankData.Data, + }) + iterCount++ + } + + return nil +} + +// GetRankList 获取排行榜数据,startPos开始的count个数据 +func (rs *RankSkip) GetRankDataFromToLimit(startPos, count uint64, result *rpc.RankDataList) error { + if rs.GetRankLen() <= 0 { + return fmt.Errorf("rank[", rs.rankId, "] no data") + } + + if result.RankDataCount < startPos { + startPos = result.RankDataCount - 1 + } + + iter := rs.skipList.IterAtPosition(startPos) + iterCount := uint64(0) + for iter.Next() && iterCount < count { + rankData := iter.Value().(*RankData) + result.RankPosDataList = append(result.RankPosDataList, &rpc.RankPosData{ + Key: rankData.Key, + RankPos: iterCount + startPos, + SortData: rankData.SortData, + Data: rankData.Data, + }) + iterCount++ + } + + return nil +} + +// checkCanInsert 检查是否能插入 +func (rs *RankSkip) checkCanInsert(upsetData *rpc.RankData) bool { + //maxLen为0,不限制长度 + if rs.maxLen == 0 { + return true + } + + //没有放满,则进行插入 + rankLen := rs.skipList.Len() + if rs.maxLen > rankLen { + return true + } + + //已经放满了,进行数据比较 + lastPosData := rs.skipList.ByPosition(rankLen - 1) + lastRankData := lastPosData.(*RankData) + moreThanFlag := compareMoreThan(upsetData.SortData, lastRankData.SortData) + //降序排列,比最后一位小,不能插入 升序排列,比最后一位大,不能插入 + if (rs.isDes == true && moreThanFlag < 0) || (rs.isDes == false && moreThanFlag > 0) || moreThanFlag == 0 { + return false + } + + //移除最后一位 + //回调模块,该RandData从排行中删除 + rs.rankModule.OnLeaveRank(rs, []*RankData{lastRankData}) + rs.skipList.Delete(lastPosData) + delete(rs.mapRankData, lastRankData.Key) + ReleaseRankData(lastRankData) + return true +} diff --git a/sysservice/rankservice/rank.proto b/sysservice/rankservice/rank.proto new file mode 100644 index 0000000..91d3e81 --- /dev/null +++ b/sysservice/rankservice/rank.proto @@ -0,0 +1,76 @@ +syntax = "proto3"; +package rpc; +option go_package = ".;rpc"; + +// RankData 排行数据 +message RankData { + uint64 Key = 1; //数据主建 + repeated int64 SortData = 2; //参与排行的数据 + bytes Data = 3; //不参与排行的数据 + int64 expireMs = 4; //剩余有效时间毫秒,如果为0永不过期 +} + +// RankPosData 排行数据——查询返回 +message RankPosData { + uint64 Key = 1; //数据主建 + uint64 RankPos = 2; //名次 + repeated int64 SortData = 3; //参与排行的数据 + bytes Data = 4; //不参与排行的数据 +} + +// RankList 排行榜数据 +message RankList { + uint64 RankId = 1; //排行榜类型 + int32 SkipListLevel = 2; //排行榜level-生成的跳表的level, 8/16/32/64等 + bool IsDec = 3; //不参与排行的数据 + uint64 MaxRank = 4; //最大排名 +} + +// UpsetRankData 更新排行榜数据 +message UpsetRankData { + uint64 RankId = 1; //排行榜的ID + repeated RankData RankDataList = 2; //排行数据 +} + +// DeleteByKey 更新排行榜数据 +message DeleteByKey { + uint64 RankId = 1; //排行榜的分类ID + repeated uint64 KeyList = 2; //排行数据 +} + +// AddRankList 新增排行榜 +message AddRankList { + repeated RankList AddList = 1; //添加的排行榜列表 +} + +// FindRankDataByKey 查找排行信息 +message FindRankDataByKey { + uint64 RankId = 1; //排行榜的ID + uint64 Key = 2; //排行的key +} + +// FindRankDataByPos 查找排行信息 +message FindRankDataByPos { + uint64 RankId = 1; //排行榜的ID + uint64 Pos = 2; //排行名次 +} + +// FindRankDataListStartTo 查找排行信息,StartPos开始Count个 +message FindRankDataListStartTo { + uint64 RankId = 1; //排行榜的ID + uint64 StartPos = 2; //排行的位置 0开始 + uint64 Count = 3; //查询格式 +} + +// RankDataList +message RankDataList { + uint64 RankDataCount = 1; //排行长度 + repeated RankPosData RankPosDataList = 2; //排行数据 +} + +// RankResult +message RankResult { + int32 AddCount = 1; //增加记录 + int32 RemoveCount = 2; //删除数量 + int32 ModifyCount = 3; //修改数量 +} diff --git a/util/algorithms/skip/interface.go b/util/algorithms/skip/interface.go new file mode 100644 index 0000000..5f816be --- /dev/null +++ b/util/algorithms/skip/interface.go @@ -0,0 +1,47 @@ +/* +Copyright 2014 Workiva, LLC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package skip + +// Comparator is a generic interface that represents items that can +// be compared. +type Comparator interface { + // Compare compares this interface with another. Returns a positive + // number if this interface is greater, 0 if equal, negative number + // if less. + Compare(Comparator) int +} + +// Comparators is a typed list of type Comparator. +type Comparators []Comparator + +// Iterator defines an interface that allows a consumer to iterate +// all results of a query. All values will be visited in-order. +type Iterator interface { + // Next returns a bool indicating if there is future value + // in the iterator and moves the iterator to that value. + Next() bool + // Prev returns a bool indicating if there is Previous value + // in the iterator and moves the iterator to that value. + Prev() bool + // Value returns a Comparator representing the iterator's current + // position. If there is no value, this returns nil. + Value() Comparator + // exhaust is a helper method that will iterate this iterator + // to completion and return a list of resulting Entries + // in order. + exhaust() Comparators +} diff --git a/util/algorithms/skip/iterator.go b/util/algorithms/skip/iterator.go new file mode 100644 index 0000000..09ab0ec --- /dev/null +++ b/util/algorithms/skip/iterator.go @@ -0,0 +1,86 @@ +/* +Copyright 2014 Workiva, LLC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package skip + +const iteratorExhausted = -2 + +// iterator represents an object that can be iterated. It will +// return false on Next and nil on Value if there are no further +// values to be iterated. +type iterator struct { + first bool + n *node +} + +// Next returns a bool indicating if there are any further values +// in this iterator. +func (iter *iterator) Next() bool { + if iter.first { + iter.first = false + return iter.n != nil + } + + if iter.n == nil { + return false + } + + iter.n = iter.n.forward[0] + return iter.n != nil +} + +// Prev returns a bool indicating if there are any Previous values +// in this iterator. +func (iter *iterator) Prev() bool { + if iter.first { + iter.first = false + return iter.n != nil + } + + if iter.n == nil { + return false + } + + iter.n = iter.n.preNode + return iter.n != nil && iter.n.entry != nil +} + +// Value returns a Comparator representing the iterator's present +// position in the query. Returns nil if no values remain to iterate. +func (iter *iterator) Value() Comparator { + if iter.n == nil { + return nil + } + + return iter.n.entry +} + +// exhaust is a helper method to exhaust this iterator and return +// all remaining entries. +func (iter *iterator) exhaust() Comparators { + entries := make(Comparators, 0, 10) + for i := iter; i.Next(); { + entries = append(entries, i.Value()) + } + + return entries +} + +// nilIterator returns an iterator that will always return false +// for Next and nil for Value. +func nilIterator() *iterator { + return &iterator{} +} diff --git a/util/algorithms/skip/node.go b/util/algorithms/skip/node.go new file mode 100644 index 0000000..525d97b --- /dev/null +++ b/util/algorithms/skip/node.go @@ -0,0 +1,50 @@ +/* +Copyright 2014 Workiva, LLC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package skip + +type widths []uint64 + +type nodes []*node + +type node struct { + // forward denotes the forward pointing pointers in this + // node. + forward nodes + //zero level pre node + preNode *node + // widths keeps track of the distance between this pointer + // and the forward pointers so we can access skip list + // values by position in logarithmic time. + widths widths + // entry is the associated value with this node. + entry Comparator +} + +func (n *node) Compare(e Comparator) int { + return n.entry.Compare(e) +} + +// newNode will allocate and return a new node with the entry +// provided. maxLevels will determine the length of the forward +// pointer list associated with this node. +func newNode(cmp Comparator, maxLevels uint8) *node { + return &node{ + entry: cmp, + forward: make(nodes, maxLevels), + widths: make(widths, maxLevels), + } +} diff --git a/util/algorithms/skip/skip.go b/util/algorithms/skip/skip.go new file mode 100644 index 0000000..2566567 --- /dev/null +++ b/util/algorithms/skip/skip.go @@ -0,0 +1,494 @@ +/* +Copyright 2014 Workiva, LLC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package skip defines a skiplist datastructure. That is, a data structure +that probabilistically determines relationships between keys. By doing +so, it becomes easier to program than a binary search tree but maintains +similar speeds. + +Performance characteristics: +Insert: O(log n) +Search: O(log n) +Delete: O(log n) +Space: O(n) + +Recently added is the capability to address, insert, and replace an +entry by position. This capability is acheived by saving the width +of the "gap" between two nodes. Searching for an item by position is +very similar to searching by value in that the same basic algorithm is +used but we are searching for width instead of value. Because this avoids +the overhead associated with Golang interfaces, operations by position +are about twice as fast as operations by value. Time complexities listed +below. + +SearchByPosition: O(log n) +InsertByPosition: O(log n) + +More information here: http://cglab.ca/~morin/teaching/5408/refs/p90b.pdf + +Benchmarks: +BenchmarkInsert-8 2000000 930 ns/op +BenchmarkGet-8 2000000 989 ns/op +BenchmarkDelete-8 3000000 600 ns/op +BenchmarkPrepend-8 1000000 1468 ns/op +BenchmarkByPosition-8 10000000 202 ns/op +BenchmarkInsertAtPosition-8 3000000 485 ns/op + +CPU profiling has shown that the most expensive thing we do here +is call Compare. A potential optimization for gets only is to +do a binary search in the forward/width lists instead of visiting +every value. We could also use generics if Golang had them and +let the consumer specify primitive types, which would speed up +these operation dramatically. +*/ +package skip + +import ( + "math/rand" + "sync" + "sync/atomic" + "time" +) + +const p = .5 // the p level defines the probability that a node +// with a value at level i also has a value at i+1. This number +// is also important in determining max level. Max level will +// be defined as L(N) where L = log base (1/p) of n where n +// is the number of items in the list and N is the number of possible +// items in the universe. If p = .5 then maxlevel = 32 is appropriate +// for uint32. + +// lockedSource is an implementation of rand.Source that is safe for +// concurrent use by multiple goroutines. The code is modeled after +// https://golang.org/src/math/rand/rand.go. +type lockedSource struct { + mu sync.Mutex + src rand.Source +} + +// Int63 implements the rand.Source interface. +func (ls *lockedSource) Int63() (n int64) { + ls.mu.Lock() + n = ls.src.Int63() + ls.mu.Unlock() + return +} + +// Seed implements the rand.Source interface. +func (ls *lockedSource) Seed(seed int64) { + ls.mu.Lock() + ls.src.Seed(seed) + ls.mu.Unlock() +} + +// generator will be the common generator to create random numbers. It +// is seeded with unix nanosecond when this line is executed at runtime, +// and only executed once ensuring all random numbers come from the same +// randomly seeded generator. +var generator = rand.New(&lockedSource{src: rand.NewSource(time.Now().UnixNano())}) + +func generateLevel(maxLevel uint8) uint8 { + var level uint8 + for level = uint8(1); level < maxLevel-1; level++ { + if generator.Float64() >= p { + + return level + } + } + + return level +} + +func insertNode(sl *SkipList, n *node, cmp Comparator, pos uint64, cache nodes, posCache widths, allowDuplicate bool) Comparator { + if !allowDuplicate && n != nil && n.Compare(cmp) == 0 { // a simple update in this case + oldEntry := n.entry + n.entry = cmp + return oldEntry + } + atomic.AddUint64(&sl.num, 1) + + nodeLevel := generateLevel(sl.maxLevel) + if nodeLevel > sl.level { + for i := sl.level; i < nodeLevel; i++ { + cache[i] = sl.head + } + sl.level = nodeLevel + } + + nn := newNode(cmp, nodeLevel) + for i := uint8(0); i < nodeLevel; i++ { + if i == 0 { + nn.preNode = cache[i] + if cache[i].forward[i] != nil { + cache[i].forward[i].preNode = nn + } + } + + nn.forward[i] = cache[i].forward[i] + cache[i].forward[i] = nn + + formerWidth := cache[i].widths[i] + if formerWidth == 0 { + nn.widths[i] = 0 + } else { + nn.widths[i] = posCache[i] + formerWidth + 1 - pos + } + + if cache[i].forward[i] != nil { + cache[i].widths[i] = pos - posCache[i] + } + + } + + for i := nodeLevel; i < sl.level; i++ { + if cache[i].forward[i] == nil { + continue + } + cache[i].widths[i]++ + } + return nil +} + +func splitAt(sl *SkipList, index uint64) (*SkipList, *SkipList) { + right := &SkipList{} + right.maxLevel = sl.maxLevel + right.level = sl.level + right.cache = make(nodes, sl.maxLevel) + right.posCache = make(widths, sl.maxLevel) + right.head = newNode(nil, sl.maxLevel) + sl.searchByPosition(index, sl.cache, sl.posCache) // populate the cache that needs updating + + for i := uint8(0); i <= sl.level; i++ { + right.head.forward[i] = sl.cache[i].forward[i] + if sl.cache[i].forward[i] != nil { + right.head.widths[i] = sl.cache[i].widths[i] - (index - sl.posCache[i]) + } + sl.cache[i].widths[i] = 0 + sl.cache[i].forward[i] = nil + } + + right.num = sl.Len() - index // right is not in user's hands yet + atomic.AddUint64(&sl.num, -right.num) + + sl.resetMaxLevel() + right.resetMaxLevel() + + return sl, right +} + +// Skip list is a datastructure that probabalistically determines +// relationships between nodes. This results in a structure +// that performs similarly to a BST but is much easier to build +// from a programmatic perspective (no rotations). +type SkipList struct { + maxLevel, level uint8 + head *node + num uint64 + // a list of nodes that can be reused, should reduce + // the number of allocations in the insert/delete case. + cache nodes + posCache widths +} + +// init will initialize this skiplist. The parameter is expected +// to be of some uint type which will set this skiplist's maximum +// level. +func (sl *SkipList) init(ifc interface{}) { + switch ifc.(type) { + case uint8: + sl.maxLevel = 8 + case uint16: + sl.maxLevel = 16 + case uint32: + sl.maxLevel = 32 + case uint64, uint: + sl.maxLevel = 64 + } + sl.cache = make(nodes, sl.maxLevel) + sl.posCache = make(widths, sl.maxLevel) + sl.head = newNode(nil, sl.maxLevel) +} + +func (sl *SkipList) search(cmp Comparator, update nodes, widths widths) (*node, uint64) { + if sl.Len() == 0 { // nothing in the list + return nil, 1 + } + + var pos uint64 = 0 + var offset uint8 + var alreadyChecked *node + n := sl.head + for i := uint8(0); i <= sl.level; i++ { + offset = sl.level - i + for n.forward[offset] != nil && n.forward[offset] != alreadyChecked && n.forward[offset].Compare(cmp) < 0 { + pos += n.widths[offset] + n = n.forward[offset] + } + + alreadyChecked = n + if update != nil { + update[offset] = n + widths[offset] = pos + } + } + + return n.forward[0], pos + 1 +} + +func (sl *SkipList) resetMaxLevel() { + if sl.level < 1 { + sl.level = 1 + return + } + for sl.head.forward[sl.level-1] == nil && sl.level > 1 { + sl.level-- + } +} + +func (sl *SkipList) searchByPosition(position uint64, update nodes, widths widths) (*node, uint64) { + if sl.Len() == 0 { // nothing in the list + return nil, 1 + } + + if position > sl.Len() { + return nil, 1 + } + + var pos uint64 = 0 + var offset uint8 + n := sl.head + for i := uint8(0); i <= sl.level; i++ { + offset = sl.level - i + for n.forward[offset] != nil && pos+n.widths[offset] <= position { + pos += n.widths[offset] + n = n.forward[offset] + } + + if update != nil { + update[offset] = n + widths[offset] = pos + } + } + + return n, pos + 1 +} + +// Get will retrieve values associated with the keys provided. If an +// associated value could not be found, a nil is returned in its place. +// This is an O(log n) operation. +func (sl *SkipList) Get(comparators ...Comparator) Comparators { + result := make(Comparators, 0, len(comparators)) + + var n *node + for _, cmp := range comparators { + n, _ = sl.search(cmp, nil, nil) + if n != nil && n.Compare(cmp) == 0 { + result = append(result, n.entry) + } else { + result = append(result, nil) + } + } + + return result +} + +// GetWithPosition will retrieve the value with the provided key and +// return the position of that value within the list. Returns nil, 0 +// if an associated value could not be found. +func (sl *SkipList) GetWithPosition(cmp Comparator) (Comparator, uint64) { + n, pos := sl.search(cmp, nil, nil) + if n == nil { + return nil, 0 + } + + return n.entry, pos - 1 +} + +// ByPosition returns the Comparator at the given position. +func (sl *SkipList) ByPosition(position uint64) Comparator { + n, _ := sl.searchByPosition(position+1, nil, nil) + if n == nil { + return nil + } + + return n.entry +} + +func (sl *SkipList) insert(cmp Comparator) Comparator { + n, pos := sl.search(cmp, sl.cache, sl.posCache) + return insertNode(sl, n, cmp, pos, sl.cache, sl.posCache, false) +} + +// Insert will insert the provided comparators into the list. Returned +// is a list of comparators that were overwritten. This is expected to +// be an O(log n) operation. +func (sl *SkipList) Insert(comparators ...Comparator) Comparators { + overwritten := make(Comparators, 0, len(comparators)) + for _, cmp := range comparators { + overwritten = append(overwritten, sl.insert(cmp)) + } + + return overwritten +} + +func (sl *SkipList) insertAtPosition(position uint64, cmp Comparator) { + if position > sl.Len() { + position = sl.Len() + } + n, pos := sl.searchByPosition(position, sl.cache, sl.posCache) + insertNode(sl, n, cmp, pos, sl.cache, sl.posCache, true) +} + +// InsertAtPosition will insert the provided Comparator at the provided position. +// If position is greater than the length of the skiplist, the Comparator +// is appended. This method bypasses order checks and checks for +// duplicates so use with caution. +func (sl *SkipList) InsertAtPosition(position uint64, cmp Comparator) { + sl.insertAtPosition(position, cmp) +} + +func (sl *SkipList) replaceAtPosition(position uint64, cmp Comparator) { + n, _ := sl.searchByPosition(position+1, nil, nil) + if n == nil { + return + } + + n.entry = cmp +} + +// Replace at position will replace the Comparator at the provided position +// with the provided Comparator. If the provided position does not exist, +// this operation is a no-op. +func (sl *SkipList) ReplaceAtPosition(position uint64, cmp Comparator) { + sl.replaceAtPosition(position, cmp) +} + +func (sl *SkipList) delete(cmp Comparator) Comparator { + n, _ := sl.search(cmp, sl.cache, sl.posCache) + + if n == nil || n.Compare(cmp) != 0 { + return nil + } + + atomic.AddUint64(&sl.num, ^uint64(0)) // decrement + + for i := uint8(0); i <= sl.level; i++ { + if sl.cache[i].forward[i] != n { + if sl.cache[i].forward[i] != nil { + sl.cache[i].widths[i]-- + } + continue + } + + if i == 0 { + if n.forward[i] != nil { + n.forward[i].preNode = sl.cache[i] + } + n.preNode = nil + } + + sl.cache[i].widths[i] += n.widths[i] - 1 + sl.cache[i].forward[i] = n.forward[i] + } + + for sl.level > 1 && sl.head.forward[sl.level-1] == nil { + sl.head.widths[sl.level] = 0 + sl.level-- + } + + return n.entry +} + +// Delete will remove the provided keys from the skiplist and return +// a list of in-order Comparators that were deleted. This is a no-op if +// an associated key could not be found. This is an O(log n) operation. +func (sl *SkipList) Delete(comparators ...Comparator) Comparators { + deleted := make(Comparators, 0, len(comparators)) + + for _, cmp := range comparators { + deleted = append(deleted, sl.delete(cmp)) + } + + return deleted +} + +// Len returns the number of items in this skiplist. +func (sl *SkipList) Len() uint64 { + return atomic.LoadUint64(&sl.num) +} + +func (sl *SkipList) iterAtPosition(pos uint64) *iterator { + n, _ := sl.searchByPosition(pos, nil, nil) + if n == nil || n.entry == nil { + return nilIterator() + } + + return &iterator{ + first: true, + n: n, + } +} + +// IterAtPosition is the sister method to Iter only the user defines +// a position in the skiplist to begin iteration instead of a value. +func (sl *SkipList) IterAtPosition(pos uint64) Iterator { + return sl.iterAtPosition(pos + 1) +} + +func (sl *SkipList) iter(cmp Comparator) *iterator { + n, _ := sl.search(cmp, nil, nil) + if n == nil { + return nilIterator() + } + + return &iterator{ + first: true, + n: n, + } +} + +// Iter will return an iterator that can be used to iterate +// over all the values with a key equal to or greater than +// the key provided. +func (sl *SkipList) Iter(cmp Comparator) Iterator { + return sl.iter(cmp) +} + +// SplitAt will split the current skiplist into two lists. The first +// skiplist returned is the "left" list and the second is the "right." +// The index defines the last item in the left list. If index is greater +// then the length of this list, only the left skiplist is returned +// and the right will be nil. This is a mutable operation and modifies +// the content of this list. +func (sl *SkipList) SplitAt(index uint64) (*SkipList, *SkipList) { + index++ // 0-index offset + if index >= sl.Len() { + return sl, nil + } + return splitAt(sl, index) +} + +// New will allocate, initialize, and return a new skiplist. +// The provided parameter should be of type uint and will determine +// the maximum possible level that will be created to ensure +// a random and quick distribution of levels. Parameter must +// be a uint type. +func New(ifc interface{}) *SkipList { + sl := &SkipList{} + sl.init(ifc) + return sl +}