ІТЕРАТОРИ
KVS — це бібліотека абстракції на KV сховищами (з єдиним простором ключів), що складається з двох частин: базового API та API управління ітераторами: take, drop, next, prev, append. Основне API в модулі kvs, а ітераторів в kvs_stream.
Призначення KVS
— Надання інтерфейсу абстрагування широкого спектру сховищ;
— Надання зручного Ерланг REPL інтерфейсу для роботи з рекордами;
— Поділ на базовий (get put delete) та розширений інтерфейс ітераторів (next prev);
— Набір драйверів (внутрішня база, зовнішня база і файлова система);
— Шари даних: файлова система, ланцюжки повідомлень, банківські транзакції, дерева підписів, трейси бізнес-процесів, блокчейни, системи черг, часові послідовності.
Бібліотека KVS дозволяє або повинна дозволяти зберігати та витягувати будь-якого виду структури надаючи семантику управління курсорами next prev, якою володіють дерева. Тому можна сказати, що це інтерфейс оператора до ланцюжкових та деревоподібних сховищ. У своїй основі KVS підтримує три механізми зберігання ланцюжків: 1) перший спосіб, двозв'язні списки, явний, де next і prev покажчики безпосередньо присутні в даних, підходить навіть для управління деревами; 2) другий, явний, де є тільки next, цей спосіб підходить для списків, багато людей запитують про цей спосіб, але ми його не використовували ніколи та імплементації під рукою немає; 3) і третій, явний спосіб, де записи вбудовуються у існуючий індекс, тобто. btree таблиці, zero-overhead.
В якомусь сенсі перший і другий способи реалізують певний шар поверх KVS, так як kvs_stream працює з будь-якими сторожами поліморфно, а ось kvs_st драйвер ітераторів зроблено спеціально для rocksdb.
ROCKSDB
1> {ok,Ref} = rocksdb:open("hey",[{create_if_missing,true}]).
2> rocksdb:put(Ref, <<"/users/1">>,<<"maxim">>,[{sync,true}]).
3> rocksdb:put(Ref, <<"/users/2">>,<<"doxtop">>,[{sync,true}]).
4> rocksdb:put(Ref, <<"/users/3">>,<<"vlad">>,[{sync,true}]).
5> rocksdb:put(Ref, <<"/staff/1">>,<<"vlad">>,[{sync,true}]).
6> rocksdb:put(Ref, <<"/staff/2">>,<<"maxim">>,[{sync,true}]).
7> rocksdb:put(Ref, <<"/staff/3">>,<<"doxtop">>,[{sync,true}]).
8> {ok,I} = rocksdb:iterator(Ref,[]).
9> rocksdb:iterator_move(I,{seek,<<"/staff/">>}).
10> rocksdb:iterator_move(I,next).
11> rocksdb:iterator_move(I,next).
12> rocksdb:iterator_move(I,next).
13> rocksdb:iterator_move(I,{seek,<<"/users/">>}).
14> rocksdb:iterator_move(I,next).
15> rocksdb:iterator_move(I,next).
16> rocksdb:iterator_move(I,next).
1> kvs:ver().
{version,"KVS ROCKSDB"}
2> rr(kvs).
[emails,id_seq,it,iter,kvs,reader,schema,table,writer]
3> kvs:join().
ok
4> kvs:put(#emails{id=1,email="maxim"}).
5> kvs:put(#emails{id=2,email="doxtop"}).
6> kvs:put(#writer{id=2}).
7> kvs:put(#writer{id=1}).
8> kvs:all(writer).
[#writer{id = 1,count = 0,cache = [],args = [],first = []},
#writer{id = 2,count = 0,cache = [],args = [],first = []}]
9> kvs:all(emails).
[#emails{id = 1,next = [],prev = [],email = "maxim"},
#emails{id = 2,next = [],prev = [],email = "doxtop"}]
10> kvs:add(#writer{id=chain,args=#emails{email="[email protected]"}}).
11> kvs:add(#writer{id=chain,args=#emails{email="[email protected]"}}).
12> kvs:add(#writer{id=chain,args=#emails{email="[email protected]"}}).
13> kvs:all(chain).
[#emails{id = 1555244691729330000,next = [],prev = [],
email = "[email protected]"},
#emails{id = 1555244699905648000,next = [],prev = [],
email = "[email protected]"},
#emails{id = 1555244696660271000,next = [],prev = [],
email = "[email protected]"}]