Namdak Tonpa 7 лет назад
Родитель
Сommit
4710e04f22
3 измененных файлов с 127 добавлено и 2 удалено
  1. 7 0
      include/kvs.hrl
  2. 117 0
      src/kvs_stream.erl
  3. 3 2
      src/kvs_user.erl

+ 7 - 0
include/kvs.hrl

@@ -1,6 +1,13 @@
 -ifndef(KVS_HRL).
 -define(KVS_HRL, true).
 
+-record(cursor, {feed=[]::term(),
+                 tab= []::atom(),
+                 id=  []::[]|integer(),
+                 val= []::[]|tuple(),
+                 top= []::[]|integer(),
+                 bot= []::[]|integer()}).
+
 -define(CONTAINER, id=[] :: [] | integer(),
                    top=[] :: [] | integer(),
                    rear=[] :: [] | integer(),

+ 117 - 0
src/kvs_stream.erl

@@ -0,0 +1,117 @@
+-module(kvs_stream).
+-include("kvs.hrl").
+-include("user.hrl").
+-compile(export_all).
+
+new(Tab) -> #cursor{feed=kvs:next_id(cursor,1),tab=Tab}.
+
+
+
+take(top,Number,Cursor)   -> take(next,Number,top(Cursor),[]);
+take(bot,Number,Cursor)   -> take(prev,Number,bot(Cursor),[]).
+take(___,_,{error,_},Res) -> lists:flatten(Res);
+take(___,0,Cursor,Res)    -> lists:flatten(Res);
+take(Atom,Number,#cursor{val=Body}=Cursor,Res) ->
+    take(Atom,Number-1,?MODULE:Atom(Cursor),[Body|Res]).
+
+add(Atom,Message,#cursor{tab=Table,bot=Bot,val=[]}=Cursor) ->
+    n2o:info(?MODULE, "add ~p val=[]:", [Atom]),
+    Id = element(2,Message),
+    M1 = setelement(#iterator.prev, Message, Bot),
+    M2 = setelement(#iterator.next, M1,      []),
+    n2o:info(?MODULE, "M2: ~w",[M2]),
+    kvs:put(M2),
+    Cursor#cursor{val=M2,id=Id,bot=Id,top=Id};
+
+add(top,Message,#cursor{tab=Table,top=Top,val=Body}=Cursor) when element(2, Body) /= Top ->
+    n2o:info(?MODULE, "add top seek:", []),
+    add(top,Message,top(Cursor));
+
+add(bot,Message,#cursor{tab=Table,bot=Bot,val=Body}=Cursor) when element(2, Body) /= Bot ->
+    n2o:info(?MODULE, "add bot seek:", []),
+    add(bot,Message,bot(Cursor));
+
+add(top,Message,#cursor{tab=Table,bot=[],top=Top,val=Body}=Cursor) ->
+    n2o:info(?MODULE, "add top []:~w",[Body]),
+    Id = element(2,Message),
+    M1 = setelement(#iterator.next, Message, Top),
+    M2 = setelement(#iterator.prev, M1,      []),
+    kvs:put(M2),
+    n2o:info(?MODULE, "Body: ~w",[Body]),
+    n2o:info(?MODULE, "M2: ~w",[M2]),
+    Cursor#cursor{val=M2,id=Id,top=Id,bot=Id};
+
+add(bot,Message,#cursor{tab=Table,bot=Bot,top=[],val=Body}=Cursor) ->
+    n2o:info(?MODULE, "add bot []:~w", [Body]),
+    Id = element(2,Message),
+    M1 = setelement(#iterator.prev, Message, Bot),
+    M2 = setelement(#iterator.next, M1,      []),
+    n2o:info(?MODULE, "Body: ~w",[Body]),
+    n2o:info(?MODULE, "M2: ~w",[M2]),
+    kvs:put(M2),
+    Cursor#cursor{val=M2,id=Id,bot=Id,top=Id};
+
+add(top,Message,#cursor{tab=Table,top=Top,val=Body}=Cursor) ->
+    n2o:info(?MODULE, "add top:~w", [Body]),
+    Id = element(2,Message),
+    M1 = setelement(#iterator.next, Message, Top),
+    M2 = setelement(#iterator.prev, M1,      []),
+    M3 = setelement(#iterator.prev, Body,    Id),
+    n2o:info(?MODULE, "Body: ~w",[Body]),
+    n2o:info(?MODULE, "M2: ~w",[M2]),
+    n2o:info(?MODULE, "M3: ~w",[M3]),
+    kvs:put(M2),
+    kvs:put(M3),
+    Cursor#cursor{val=M2,id=Id,top=Id};
+
+add(bot,Message,#cursor{tab=Table,bot=Bot,val=Body}=Cursor) ->
+    n2o:info(?MODULE, "add bot:~w",[Body]),
+    Id = element(2,Message),
+    M1 = setelement(#iterator.prev, Message, Bot),
+    M2 = setelement(#iterator.next, M1,      []),
+    M3 = setelement(#iterator.next, Body,    Id),
+    kvs:put(M2),
+    kvs:put(M3),
+    n2o:info(?MODULE, "Body: ~w",[Body]),
+    n2o:info(?MODULE, "M2: ~w",[M2]),
+    n2o:info(?MODULE, "M3: ~w",[M3]),
+    Cursor#cursor{val=M2,id=Id,bot=Id}.
+
+top(#cursor{top=Top}=Cursor) -> seek(Top,Cursor).
+bot(#cursor{bot=Bot}=Cursor) -> seek(Bot,Cursor).
+
+seek(Id, #cursor{tab=Tab}=Cursor) ->
+    case kvs:get(Tab,Id) of
+         {ok, Record} -> Tab = element(1,Record),
+                         Id = element(2,Record),
+                         Cursor#cursor{id=Id,val=Record} end.
+
+next(#cursor{tab=Table,id=Id,val=Body}=Cursor) ->
+    Next = element(#iterator.next,Body),
+    case kvs:get(Table,Next) of
+         {ok, Record} -> Cursor#cursor{id=element(2,Record),val=Record};
+         {error, Err} -> {error,Err} end.
+
+prev(#cursor{tab=Table,id=Id,val=Body}=Cursor) ->
+    Next = element(#iterator.prev,Body),
+    case kvs:get(Table,Next) of
+         {ok, Record} -> Cursor#cursor{id=element(2,Record),val=Record};
+         {error, Err} -> {error,Err} end.
+
+save(Cursor) ->
+    kvs:put(Cursor), Cursor.
+
+load(#cursor{feed=Key}) ->
+    kvs:get(cursor,Key).
+
+test() ->
+    A = save(
+        add(top,#user{id=kvs:next_id(user,1)},
+        add(bot,#user{id=kvs:next_id(user,1)},
+        add(top,#user{id=kvs:next_id(user,1)},
+        add(bot,#user{id=kvs:next_id(user,1)},
+        new(user)))))),
+    X = take(top,-1,A),
+    Y = take(bot,-1,A),
+    X = lists:reverse(Y),
+    ok.

+ 3 - 2
src/kvs_user.erl

@@ -1,5 +1,6 @@
 -module(kvs_user).
 -copyright('Synrc Research Center s.r.o.').
+-include("kvs.hrl").
 -include("user.hrl").
 -include("group.hrl").
 -include("metainfo.hrl").
@@ -9,7 +10,7 @@ metainfo() ->
     #schema{name=kvs,tables=[
 %        #table{name=user2,container=feed,fields=record_info(fields,user2)},
         #table{name=group,container=feed,fields=record_info(fields,group)},
-        #table{name=user,container=feed,fields=record_info(fields,user),
-                 keys=[email]}
+        #table{name=cursor,container=feed,fields=record_info(fields,cursor)},
+        #table{name=user,container=feed,fields=record_info(fields,user),keys=[email]}
     ]}.