|
@@ -18,9 +18,9 @@ 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{val=[]}=C) -> {error,[]};
|
|
|
-next(#cur{val=B}=C) -> lookup(kvs:get(tab(B),en(B)),C).
|
|
|
+next(#cur{val=B}=C) -> {L,R} = right(C), lookup(kvs:get(tab(B),en(B)),C,{L,R}).
|
|
|
prev(#cur{val=[]}=C) -> {error,[]};
|
|
|
-prev(#cur{val=B}=C) -> lookup(kvs:get(tab(B),ep(B)),C).
|
|
|
+prev(#cur{val=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,?MODULE:(dir(D))(C),[]).
|
|
|
seek(I, #cur{val=[]}=C) -> {error,[]};
|
|
|
seek(I, #cur{val=B}=C) -> {ok,R}=kvs:get(tab(B),I), C#cur{val=R}.
|
|
@@ -34,22 +34,30 @@ add(top,M,#cur{top=T,val=[]}=C) -> Id=id(M), N=sp(sn(M,T),[]), kvs:put(N), C
|
|
|
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 -> n2o:warning(?MODULE,"cur:~p",[V]), add(top, M, top(C));
|
|
|
add(bot,M,#cur{bot=B, val=V}=C) when element(2,V)/=B -> n2o:warning(?MODULE,"cur:~p",[V]), 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}.
|
|
|
+add(top,M,#cur{top=T, val=V}=C) -> Id=id(M), N=sp(sn(M,T),[]), kvs:put([N,sp(V,Id)]), {L,R} = inc(C), C#cur{val=N,top=Id,left=L,right=R};
|
|
|
+add(bot,M,#cur{bot=B, val=V}=C) -> Id=id(M), N=sn(sp(M,B),[]), kvs:put([N,sn(V,Id)]), {L,R} = inc(C), C#cur{val=N,bot=Id,left=L,right=R}.
|
|
|
|
|
|
-join([[],[]],C) -> C#cur{top=[],bot=[], val=[]};
|
|
|
-join([[], R],C) -> N=sp(R,[]), kvs:put(N), C#cur{top=id(N), val=N};
|
|
|
-join([L, []],C) -> N=sn(L,[]), kvs:put(N), C#cur{ bot=id(N),val=N};
|
|
|
-join([L, R],C) -> N=sp(R,id(L)), kvs:put([N,sn(L,id(R))]), C#cur{ val=N}.
|
|
|
+join([[],[]],C) -> {X,Y} = dec(C), C#cur{top=[],bot=[], val=[],left=X,right=Y};
|
|
|
+join([[], R],C) -> N=sp(R,[]), kvs:put(N), {X,Y} = dec(C), C#cur{top=id(N), val=N, left=X,right=Y};
|
|
|
+join([L, []],C) -> N=sn(L,[]), kvs:put(N), {X,Y} = dec(C), C#cur{ bot=id(N),val=N, left=X,right=Y};
|
|
|
+join([L, R],C) -> N=sp(R,id(L)), kvs:put([N,sn(L,id(R))]), {X,Y} = dec(C), C#cur{ val=N, left=X,right=Y}.
|
|
|
|
|
|
+cv(R,V) -> setelement(#cur.val, R, V).
|
|
|
+cb(R,V) -> setelement(#cur.bot, R, V).
|
|
|
+ct(R,V) -> setelement(#cur.top, R, V).
|
|
|
+cl(R,V) -> setelement(#cur.left, R, V).
|
|
|
+cr(R,V) -> setelement(#cur.right, R, V).
|
|
|
+cd(R,V) -> setelement(#cur.dir, R, V).
|
|
|
sn(M,T) -> setelement(#iter.next, M, T).
|
|
|
sp(M,T) -> setelement(#iter.prev, M, T).
|
|
|
+si(M,T) -> setelement(#iter.id, M, T).
|
|
|
+
|
|
|
el(X,T) -> element(X, T).
|
|
|
tab(T) -> element(1, T).
|
|
|
id(T) -> element(#iter.id, T).
|
|
|
-si(M,T) -> setelement(#iter.id, M, T).
|
|
|
en(T) -> element(#iter.next, T).
|
|
|
ep(T) -> element(#iter.prev, T).
|
|
|
+
|
|
|
dir(0) -> top;
|
|
|
dir(1) -> bot.
|
|
|
acc(0) -> next;
|
|
@@ -60,15 +68,45 @@ fix(M,X) -> fix(kvs:get(M,X)).
|
|
|
fix({ok,O}) -> O;
|
|
|
fix(_) -> [].
|
|
|
|
|
|
-lookup({ok,R},C) -> C#cur{val=R};
|
|
|
-lookup({error,X},C) -> {error,X}.
|
|
|
-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]).
|
|
|
+lookup({ok,R},C,{X,Y}) -> C#cur{val=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{val=B}=C,R) -> take(A,N-1,?MODULE:A(C),[B|R]).
|
|
|
+inc(#cur{left=L,right=R}) -> {L,R+1}.
|
|
|
+dec(#cur{left=0,right=0}) -> {0,0};
|
|
|
+dec(#cur{left=L,right=0}) -> {L-1,0};
|
|
|
+dec(#cur{left=0,right=R}) -> {0,R-1};
|
|
|
+dec(#cur{left=L,right=R}) -> {L,R-1}.
|
|
|
+right(#cur{left=0,right=0}) -> {0,0};
|
|
|
+right(#cur{left=L,right=0}) -> {L,0};
|
|
|
+right(#cur{left=L,right=R}) -> {L+1,R-1}.
|
|
|
+left(#cur{left=0,right=0}) -> {0,0};
|
|
|
+left(#cur{left=0,right=R}) -> {0,R};
|
|
|
+left(#cur{left=L,right=R}) -> {L-1,R+1}.
|
|
|
|
|
|
% TESTS
|
|
|
|
|
|
-check() -> test1(), test2(), create_destroy(), ok.
|
|
|
+check() ->
|
|
|
+ test1(),
|
|
|
+ test2(),
|
|
|
+ create_destroy(),
|
|
|
+ next_prev_duality(),
|
|
|
+ ok.
|
|
|
+
|
|
|
+next_prev_duality() ->
|
|
|
+ Cur = new(),
|
|
|
+ [A,B,C] = [ kvs:next_id(person,1) || _ <- lists:seq(1,3) ],
|
|
|
+ R = kvs_stream:save(
|
|
|
+ kvs_stream:add(#person{id=A},
|
|
|
+ kvs_stream:add(#person{id=B},
|
|
|
+ kvs_stream:add(#person{id=C},
|
|
|
+ Cur)))),
|
|
|
+ X = kvs_stream:load(id(Cur)),
|
|
|
+ X = kvs_stream:prev(
|
|
|
+ kvs_stream:prev(
|
|
|
+ kvs_stream:next(
|
|
|
+ kvs_stream:next(X)))).
|
|
|
|
|
|
test2() ->
|
|
|
Cur = new(),
|
|
@@ -115,5 +153,7 @@ test1() ->
|
|
|
add(bot,#person{id=D}, Cur ))))),
|
|
|
X = take(-1,down(top(R))),
|
|
|
Y = take(-1,up(bot(R))),
|
|
|
+ n2o:info(?MODULE,"X:~w",[{R,X}]),
|
|
|
+ n2o:info(?MODULE,"Y:~w",[Y]),
|
|
|
X = lists:reverse(Y),
|
|
|
L = length(X).
|