Namdak Tonpa 7 лет назад
Родитель
Сommit
287d82cfe7
1 измененных файлов с 43 добавлено и 19 удалено
  1. 43 19
      src/kvs_stream.erl

+ 43 - 19
src/kvs_stream.erl

@@ -4,13 +4,13 @@
 -author('Maxim Sokhatsky').
 -license('ISC').
 -include("kvs.hrl").
--export([ new/0, top/1, bot/1, take/2, load/1, save/1, down/1, up/1,
+-export([ new/0, top/1, bot/1, take/2, drop/2, load/1, save/1, down/1, up/1, cons/2, snoc/2,
           check/0, seek/1, rewind/1, next/1, prev/1, add/2, remove/2 ]).
 
 % section: kvs_stream prelude
 
 se(X,Y,Z) -> setelement(X,Y,Z).
-e(X,Y)  -> element(X,Y).
+e(X,Y) -> element(X,Y).
 cv(R,V) -> se(#cur.writer,R, V).
 cb(R,V) -> se(#cur.bot,   R, V).
 ct(R,V) -> se(#cur.top,   R, V).
@@ -21,16 +21,16 @@ sn(M,T) -> se(#iter.next, M, T).
 sp(M,T) -> se(#iter.prev, M, T).
 si(M,T) -> se(#iter.id, M, T).
 el(X,T) -> e(X, T).
-tab(T)  -> e(1, T).
-et(T)   -> e(#cur.top, T).
-eb(T)   -> e(#cur.bot, T).
-id(T)   -> e(#iter.id, T).
-en(T)   -> e(#iter.next, T).
-ep(T)   -> e(#iter.prev, T).
-dir(0)  -> top;
-dir(1)  -> bot.
-acc(0)  -> prev;
-acc(1)  -> next.
+tab(T) -> e(1, T).
+et(T) -> e(#cur.top, T).
+eb(T) -> e(#cur.bot, T).
+id(T) -> e(#iter.id, T).
+en(T) -> e(#iter.next, T).
+ep(T) -> e(#iter.prev, T).
+dir(0) -> top;
+dir(1) -> bot.
+acc(0) -> prev;
+acc(1) -> next.
 
 % section: next, prev
 
@@ -52,14 +52,19 @@ swap(0,{L,R}) -> {L,R}.
 pos({ok,R},C,{X,Y}) -> C#cur{reader=R,left=X,right=Y};
 pos({error,X},C,_)  -> {error,X}.
 
-% section: take
+% section: take, drop
 
-take(N,#cur{dir=D}=C)  -> take(acc(D),N,C,[]).
+drop(N,#cur{dir=D}=C) -> drop(acc(D),N,C).
+take(N,#cur{dir=D}=C) -> take(acc(D),N,C,[]).
 
-take(_,_,{error,_},R)     -> lists:flatten(R);
-take(_,0,_,R)             -> lists:flatten(R);
+take(_,_,{error,_},R) -> lists:flatten(R);
+take(_,0,_,R) -> lists:flatten(R);
 take(A,N,#cur{reader=B}=C,R) -> take(A,N-1,?MODULE:A(C),[B|R]).
 
+drop(_,_,{error,X}) -> {error,X};
+drop(_,0,C) -> C;
+drop(A,N,C) -> drop(A,N-1,?MODULE:A(C)).
+
 % rewind
 
 rewind(#cur{writer=[]}=C) -> {error,[]};
@@ -100,6 +105,9 @@ add(M,#cur{dir=D}=C) ->
 
 inc(#cur{left=L,right=R,dir=D}) -> swap(D,{L+1,R}).
 
+cons(M,C) -> add(top,M,C).
+snoc(M,C) -> add(bot,M,C).
+
 add(bot,M,#cur{bot=T,writer=[]}=C) ->
     Id=id(M), N=sn(sp(M,T),[]), kvs:put(N),
     C#cur{writer=N,reader=N,bot=Id,top=Id};
@@ -124,9 +132,10 @@ add(top,M,#cur{top=B,writer=V,reader=P}=C) ->
 
 % remove
 
-remove(I,#cur{writer=[]}=C)      -> {error,val};
-remove(I,#cur{writer=B,reader=X}=C) -> {ok,R}=kvs:get(tab(B),I), kvs:delete(tab(B),I),
-                                 join(I,[fix(tab(B),X)||X<-[ep(R),en(R)]],C).
+remove(I,#cur{writer=[]}=C) -> {error,val};
+remove(I,#cur{writer=B,reader=X}=C) ->
+    {ok,R}=kvs:get(tab(B),I), kvs:delete(tab(B),I),
+    join(I,[fix(tab(B),X)||X<-[ep(R),en(R)]],C).
 
 fix(M,[])     -> [];
 fix(M,X)      -> fix(kvs:get(M,X)).
@@ -173,6 +182,7 @@ check() ->
     te_remove(),
     test1(),
     test2(),
+    drop(),
     create_destroy(),
     next_prev_duality(),
     test_sides(),
@@ -266,6 +276,20 @@ test1() ->
     X  = lists:reverse(Y),
     L  = length(X).
 
+drop() ->
+    #cur{id=S}=save(new()),
+    P = {'user2',[],[],[],[],[],[],[],[]},
+    S1 = save(
+         add(P,
+         add(P,
+         add(P,
+         add(P,
+         load(S)))))),
+    S2= drop(2,S1),
+    2 = length(take(-1,S2)),
+    4 = length(take(-1,S1)),
+    ok.
+
 te_remove() ->
     #cur{id=S}=save(new()),
     P = {'user2',[],[],[],[],[],[],[],[]},