|
|
@ -2,8 +2,13 @@ |
|
|
|
|
|
|
|
-behavior(gen_srv). |
|
|
|
|
|
|
|
-include("ranks.hrl"). |
|
|
|
|
|
|
|
-export([ |
|
|
|
start_link/1 |
|
|
|
, mUpdateScore/3 |
|
|
|
, mUpdateInfo/2 |
|
|
|
, mGetRankInfo/5 |
|
|
|
]). |
|
|
|
|
|
|
|
-export([ |
|
|
@ -25,8 +30,6 @@ start_link(SrvName) -> |
|
|
|
init(_Args) -> |
|
|
|
{ok, #state{}}. |
|
|
|
|
|
|
|
handleCall(_Msg, _State, _FROM) -> |
|
|
|
{reply, ok}; |
|
|
|
handleCall(_Msg, _State, _FROM) -> |
|
|
|
{reply, ok}. |
|
|
|
|
|
|
@ -42,3 +45,132 @@ terminate(_Reason, _State) -> |
|
|
|
code_change(_OldVsn, State, _Extra) -> |
|
|
|
{ok, State}. |
|
|
|
%% ****************************************************** logic ******************************************************** |
|
|
|
|
|
|
|
mUpdateScore(Key, RankType, Score) -> |
|
|
|
{_RankLimit, RankMax} = ?ranksLimit:getV(RankType), |
|
|
|
RankPos = ?ranksCfg:getV(RankType), |
|
|
|
case ets:lookup(etsRankInfo, Key) of |
|
|
|
[RankRecord] -> |
|
|
|
OldScore = element(RankPos, RankRecord), |
|
|
|
ets:delete(RankType, OldScore), |
|
|
|
|
|
|
|
RankSize = ets:info(RankType, size), |
|
|
|
case RankSize >= RankMax of |
|
|
|
true -> |
|
|
|
FirstKey = ets:first(RankType), |
|
|
|
case Score > FirstKey of |
|
|
|
true -> |
|
|
|
ets:insert(RankType, Score), |
|
|
|
ets:delete(RankType, FirstKey); |
|
|
|
_ -> |
|
|
|
ignore |
|
|
|
end; |
|
|
|
_ -> |
|
|
|
ets:insert(RankType, Score) |
|
|
|
end, |
|
|
|
ets:update_element(etsRankInfo, Key, {RankPos, Score}); |
|
|
|
_ -> |
|
|
|
%% 插入新的数据 |
|
|
|
RankSize = ets:info(RankType, size), |
|
|
|
case RankSize >= RankMax of |
|
|
|
true -> |
|
|
|
FirstKey = ets:first(RankType), |
|
|
|
case Score > FirstKey of |
|
|
|
true -> |
|
|
|
ets:insert(RankType, Score), |
|
|
|
ets:delete(RankType, FirstKey), |
|
|
|
NewRecord = #etsRankRecord{key = Key}, |
|
|
|
RankRecord = setelement(RankPos, NewRecord, Score), |
|
|
|
ets:insert(etsRankInfo, RankRecord); |
|
|
|
_ -> |
|
|
|
ignore |
|
|
|
end; |
|
|
|
_ -> |
|
|
|
ets:insert(RankType, Score), |
|
|
|
NewRecord = #etsRankRecord{key = Key}, |
|
|
|
RankRecord = setelement(RankPos, NewRecord, Score), |
|
|
|
ets:insert(etsRankInfo, RankRecord) |
|
|
|
end |
|
|
|
end, |
|
|
|
{mayReply, ok}. |
|
|
|
|
|
|
|
mUpdateInfo(Key, RecordKvs) -> |
|
|
|
ets:update_element(etsRankInfo, Key, RecordKvs), |
|
|
|
{mayReply, ok}. |
|
|
|
|
|
|
|
mGetRankInfo(RankType, MyKey, Cnt, Page, PageInfo) -> |
|
|
|
{RankLimit, _RankMax} = ?ranksLimit:getV(RankType), |
|
|
|
|
|
|
|
%% 请求第一页的时候 附加上自己的排名 |
|
|
|
SelfRank = |
|
|
|
case Page of |
|
|
|
0 -> |
|
|
|
case ets:lookup_element(etsRankInfo, MyKey) of |
|
|
|
[RankRecord] -> |
|
|
|
RankPos = ?ranksCfg:getV(RankType), |
|
|
|
CurScore = element(RankPos, RankRecord), |
|
|
|
MyIndex = ets:select_count(RankType, [{{'$1', '$2'}, [{'>=', '$1', CurScore}], [true]}]), |
|
|
|
max(RankLimit, MyIndex); |
|
|
|
_ -> |
|
|
|
-1 |
|
|
|
end; |
|
|
|
_ -> |
|
|
|
0 |
|
|
|
end, |
|
|
|
|
|
|
|
MS = |
|
|
|
case PageInfo == 0 orelse PageInfo of |
|
|
|
true -> |
|
|
|
[{'$1', [], ['$1']}]; |
|
|
|
<<"">> -> |
|
|
|
[{'$1', [], ['$1']}]; |
|
|
|
_ -> |
|
|
|
try binary_to_term(PageInfo) of |
|
|
|
KeyTerm when KeyTerm == <<"">>; KeyTerm == "" -> |
|
|
|
[{'$1', [], ['$1']}]; |
|
|
|
KeyTerm -> |
|
|
|
% ets:fun2ms(fun({K, _V} = T) when K < KeyTerm -> T end) |
|
|
|
[{{'$1', '$2'}, [{'<', '$1', KeyTerm}], ['$_']}] |
|
|
|
catch _C:_R -> |
|
|
|
[{'$1', [], ['$1']}] |
|
|
|
end |
|
|
|
end, |
|
|
|
|
|
|
|
case ets:select_reverse(RankType, MS, Cnt) of |
|
|
|
'$end_of_table' -> |
|
|
|
{true, {<<"">>, []}}; |
|
|
|
{KeyIds, '$end_of_table'} -> |
|
|
|
{true, SelfRank, makeRankData(KeyIds, Cnt * Page + 1)}; |
|
|
|
{KeyIds, _NextKey} -> |
|
|
|
Length = length(KeyIds), |
|
|
|
if |
|
|
|
Length < Cnt -> |
|
|
|
{true, SelfRank, makeRankData(KeyIds, Cnt * Page + 1)}; |
|
|
|
true -> |
|
|
|
NewCurCnt = Page * Cnt + Length, |
|
|
|
case NewCurCnt >= RankLimit of |
|
|
|
true -> |
|
|
|
{true, SelfRank, makeRankData(KeyIds, Cnt * Page + 1)}; |
|
|
|
_ -> |
|
|
|
{false, SelfRank, makeRankData(KeyIds, Cnt * Page + 1)} |
|
|
|
end |
|
|
|
end |
|
|
|
end. |
|
|
|
|
|
|
|
makeRankData(KeyIds, Idx) -> |
|
|
|
makeRankData(KeyIds, Idx, <<"">>, []). |
|
|
|
|
|
|
|
makeRankData([], _Idx, LastKey, Acc) -> |
|
|
|
case LastKey of |
|
|
|
<<"">> -> |
|
|
|
{LastKey, lists:reverse(Acc)}; |
|
|
|
_ -> |
|
|
|
{erlang:term_to_binary(LastKey), lists:reverse(Acc)} |
|
|
|
end; |
|
|
|
makeRankData([{CurKey, Score} | KeyIds], Idx, LastKey, Acc) -> |
|
|
|
case ets:lookup(ets_pub_rank_info, CurKey) of |
|
|
|
[OneData] -> |
|
|
|
makeRankData(KeyIds, Idx + 1, CurKey, [#rankInfo{rank = Idx, key = CurKey, publicInfo = element(?publicInfoPos, OneData), rankTypeScore = Score} | Acc]); |
|
|
|
_ -> |
|
|
|
makeRankData(KeyIds, Idx, LastKey, Acc) |
|
|
|
end. |