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

+ 52 - 20
src/kvs_stream.erl

@@ -7,27 +7,40 @@
 % PUBLIC
 
 new(T)                -> #cur{feed=kvs:next_id(cur,1),tab=T}.
+top(#cur{top=[]}=C)   -> C#cur{val=[]};
 top(#cur{top=T}=C)    -> seek(T,C).
+bot(#cur{bot=[]}=C)   -> C#cur{val=[]};
 bot(#cur{bot=B}=C)    -> seek(B,C).
 take(N,#cur{dir=D}=C) -> take(D,N,C,[]).
 save(C)               -> kvs:put(C), C.
 load(#cur{feed=K})    -> kvs:get(cur,K).
 
-seek(Id, #cur{tab=T}=C)         -> {ok,R}=kvs:get(T,Id), C#cur{id=el(2,R),val=R}.
-next(#cur{tab=T,id=Id,val=B}=C) -> lookup(kvs:get(T,en(B)),C).
-prev(#cur{tab=T,id=Id,val=B}=C) -> lookup(kvs:get(T,ep(B)),C).
+seek(Id, #cur{tab=T}=C)    -> {ok,R}=kvs:get(T,Id),   C#cur{val=R}.
+next(#cur{tab=T,val=[]}=C) -> {error,[]};
+next(#cur{tab=T,val=B}=C)  -> lookup(kvs:get(T,en(B)),C).
+prev(#cur{tab=T,val=[]}=C) -> {error,[]};
+prev(#cur{tab=T,val=B}=C)  -> lookup(kvs:get(T,ep(B)),C).
 
-add(top,M,#cur{top=T,val=[]}=C) -> Id=el(2,M), M2=sp(sn(M,T),[]), kvs:put(M2), C#cur{val=M2,id=Id,bot=Id,top=Id};
-add(bot,M,#cur{bot=B,val=[]}=C) -> Id=el(2,M), M2=sn(sp(M,B),[]), kvs:put(M2), C#cur{val=M2,id=Id,bot=Id,top=Id};
-add(top,M,#cur{top=T, val=D}=C) when element(2,D) /=T -> add(top, M, top(C));
-add(bot,M,#cur{bot=B, val=D}=C) when element(2,D) /=B -> add(bot, M, bot(C));
-add(top,M,#cur{top=T, val=D}=C) -> Id=el(2,M), M2=sp(sn(M,T),[]), kvs:put([M2,sp(D,Id)]), C#cur{val=M2,id=Id,top=Id};
-add(bot,M,#cur{bot=B, val=D}=C) -> Id=el(2,M), M2=sn(sp(M,B),[]), kvs:put([M2,sn(D,Id)]), C#cur{val=M2,id=Id,bot=Id}.
+add(top,M,#cur{top=T,val=[]}=C) -> Id=id(M), N=sp(sn(M,T),[]), kvs:put(N), C#cur{val=N,bot=Id,top=Id};
+add(bot,M,#cur{bot=B,val=[]}=C) -> Id=id(M), N=sn(sp(M,B),[]), kvs:put(N), C#cur{val=N,bot=Id,top=Id};
+add(top,M,#cur{top=T, val=V}=C) when element(2,V) /=T -> add(top, M, top(C));
+add(bot,M,#cur{bot=B, val=V}=C) when element(2,V) /=B -> add(bot, M, bot(C));
+add(top,M,#cur{top=T, val=V}=C) -> Id=id(M), N=sp(sn(M,T),[]), kvs:put([N,sp(V,Id)]), C#cur{val=N,top=Id};
+add(bot,M,#cur{bot=B, val=V}=C) -> Id=id(M), N=sn(sp(M,B),[]), kvs:put([N,sn(V,Id)]), C#cur{val=N,bot=Id}.
+
+remove(Id, #cur{tab=M}=C) ->
+    {ok,R}=kvs:get(M,Id),
+    join(M,Id,lists:map(fun(X)->fix(kvs:get(M,X))end,[ep(R),en(R)]),C).
+
+join(T,I,[[],[]],C) ->                                          kvs:delete(T,I), C#cur{top=[],bot=[],val=[]};
+join(T,I,[[], R],C) -> N=sp(R,[]),    kvs:put(N),               kvs:delete(T,I), C#cur{top=id(N),val=N};
+join(T,I,[L, []],C) -> N=sn(L,[]),    kvs:put(N),               kvs:delete(T,I), C#cur{bot=id(N),val=N};
+join(T,I,[L,  R],C) -> N=sp(R,id(L)), kvs:put([N,sn(L,id(R))]), kvs:delete(T,I), C#cur{val=N}.
 
 sn(M,T)   -> setelement(#iterator.next, M, T).
 sp(M,T)   -> setelement(#iterator.prev, M, T).
 el(X,T)   -> element(X,T).
-tn(T)     -> element(1,T).
+tab(T)    -> element(1,T).
 id(T)     -> element(2,T).
 en(T)     -> element(#iterator.next, T).
 ep(T)     -> element(#iterator.prev, T).
@@ -36,6 +49,9 @@ dir(prev) -> bot.
 down(C)   -> C#cur{dir=next}.
 up(C)     -> C#cur{dir=prev}.
 
+fix({ok,O})      -> O;
+fix(_)           -> [].
+
 lookup({ok,R},C) -> C#cur{id=el(2,R),val=R};
 lookup(X,C)      -> X.
 
@@ -43,16 +59,32 @@ take(_,_,{error,_},R)     -> lists:flatten(R);
 take(_,0,_,R)             -> lists:flatten(R);
 take(A,N,#cur{val=B}=C,R) -> take(A,N-1,?MODULE:A(C),[B|R]).
 
+check() -> test(), test2(), ok.
+
+test2() ->
+    #cur{feed = K} = Cur = new(user),
+    Feed = lists:concat(["cur",K]),
+    Ids = [A,B,C,D] = [ kvs:next_id(user,1) || _ <- lists:seq(1,4) ],
+    R = save(add(top,#user{id=A},
+             add(bot,#user{id=B},
+             add(top,#user{id=C},
+             add(bot,#user{id=D}, Cur ))))),
+    X = remove(A,
+        remove(B,
+        remove(C,
+        remove(D,R)))),
+    [] = take(-1,down(top(X))).
+
 test() ->
-    #cur{feed = K} = C = new(user),
+    #cur{feed = K} = Cur = new(user),
+    take(-1,down(top(Cur))),
     Feed = lists:concat(["cur",K]),
-    A = save(add(top,#user{id=kvs:next_id(Feed,1)},
-             add(bot,#user{id=kvs:next_id(Feed,1)},
-             add(top,#user{id=kvs:next_id(Feed,1)},
-             add(bot,#user{id=kvs:next_id(Feed,1)}, C ))))),
-    X = take(-1,down(top(A))),
-    Y = take(-1,up(bot(A))),
+    Ids = [A,B,C,D] = [ kvs:next_id(user,1) || _ <- lists:seq(1,4) ],
+    R = save(add(top,#user{id=A},
+             add(bot,#user{id=B},
+             add(top,#user{id=C},
+             add(bot,#user{id=D}, Cur ))))),
+    X = take(-1,down(top(R))),
+    Y = take(-1,up(bot(R))),
     X = lists:reverse(Y),
-    L = length(X),
-    {ok,{id_seq,Feed,L}} = kvs:get(id_seq,Feed),
-    ok.
+    L = length(X).