kvs_stream.erl 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. -module(kvs_stream).
  2. -description('KVS STREAM LAYER').
  3. -include("kvs.hrl").
  4. -include("stream.hrl").
  5. -include("metainfo.hrl").
  6. -export(?STREAM).
  7. -export([metainfo/0]).
  8. % boot for sample
  9. metainfo() -> #schema { name = kvs, tables = tables() }.
  10. tables() -> [ #table { name = writer, fields = record_info(fields, writer) },
  11. #table { name = reader, fields = record_info(fields, reader) } ].
  12. % section: kvs_stream prelude
  13. se(X,Y,Z) -> setelement(X,Y,Z).
  14. e(X,Y) -> element(X,Y).
  15. c4(R,V) -> se(#reader.args, R, V).
  16. sn(M,T) -> se(#iter.next, M, T).
  17. sp(M,T) -> se(#iter.prev, M, T).
  18. si(M,T) -> se(#iter.id, M, T).
  19. tab(T) -> e(1, T).
  20. id(T) -> e(#iter.id, T).
  21. en(T) -> e(#iter.next, T).
  22. ep(T) -> e(#iter.prev, T).
  23. acc(0) -> next;
  24. acc(1) -> prev.
  25. % section: next, prev
  26. top(#reader{feed=F}=C) -> w(kvs:get(writer,F),top,C).
  27. bot(#reader{feed=F}=C) -> w(kvs:get(writer,F),bot,C).
  28. next(#reader{cache=[]}) -> {error,empty};
  29. next(#reader{cache={T,R},pos=P}=C) -> n(kvs:get(T,R),C,P+1).
  30. prev(#reader{cache=[]}) -> {error,empty};
  31. prev(#reader{cache={T,R},pos=P}=C) -> p(kvs:get(T,R),C,P-1).
  32. n({ok,R},C,P) -> r(kvs:get(tab(R),en(R)),C,P);
  33. n({error,X},_,_) -> {error,X}.
  34. p({ok,R},C,P) -> r(kvs:get(tab(R),ep(R)),C,P);
  35. p({error,X},_,_) -> {error,X}.
  36. r({ok,R},C,P) -> C#reader{cache={tab(R),id(R)},pos=P};
  37. r({error,X},_,_) -> {error,X}.
  38. w({ok,#writer{first=[]}},bot,C) -> C#reader{cache=[],pos=1,dir=0};
  39. w({ok,#writer{first=B}},bot,C) -> C#reader{cache={tab(B),id(B)},pos=1,dir=0};
  40. w({ok,#writer{cache=B,count=Size}},top,C) -> C#reader{cache={tab(B),id(B)},pos=Size,dir=1};
  41. w({error,X},_,_) -> {error,X}.
  42. % section: take, drop
  43. feed(Feed) -> #reader{args=Args} = take((reader(Feed))#reader{args=-1}), Args.
  44. drop(#reader{cache=[]}=C) -> C#reader{args=[]};
  45. drop(#reader{dir=D,cache=B,args=N,pos=P}=C) -> drop(acc(D),N,C,C,P,B).
  46. take(#reader{cache=[]}=C) -> C#reader{args=[]};
  47. take(#reader{dir=D,cache=B,args=N,pos=P}=C) -> take(acc(D),N,C,C,[],P).
  48. take(_,_,{error,_},C2,R,P) -> C2#reader{args=lists:flatten(R),pos=P,cache={tab(hd(R)),en(hd(R))}};
  49. take(_,0,_,C2,R,P) -> C2#reader{args=lists:flatten(R),pos=P,cache={tab(hd(R)),en(hd(R))}};
  50. take(A,N,#reader{cache={T,I},pos=P}=C,C2,R,_) -> take(A,N-1,?MODULE:A(C),C2,[element(2,kvs:get(T,I))|R],P).
  51. drop(_,_,{error,_},C2,P,B) -> C2#reader{pos=P,cache=B};
  52. drop(_,0,_,C2,P,B) -> C2#reader{pos=P,cache=B};
  53. drop(A,N,#reader{cache=B,pos=P}=C,C2,_,_) -> drop(A,N-1,?MODULE:A(C),C2,P,B).
  54. % new, save, load, up, down, top, bot
  55. load_reader (Id) -> case kvs:get(reader,Id) of {ok,C} -> C; _ -> #reader{id=[]} end.
  56. writer (Id) -> case kvs:get(writer,Id) of {ok,W} -> W; {error,_} -> #writer{id=Id} end.
  57. reader (Id) -> case kvs:get(writer,Id) of
  58. {ok,#writer{first=[]}} -> #reader{id=kvs:seq(reader,1),feed=Id,cache=[]};
  59. {ok,#writer{first=F}} -> #reader{id=kvs:seq(reader,1),feed=Id,cache={tab(F),id(F)}};
  60. {error,_} -> save(#writer{id=Id}), reader(Id) end.
  61. save (C) -> NC = c4(C,[]), kvs:put(NC), NC.
  62. % add
  63. add(#writer{args=M}=C) when element(2,M) == [] -> add(si(M,kvs:seq(tab(M),1)),C);
  64. add(#writer{args=M}=C) -> add(M,C).
  65. add(M,#writer{cache=[]}=C) ->
  66. _Id=id(M), N=sp(sn(M,[]),[]), kvs:put(N),
  67. C#writer{cache=N,count=1,first=N};
  68. %add(M,#writer{cache=V,count=S}=C) ->
  69. % N=sp(sn(M,[]),id(V)), P=sn(V,id(M)), kvs:put([N,P]),
  70. % C#writer{cache=N,count=S+1}.
  71. add(M,#writer{cache=V1,count=S}=C) ->
  72. {ok,V} = kvs:get(tab(V1),id(V1)),
  73. N=sp(sn(M,[]),id(V)), P=sn(V,id(M)), kvs:put([N,P]),
  74. C#writer{cache=N,count=S+1}.
  75. remove(Rec,Feed) ->
  76. {ok,W=#writer{count=Count}} = kvs:get(writer,Feed),
  77. NC = Count-1,
  78. kvs:save(W#writer{count=NC}),
  79. NC.
  80. append(Rec,Feed) ->
  81. kvs:ensure(#writer{id=Feed}),
  82. Name = element(1,Rec),
  83. Id = element(2,Rec),
  84. case kvs:get(Name,Id) of
  85. {ok,_} -> Id;
  86. {error,_} -> kvs:save(kvs:add((kvs:writer(Feed))#writer{args=Rec})), Id end.
  87. cut(_Feed,Id) ->
  88. case kvs:get(writer,Id) of
  89. {ok,#writer{count=N}} -> {ok,N};
  90. {error,_} -> {error,not_found} end.