Namdak Tonpa 7 years ago
parent
commit
d77502178e
1 changed files with 52 additions and 39 deletions
  1. 52 39
      src/kvs_stream.erl

+ 52 - 39
src/kvs_stream.erl

@@ -1,31 +1,46 @@
 -module(kvs_stream).
 -include("kvs.hrl").
--export([ new/0, top/1, bot/1, take/2, load/1, save/1, down/1, up/1,
-          check/0, seek/2, rewind/1, next/1, prev/1, add/2, remove/2 ]).
+-export([
+    new/0, top/1, bot/1, take/2, load/1, save/1, down/1, up/1,
+    check/0, seek/1, rewind/1, next/1, prev/1, add/2, remove/2 ]).
 
 % PUBLIC
 
-new()                 -> application:set_env(kvs,mnesia_context,transaction),
-                         #cur{id=kvs:next_id(cur,1)}.
-up(C)                 -> C#cur{dir=0}.
-down(C)               -> C#cur{dir=1}.
-top(#cur{top=[]}=C)   -> C#cur{val=[]};
-top(#cur{top=T,left=L,right=R}=C)    -> (seek(T,C))#cur{left=0,right=L+R}.
-bot(#cur{bot=[]}=C)   -> C#cur{val=[]};
-bot(#cur{bot=B,left=L,right=R}=C)    -> (seek(B,C))#cur{left=L+R,right=0}.
-add(M,#cur{dir=D}=C) when element(2,M) == [] -> add(dir(D),si(M,kvs:next_id(tab(M),1)),C);
-add(M,#cur{dir=D}=C)  -> add(dir(D),M,C).
-save(#cur{}=C)        -> kvs:put(C), C.
-load(K)               -> case kvs:get(cur,K) of {ok,C} -> C; E -> E end.
-next(#cur{pos=[]}=C)  -> {error,[]};
-next(#cur{pos=B}=C)   -> {L,R} = right(C), lookup(kvs:get(tab(B),en(B)),C,{L,R}).
-prev(#cur{pos=[]}=C)  -> {error,[]};
-prev(#cur{pos=B}=C)   -> {L,R} = left(C), lookup(kvs:get(tab(B),ep(B)),C,{L,R}).
-take(N,#cur{dir=D}=C)    -> take(acc(D),N,C,[]).
-seek(I,  #cur{val=[]}=C) -> {error,[]};
-seek(I,   #cur{val=B}=C) -> {ok,R}=kvs:get(tab(B),I), C#cur{pos=R}.
-rewind(#cur{val=[]}=C)   -> {error,[]};
-rewind(#cur{dir=D,top=T,bot=B,val=V}=C) -> {ok,R}=kvs:get(tab(V),select(D,T,B)), C#cur{val=R}.
+new()   -> #cur{id=kvs:next_id(cur,1)}.
+up(C)   -> C#cur{dir=0}.
+down(C) -> C#cur{dir=1}.
+top(C)  -> seek(up(C)).
+bot(C)  -> seek(down(C)).
+
+seek(#cur{bot=[],dir=0}=C) -> C#cur{val=[]};
+seek(#cur{top=[],dir=1}=C) -> C#cur{val=[]};
+seek(#cur{bot=[],dir=0}=C) -> {error,[]};
+seek(#cur{top=[],dir=1}=C) -> {error,[]};
+seek(#cur{bot=X,pos=P,dir=0}=C) when element(2,P) == X -> C;
+seek(#cur{top=X,pos=P,dir=1}=C) when element(2,P) == X -> C;
+seek(#cur{top=T,bot=B,left=L,right=R,dir=0,pos=P}=C) ->
+    C#cur{pos=id(kvs:get(tab(P),B)),left=0,right=L+R};
+seek(#cur{top=T,bot=B,left=L,right=R,dir=1,pos=P}=C) ->
+    C#cur{pos=id(kvs:get(tab(P),T)),left=L+R,right=0}.
+
+rewind(#cur{val=[]}=C) -> {error,[]};
+rewind(#cur{dir=D,top=T,bot=B,val=V}=C) ->
+    C#cur{val=id(kvs:get(tab(V),select(D,T,B)))}.
+
+add(M,#cur{dir=D}=C) when element(2,M) == [] ->
+    add(dir(D),si(M,kvs:next_id(tab(M),1)),C);
+add(M,#cur{dir=D}=C) -> add(dir(D),M,C).
+
+save(C) -> kvs:put(C), C.
+load(K) -> case kvs:get(cur,K) of {ok,C} -> C; E -> E end.
+
+next(#cur{pos=[]}=C) -> {error,[]};
+next(#cur{pos=B} =C) -> pos(kvs:get(tab(B),en(B)),C,right(C)).
+prev(#cur{pos=[]}=C) -> {error,[]};
+prev(#cur{pos=B} =C) -> pos(kvs:get(tab(B),ep(B)),C,left(C)).
+
+take(N,#cur{dir=D}=C) -> take(acc(D),N,C,[]).
+
 remove(I,#cur{val=[]}=C) -> {error,val};
 remove(I, #cur{val=B,pos=X}=C) ->
     {ok,R}=kvs:get(tab(B),I), kvs:delete(tab(B),I),
@@ -94,9 +109,6 @@ m(_,_,I,_,I,L,R,P,V) -> {V,sn(P,id(L))};
 m(_,_,_,I,I,L,R,P,V) -> {V,sp(P,id(L))};
 m(_,_,_,_,I,L,R,P,V) -> {V,P}.
 
-cas(true,  L, R) -> L;
-cas(false, L, R) -> R.
-
 cv(R,V) -> setelement(#cur.val,   R, V).
 cb(R,V) -> setelement(#cur.bot,   R, V).
 ct(R,V) -> setelement(#cur.top,   R, V).
@@ -109,10 +121,11 @@ si(M,T) -> setelement(#iter.id, M, T).
 
 el(X,T) -> element(X, T).
 tab(T)  -> element(1, T).
+et(T)   -> element(#cur.top, T).
+eb(T)   -> element(#cur.bot, T).
 id(T)   -> element(#iter.id, T).
 en(T)   -> element(#iter.next, T).
 ep(T)   -> element(#iter.prev, T).
-
 dir(0)  -> top;
 dir(1)  -> bot.
 acc(0)  -> prev;
@@ -123,13 +136,13 @@ fix(M,X)      -> fix(kvs:get(M,X)).
 fix({ok,O})   -> O;
 fix(_)        -> [].
 
-lookup({ok,R},C,{X,Y})      -> C#cur{pos=R,left=X,right=Y};
-lookup({error,X},C,_)       -> {error,X}.
-take(_,_,{error,_},R)       -> lists:flatten(R);
-take(_,0,_,R)               -> lists:flatten(R);
-take(A,N,#cur{pos=B}=C,R)   -> take(A,N-1,?MODULE:A(C),[B|R]).
-swap(1,{L,R})               -> {R,L};
-swap(0,{L,R})               -> {L,R}.
+pos({ok,R},C,{X,Y})       -> C#cur{pos=R,left=X,right=Y};
+pos({error,X},C,_)        -> {error,X}.
+take(_,_,{error,_},R)     -> lists:flatten(R);
+take(_,0,_,R)             -> lists:flatten(R);
+take(A,N,#cur{pos=B}=C,R) -> take(A,N-1,?MODULE:A(C),[B|R]).
+swap(1,{L,R})             -> {R,L};
+swap(0,{L,R})             -> {L,R}.
 
 inc(#cur{left=L,right=R,dir=D})   -> swap(D,{L+1,R}).
 dec(#cur{left=0,right=0,dir=D})   -> swap(D,{0,0});
@@ -237,8 +250,8 @@ test1() ->
          add({person,B,[],[],[],[],[],[],[]},
          add({person,A,[],[],[],[],[],[],[]},
          new() ))))),
-    X  = take(-1,up(bot(R))),
-    Y  = take(-1,down(top(R))),
+    X  = take(-1,up(top(R))),
+    Y  = take(-1,down(bot(R))),
     X  = lists:reverse(Y),
     L  = length(X).
 
@@ -252,10 +265,10 @@ te() ->
     kvs_stream:add(P,
     kvs_stream:load(S)))))),
     4 = length(kvs_stream:take(-1,S1)),
-    S2 = kvs_stream:save(kvs_stream:seek(S1#cur.top,S1)),
+    S2 = kvs_stream:save(kvs_stream:top(S1)),
     S3 = kvs_stream:save(kvs_stream:remove(S2#cur.top-1,S2)),
-    List = kvs_stream:take(-1,kvs_stream:up(kvs_stream:bot(S3))),
-    Rev  = kvs_stream:take(-1,kvs_stream:down(kvs_stream:top(S3))),
+    List = kvs_stream:take(-1,kvs_stream:seek(kvs_stream:up(S3))),
+    Rev  = kvs_stream:take(-1,kvs_stream:seek(kvs_stream:down(S3))),
     List = lists:reverse(Rev),
     3 = length(List),
     {S3,List}.