瀏覽代碼

ft: 完善代码

master
SisMaker 3 年之前
父節點
當前提交
592ed0b401
共有 7 個檔案被更改,包括 154 行新增58 行删除
  1. +21
    -0
      include/etsmatch.hrl.in
  2. +2
    -0
      include/ranks.hrl
  3. +1
    -1
      src/rank/rankMgr.erl
  4. +70
    -0
      src/rank/rankTest.erl
  5. +46
    -47
      src/rank/rankWork.erl
  6. +13
    -9
      src/ranks.erl
  7. +1
    -1
      src/ranks_app.erl

+ 21
- 0
include/etsmatch.hrl.in 查看文件

@ -0,0 +1,21 @@
-type matchExpression() :: [ matchFunction(), ... ].
-type matchFunction() :: { matchHead(), matchConditions(), matchBody()}.
-type matchHead() :: matchVariable() | '_' | { matchHeadPart(), ...}.
-type matchHeadPart() :: term() | matchVariable() | '_'.
-type matchVariable() :: '$<number>'.
-type matchConditions() :: [ matchCondition(), ...] | [].
-type matchCondition() :: { guardFunction() } | { guardFunction(), conditionExpression(), ... }.
-type boolFunction() :: is_atom | is_float | is_integer | is_list | is_number | is_pid | is_port | is_reference | is_tuple | is_map | map_is_key | is_binary | is_function | is_record | 'and' | 'or' | 'not' | 'xor' | 'andalso' | 'orelse'.
-type conditionExpression() :: exprMatchVariable() | { guardFunction() } | { guardFunction(), conditionExpression(), ... } | termConstruct().
-type exprMatchVariable() :: matchVariable() (bound in the MatchHead) | '$_' | '$$'
-type termConstruct():: {{}} | {{ conditionExpression(), ... }} | [] | [conditionExpression(), ...] | #{} | #{term() => conditionExpression(), ...} | nonCompositeTerm() | constant().
-type nonCompositeTerm() :: term(). %% (not list or tuple or map)
-type constant() :: {const, term()}.
-type guardFunction() :: boolFunction() | abs | element | hd | length | map_get | map_size | node | round | size | bit_size | tl | trunc | '+' | '-' | '*' | 'div' | 'rem' | 'band' | 'bor' | 'bxor' | 'bnot' | 'bsl' | 'bsr' | '>' | '>=' | '<' | '=<' | '=:=' | '==' | '=/=' | '/=' | self.
-type matchBody() :: [ conditionExpression(), ... ].

+ 2
- 0
include/ranks.hrl 查看文件

@ -25,6 +25,8 @@
, rankTypeNScore :: term()
}).
-define(AllRankType, [rankType1Score, rankType2Score, rankTypeNScore]).
-record(rankInfo, {
rank :: integer()
, key :: integer()

+ 1
- 1
src/rank/rankMgr.erl 查看文件

@ -35,7 +35,7 @@ handleCall({mInitRank, RankType, CntLimit, CntMax}, State, _FROM) ->
_ ->
ets:new(RankType, [ordered_set, public, named_table, {write_concurrency, auto}, {read_concurrency, true}, {decentralized_counters, false}]),
NewState = State#{RankType => {CntLimit, CntMax}},
gtKvsToBeam:load(?ranksLimit, maps:to_list(NewState)),
rsKvsToBeam:load(?ranksLimit, maps:to_list(NewState)),
{reply, ok, NewState}
end;
handleCall(_Msg, _State, _FROM) ->

+ 70
- 0
src/rank/rankTest.erl 查看文件

@ -0,0 +1,70 @@
-module(rankTest).
-behavior(gen_srv).
-include("ranks.hrl").
-export([
start_link/2
, start/3
]).
-export([
init/1
, handleCall/3
, handleCast/2
, handleInfo/2
, terminate/2
, code_change/3
]).
start(Cnt, Num, Limit) ->
ranks:startWork(4) ,
[ranks:initRank(RankType, ceil(Limit * 0.6), Limit) || RankType <- ?AllRankType],
doTest(Cnt, Num).
doTest(0, _) ->
ok;
doTest(Cnt, Num) ->
start_link(Cnt, Num),
doTest(Cnt - 1, Num).
-record(state, {id, num}).
%% ******************************************** API *******************************************************************
start_link(Id, Num) ->
gen_srv:start_link(?MODULE, {Id, Num}, []).
%% ******************************************** callback **************************************************************
init({Id, Num}) ->
ranks:updateInfo(Id, {?publicInfoPos, {Id, Num, self()}}),
{ok, #state{id = Id, num = Num}, 0}.
handleCall(_Msg, _State, _FROM) ->
{reply, ok}.
handleCast(_Msg, _State) ->
kpS.
handleInfo(timeout, #state{id = Id, num = Num} = State) ->
RankType = lists:nth(rand:uniform(3), ?AllRankType),
Score = rand:uniform(10000),
ranks:updateScore(RankType, Id, {Score, Id}),
NewNum = Num - 1,
case NewNum < 0 of
true ->
io:format("test over ~p~n", [Id]),
{stop, normal, State};
_ ->
{noreply, State#state{num = NewNum}, 0}
end;
handleInfo(_Msg, _State) ->
kpS.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%% ****************************************************** logic ********************************************************

+ 46
- 47
src/rank/rankWork.erl 查看文件

@ -46,12 +46,12 @@ code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%% ****************************************************** logic ********************************************************
mUpdateScore(Key, RankType, Score) ->
mUpdateScore(RankType, Key, Score) ->
{_RankLimit, RankMax} = ?ranksLimit:getV(RankType),
RankPos = ?ranksCfg:getV(RankType),
case ets:lookup(etsRankInfo, Key) of
[RankRecord] ->
OldScore = element(RankPos, RankRecord),
try ets:lookup_element(?etsRankInfo, Key, RankPos) of
OldScore ->
ets:delete(RankType, OldScore),
RankSize = ets:info(RankType, size),
@ -60,42 +60,43 @@ mUpdateScore(Key, RankType, Score) ->
FirstKey = ets:first(RankType),
case Score > FirstKey of
true ->
ets:insert(RankType, Score),
ets:insert(RankType, {Score, Key}),
ets:delete(RankType, FirstKey);
_ ->
ignore
end;
_ ->
ets:insert(RankType, Score)
ets:insert(RankType, {Score, Key})
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
ets:update_element(?etsRankInfo, Key, {RankPos, Score})
catch _:_ ->
%%
RankSize = ets:info(RankType, size),
case RankSize >= RankMax of
true ->
FirstKey = ets:first(RankType),
case Score > FirstKey of
true ->
ets:insert(RankType, {Score, Key}),
ets:delete(RankType, FirstKey),
NewRecord = #etsRankRecord{key = Key},
RankRecord = setelement(RankPos, NewRecord, Score),
ets:insert(?etsRankInfo, RankRecord);
_ ->
ignore
end;
_ ->
ets:insert(RankType, {Score, Key}),
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),
ets:update_element(?etsRankInfo, Key, RecordKvs),
{mayReply, ok}.
mGetRankInfo(RankType, MyKey, Cnt, Page, PageInfo) ->
@ -105,14 +106,13 @@ mGetRankInfo(RankType, MyKey, Cnt, Page, PageInfo) ->
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
RankPos = ?ranksCfg:getV(RankType),
try ets:lookup_element(?etsRankInfo, MyKey, RankPos) of
CurScore ->
MyIndex = ets:select_count(RankType, [{{'$1', '$2'}, [{'>=', '$1', {const, CurScore}}], [true]}]),
?IIF(MyIndex > RankLimit, -1, MyIndex)
catch _:_ ->
-1
end;
_ ->
0
@ -129,9 +129,8 @@ mGetRankInfo(RankType, MyKey, Cnt, Page, PageInfo) ->
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', '$2'}, [{'<', '$1', {const, KeyTerm}}], ['$_']}]
catch _:_ ->
[{'$1', [], ['$1']}]
end
end,
@ -167,10 +166,10 @@ makeRankData([], _Idx, LastKey, 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)
makeRankData([{Score, CurKey} | KeyIds], Idx, LastKey, Acc) ->
try ets:lookup_element(?etsRankInfo, CurKey, ?publicInfoPos) of
PublicInfo ->
makeRankData(KeyIds, Idx + 1, CurKey, [#rankInfo{rank = Idx, key = CurKey, publicInfo = PublicInfo, rankTypeScore = Score} | Acc])
class="k">catch class="p">_:_ ->
makeRankData(KeyIds, Idx, LastKey, Acc)
end.

+ 13
- 9
src/ranks.erl 查看文件

@ -9,7 +9,7 @@
, initRank/3 %%
, updateScore/3 %%
, updateInfo/2 %%
, getRankInfo/4 %%
, getRankInfo/5 %%
]).
start() ->
@ -18,6 +18,7 @@ start() ->
stop() ->
application:stop(ranks).
-spec workName(Idx :: integer()) -> atom().
workName(Idx) ->
binary_to_atom(<<"$rankWork_", (integer_to_binary(Idx))/binary>>).
@ -34,35 +35,38 @@ startWork(Cnt) when Cnt > 0 ->
[supervisor:start_child(rankWork_sup, [WorkName]) || {_Idx, WorkName} <- NameList],
CfgList = [{?workCnt, Cnt} | NameList],
Fields = record_info(fields, etsRankRecord),
gtKvsToBeam:load(?ranksCfg, fieldIdx(Fields, 1, CfgList)),
rsKvsToBeam:load(?ranksCfg, fieldIdx(Fields, 2, CfgList)),
ok;
_Cnt ->
{error, started}
end.
-spec initRank(RankType :: atom(), CntLimit :: non_neg_integer(), CntMax :: non_neg_integer()) -> ok | {error, atom()}.
initRank(RankType, CntLimit, CntMax) ->
gen_srv:call(rankMgr, {mInitRank, RankType, CntLimit, CntMax}).
%% key
%% key Score {Score1, Score2, ..., Key}
-spec updateScore(RankType :: atom(), Key :: term(), Score :: tuple()) -> no_return().
updateScore(RankType, Key, Score) ->
WorkName = ?ranksCfg:getV(erlang:phash2(Key, ?ranksCfg:getV(?workCnt))),
RankPos = ?ranksCfg:getV(RankType),
%%
%%
%% gen_srv:clfn(WorkName, rank_work, mUpdateScore, [Key, RankPos, Score]),
%%
gen_srv:csfn(WorkName, rank_work, mUpdateScore, [Key, RankPos, Score]).
gen_srv:csfn(WorkName, rankWork, mUpdateScore, [RankType, Key, Score]).
%% key
-spec updateInfo(Key :: term(), RecordKvs :: {non_neg_integer(), term()} | [{non_neg_integer(), term()}, ...]) -> no_return().
updateInfo(Key, RecordKvs) ->
WorkName = ?ranksCfg:getV(erlang:phash2(Key, ?ranksCfg:getV(?workCnt))),
%%
%%
%% gen_srv:clfn(WorkName, rank_work, mUpdateInfo, [Key, RecordKvs]),
%%
gen_srv:csfn(WorkName, rank_work, mUpdateInfo, [Key, RecordKvs]).
gen_srv:csfn(WorkName, rankWork, mUpdateInfo, [Key, RecordKvs]).
%%
getRankInfo(RankType, Cnt, Page, PageInfo) ->
rankWork:mGetRankInfo(RankType, Cnt, Page, PageInfo).
%% {IsOver , SelfRank -1 0 , RankData }.
-spec getRankInfo(RankType :: atom(), MyKey :: term(), Cnt :: non_neg_integer(), Page :: integer(), PageInfo :: binary()) -> {IsOver :: boolean(), SelfRank :: integer(), RankData :: list()}.
getRankInfo(RankType, MyKey, Cnt, Page, PageInfo) ->
rankWork:mGetRankInfo(RankType, MyKey, Cnt, Page, PageInfo).

+ 1
- 1
src/ranks_app.erl 查看文件

@ -7,7 +7,7 @@
-export([start/2, stop/1]).
start(_StartType, _StartArgs) ->
gtKvsToBeam:load(?ranksCfg, [{?workCnt, 0}]),
rsKvsToBeam:load(?ranksCfg, [{?workCnt, 0}]),
ranks_sup:start_link().
stop(_State) ->

Loading…
取消
儲存