kvs_stream.erl 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. -module(kvs_stream).
  2. -include("kvs.hrl").
  3. -include("user.hrl").
  4. -compile(export_all).
  5. -export([ new/1, top/1, bot/1, take/2, load/1, save/1, seek/2, next/1, prev/1, add/3 ]).
  6. % PUBLIC
  7. new(T) -> #cur{feed=kvs:next_id(cur,1),tab=T}.
  8. top(#cur{top=T}=C) -> seek(T,C).
  9. bot(#cur{bot=B}=C) -> seek(B,C).
  10. take(N,#cur{dir=D}=C) -> take(D,N,C,[]).
  11. save(C) -> kvs:put(C), C.
  12. load(#cur{feed=K}) -> kvs:get(cur,K).
  13. seek(Id, #cur{tab=T}=C) -> {ok,R}=kvs:get(T,Id), C#cur{id=el(2,R),val=R}.
  14. next(#cur{tab=T,id=Id,val=B}=C) -> lookup(kvs:get(T,en(B)),C).
  15. prev(#cur{tab=T,id=Id,val=B}=C) -> lookup(kvs:get(T,ep(B)),C).
  16. 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};
  17. 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};
  18. add(top,M,#cur{top=T, val=D}=C) when element(2,D) /=T -> add(top, M, top(C));
  19. add(bot,M,#cur{bot=B, val=D}=C) when element(2,D) /=B -> add(bot, M, bot(C));
  20. 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};
  21. 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}.
  22. sn(M,T) -> setelement(#iterator.next, M, T).
  23. sp(M,T) -> setelement(#iterator.prev, M, T).
  24. el(X,T) -> element(X,T).
  25. tn(T) -> element(1,T).
  26. id(T) -> element(2,T).
  27. en(T) -> element(#iterator.next, T).
  28. ep(T) -> element(#iterator.prev, T).
  29. dir(next) -> top;
  30. dir(prev) -> bot.
  31. down(C) -> C#cur{dir=next}.
  32. up(C) -> C#cur{dir=prev}.
  33. lookup({ok,R},C) -> C#cur{id=el(2,R),val=R};
  34. lookup(X,C) -> X.
  35. take(_,_,{error,_},R) -> lists:flatten(R);
  36. take(_,0,_,R) -> lists:flatten(R);
  37. take(A,N,#cur{val=B}=C,R) -> take(A,N-1,?MODULE:A(C),[B|R]).
  38. test() ->
  39. #cur{feed = K} = C = new(user),
  40. Feed = lists:concat(["cur",K]),
  41. A = save(add(top,#user{id=kvs:next_id(Feed,1)},
  42. add(bot,#user{id=kvs:next_id(Feed,1)},
  43. add(top,#user{id=kvs:next_id(Feed,1)},
  44. add(bot,#user{id=kvs:next_id(Feed,1)}, C ))))),
  45. X = take(-1,down(top(A))),
  46. Y = take(-1,up(bot(A))),
  47. X = lists:reverse(Y),
  48. L = length(X),
  49. {ok,{id_seq,Feed,L}} = kvs:get(id_seq,Feed),
  50. ok.