Browse Source

Merge pull request #40 from 221V/master

man/ua
Namdak Tonpa 5 years ago
parent
commit
077de24eda
15 changed files with 898 additions and 11 deletions
  1. 1 0
      index.html
  2. 134 0
      index.ua.html
  3. 2 2
      man/kvs.htm
  4. 2 2
      man/kvs_fs.htm
  5. 2 2
      man/kvs_mnesia.htm
  6. 2 2
      man/kvs_rocks.htm
  7. 1 0
      man/kvs_st.htm
  8. 4 3
      man/kvs_stream.htm
  9. 230 0
      man/ua/KVX_new_version.htm
  10. 158 0
      man/ua/kvs.htm
  11. 46 0
      man/ua/kvs_fs.htm
  12. 48 0
      man/ua/kvs_mnesia.htm
  13. 50 0
      man/ua/kvs_rocks.htm
  14. 45 0
      man/ua/kvs_st.htm
  15. 173 0
      man/ua/kvs_stream.htm

+ 1 - 0
index.html

@@ -1,3 +1,4 @@
+<!DOCTYPE html>
 <html>
 <head>
     <meta charset="utf-8" />

+ 134 - 0
index.ua.html

@@ -0,0 +1,134 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8" />
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta name="description" content="" />
+    <meta name="author" content="Maxim Sokhatsky" />
+    <title>KVS</title>
+    <link rel="stylesheet" href="https://synrc.space/synrc.css?v=2" />
+</head>
+<body>
+<nav>
+    <a href='https://n2o.dev'>DEV</a>
+    <a href='https://kvs.n2o.space' style="background:#ededed;">KVS</a>
+</nav>
+<header>
+    <a href="https://github.com/synrc/kvs"><img src="https://synrc.space/images/Synrc Neo.svg?v=1"></a>
+    <h1>KVS</h1>
+</header>
+<aside>
+    <article>
+        <section>
+            <h3>СИНОПИС</h3>
+            <div>KVS — це легкий клієнтський інтерфейс над
+                 абстракціями BTREE бази даних, який підтримує основні можливості: </div>
+            <div>
+                 <ul>
+                 <li>Поліморфні кортежі, як розширювані записи;</li>
+                 <li>Основна схема для сховища ланцюжків;</li>
+                 <li>Бекенди: MNESIA, FS, ROCKS;</li>
+                 <li>Надзвичайно компактний та перевірений код: 500 LOC.</li>
+                 </ul>
+            </div>
+            <div>Це суть і серце KVS — інтерфейс абстрактних виразів
+                 з наївною, та продуктивною реалізацією потоків.
+                 Підходить для систем повідомлень, простих блокчейнів,
+                 систем обробки, зберігання даних, та банківської галузі.
+                 KVS використовується в BPE та BANK додатках.</div>
+        </section>
+        <section>
+            <h3>МОДУЛІ</h3>
+            <div><ul>
+           <li><a href="man/ua/kvs.htm">KVS</a></font></li>
+           <li><a href="man/ua/kvs_stream.htm">STREAM</a></font></li>
+           <li><a href="man/ua/kvs_fs.htm">FS</a></font></li>
+           <li><a href="man/ua/kvs_mnesia.htm">MNESIA</a></font></li>
+           <li><a href="man/ua/kvs_rocks.htm">ROCKS</a></font></li>
+           <li><a href="man/ua/kvs_st.htm">ST</a></font></li>
+            </ul></div>
+            <br>
+            <div>
+                APR 2019 &copy; <a href="https://github.com/5HT">5HT</a> ISC<br>
+                VER 6.6 6.5 6.4
+            </div>
+        </section>
+        <section>
+        <figure>
+        <code>
+ $ mad get kvs && cd kvs
+ $ mad com pla rep
+ > kvs:join().
+        </code>
+        </figure>
+        </section>
+    </article>
+</aside>
+<main>
+    <section>
+
+<h3>ПРИКЛАД ВИКОРИСТАННЯ</h3>
+
+<figure><code>
+ > kvs:join().
+ ok
+
+ > kvs:check().
+ ok
+
+ > kvs:all(reader).
+ [{reader,1555175169121817000,0,[],[],
+          {list,1555175169120161000},
+          0},
+  {reader,1555175169121249000,0,[],[],
+          {list,1555175169120161000},
+          0}]
+
+ > rr(kvs).
+ [emails,id_seq,iter,kvs,reader,schema,table,writer]
+
+ > kvs:save(kvs:reader({list,1555175169120161000})).
+ #reader{id = 1555175244188986000,pos = 0,
+         cache = {emails,1555175169122304000},
+         args = [],
+         feed = {list,1555175169120161000},
+         dir = 0}
+
+ > kvs:take(kvs:bot((kvs:load_reader(1555175244188986000))#reader{args=-1})).
+ #reader{id = 1555175244188986000,pos = 5,
+         cache = {emails,1555175169127279000},
+         args = [#emails{id = 1555175169127279000,next = [],
+                         prev = 1555175169126314000,email = []},
+                 #emails{id = 1555175169126314000,next = 1555175169127279000,
+                         prev = 1555175169125227000,email = []},
+                 #emails{id = 1555175169125227000,next = 1555175169126314000,
+                         prev = 1555175169123405000,email = []},
+                 #emails{id = 1555175169123405000,next = 1555175169125227000,
+                         prev = 1555175169122304000,email = []},
+                 #emails{id = 1555175169122304000,next = 1555175169123405000,
+                         prev = [],email = []}],
+         feed = {list,1555175169120161000},
+         dir = 0}
+
+</code></figure>
+    </section>
+
+    <section>
+        <a name=plugin><h3>CONTRIBUTORS</h3></a>
+        <div>
+        <ul>
+           <li><a href="https://github.com/5HT">5HT</a> &mdash; Namdak Tonpa</li>
+           <li><a href="https://github.com/proger">proger</a> &mdash; Vlad Ki</li>
+           <li><a href="https://github.com/doxtop">doxtop</a> &mdash; Andrii Zadorozhnii</li>
+           <li><a href="https://github.com/cryoflamer">cryoflamer</a> &mdash; Yuri Maslovsky</li>
+           <li><a href="https://github.com/qomputer">qomputer</a> &mdash; Igor Kharin</li>
+        </ul></div>
+        <br><br>
+    </section>
+</main>
+<footer>
+    Made with <span class="heart"></span> to N2O
+</footer>
+</body>
+</html>

+ 2 - 2
man/kvs.htm

@@ -1,5 +1,5 @@
+<!DOCTYPE html>
 <html>
-
 <head>
     <meta charset="utf-8" />
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
@@ -127,7 +127,7 @@
 
 <h4>get(atom(),any()) -> {ok,any()} | {error, not_found | duplicated }.</h4>
 
-<p>Retrival of data record.</p>
+<p>Retrieval of data record.</p>
 
 <h4>delete(atom(),any()) -> ok | {error,any()}.</h4>
 

+ 2 - 2
man/kvs_fs.htm

@@ -1,5 +1,5 @@
+<!DOCTYPE html>
 <html>
-
 <head>
     <meta charset="utf-8" />
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
@@ -26,7 +26,7 @@
 <main>
    <section>
    <h3>INTRO</h3>
-   <p>FS is a <b>filesystem</b> backend imlpementation for KVS.
+   <p>FS is a <b>filesystem</b> backend implementation for KVS.
       Put the {dba,kvx_fs} property for the kvx application in your sys.config.</p>
    <br>
    </section>

+ 2 - 2
man/kvs_mnesia.htm

@@ -1,5 +1,5 @@
+<!DOCTYPE html>
 <html>
-
 <head>
     <meta charset="utf-8" />
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
@@ -28,7 +28,7 @@
    <section>
    <h3>INTRO</h3>
    <p>MNESIA is a <b>mnesia</b> backend imlpementation for KVS.
-      Put the {dba,kvx_mnesia} property for the kvx application in your  sys.config.</p>
+      Put the {dba,kvx_mnesia} property for the kvx application in your sys.config.</p>
    <br>
    </section>
     <section>

+ 2 - 2
man/kvs_rocks.htm

@@ -1,5 +1,5 @@
+<!DOCTYPE html>
 <html>
-
 <head>
     <meta charset="utf-8" />
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
@@ -27,7 +27,7 @@
    <article>
    <section>
    <h3>INTRO</h3>
-   <p>ROCKS is the <b>RocksDB</b> backend imlpementation for KVS.
+   <p>ROCKS is the <b>RocksDB</b> backend implementation for KVS.
       Put the {dba,kvs_rocks} and (optionally) {dba_st,kvs_st} properties
       for the kvs application in your sys.config.</p>
    <br>

+ 1 - 0
man/kvs_st.htm

@@ -1,3 +1,4 @@
+<!DOCTYPE html>
 <html>
 <head>
     <meta charset="utf-8" />

+ 4 - 3
man/kvs_stream.htm

@@ -1,3 +1,4 @@
+<!DOCTYPE html>
 <html>
 <head>
     <meta charset="utf-8" />
@@ -49,7 +50,7 @@
       and use it in your applications without importing <b>synrc/kvs</b> dependency,
       as this module is self-containing.
       The possible applications are: public and private feeds, FIFO queues,
-   unread messages, chat applications, blockchain, etc.<br><br>
+   unread messages, chat applications, blockchain etc.<br><br>
     </section>
     <section>
 
@@ -137,12 +138,12 @@
 <h4>next(#reader{}) -> #reader{}.</h4>
 
 <p>Moves cursor to next. Consume data down from top.
-   Reutrn error if lists is empty, otherwise next element or last.</p>
+   Return error if list is empty, otherwise next element or last.</p>
 
 <h4>prev(#reader{}) -> #reader{}.</h4>
 
 <p>Moves cursor to prev. Consume data up from bottom.
-   Reutrn error if lists is empty, otherwise next element or last.</p>
+   Return error if list is empty, otherwise next element or last.</p>
 
 <h4>drop(#reader{}) -> #reader{}.</h4>
 

+ 230 - 0
man/ua/KVX_new_version.htm

@@ -0,0 +1,230 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8" />
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta name="description" content="" />
+    <meta name="author" content="Maxim Sokhatsky" />
+    <title>Нова версія KVX</title>
+    <link rel="stylesheet" href="https://forms.n2o.space/priv/static/css/forms.css?v=1" />
+    <link rel="stylesheet" href="../../blank.css?v=2" />
+</head>
+<body>
+<nav>
+    <a href='https://n2o.dev'>DEV</a>
+    <a href='https://kvx.n2o.space'>KVS</a>
+    <a href='#' style="background:#ededed;">KVX</a>
+    
+</nav>
+<main>
+    <section>
+        <h3>Нова версія KVX 6.4</h3>
+        <p>KVX — слой абстракції, який складається з двох частин: базового API та API керування стрімами,
+           тейк, дроп, фолд, катаморфізм, як ви любите. Головний API в модулі kvx,
+           а стрімовий — в kvx_stream. Користуючись нагодою, хочу пропіарити схожі рішення
+           в області зберігання даних на erlang: <a href="https://github.com/fogfish/datum">datum</a> та серія бібліотек
+           від Дмитра Колесникова, <a href="https://github.com/emqx/replayq">replayq</a> від Фенга Лі,
+           а також небагатьох інших, хто намагався абстрактно вирішити проблему.</p>
+
+         <h3>Чому KVX?</h3>
+
+         <p>Призначення KVX:</p>
+         <p>— надання інтерфейсу абстрагування широкого спектра сховищ;<br>
+            — надання зручного Erlang REPL інтерфейсу для роботи з записами (records);<br>
+            — розділення на базовий (get put) інтерфейс, та стрім інтерфейс ітераторів (next prev);<br>
+            — набір драйверів (внутрішня база, зовнішня база і файлова система);<br>
+            — шари даних: файлова система, ланцюжки повідомлень, банківські транзакції, дерева
+              підписів, трейси бізнес-процесів, блокчейни, системи черг,
+              тайм серіес, ось це все.<br>
+        </p>
+         <p>Розпочинаючи з незначної модифікації KVX поміняла назву, тепер це "Абстрактна База Ланцюжків",
+            а не "Абстрактна База Термів", оскільки відділився окремий стрім API.</p>
+
+         <p>— <a href="https://github.com/synrc/kvx">synrc/kvx</a> — 6.4<br></p>
+
+        <p> Розповімо трохи про теоретичні основи KVX. Ця бібліотека дозволяє або повинна
+            дозволяти зберігати та діставати структури будь-якого виду, надаючи семантику управління
+            курсорами next prev, якою володіють дерева. Тому можна сказати, що це інтерфейс
+            оператора до деревоподібних сховищ та сховищ ланцюжків. У своїй основі KVX підтримує три
+            механізми зберігання ланцюжків:</p>
+         <p>1) перший, очевидний — двонаправлені списки, де вказівники next та prev
+               безпосереднім чином присутні в даних. Спосіб підходить
+               навіть для керування деревами;</p>
+         <p>2) другий, очевидний — однонаправлені списки, де наявний тільки вказівник next. Цей спосіб підходить для списків.
+               Багато людей запитують про цей спосіб, але ми його ніколи не використовували,
+               тому немає імплементації;</p>
+         <p>3) третій, неочевидний спосіб — пряме вбудовувавання записів в BTree index,
+               zero-overhead.</p>
+
+         <p>В якомусь сенсі перший та другий способи реалізують певний шар поверх KVX,
+            оскільки kvx_stream працює з будь-якими стораджами поліморфно, а ось kvx_st драйвер
+            стрімів зроблений спеціально для rocksdb.</p>
+
+        <h3>Дерева</h3>
+
+        <p>Двонаправлені списки або дерева, перша модель, яка лягає прямо з С++ класів, при вивченні програмування —
+           це зберігати в базі прямі вказівники, така система зберігання може використовуватися навіть,
+           якщо integer поміняти на pid, тоді можна буде точково відновлювати історію виклику.</p>
+
+        <figure>
+        <code>
+  -record(iter, { id    = [] :: [] | integer(),
+                  next  = [] :: [] | integer(),
+                  prev  = [] :: [] | integer() } ).
+        </code>
+        </figure>
+
+        <p>Перше поле будь-якої таблиці — це її ім'я, друге — id, третє та
+            четверте — next і prev (сигнатура бінарного розгалуження).
+           Поліморфно за цими зміщеннями ми очікуємо наявність цих полів
+           для лінковки даних в ланцюжки.
+           Базова частина разом називається #iter.</p>
+
+        <h4>kvx_stream — <b>#iter{}</b></h4>
+
+        <p> За поліморфое явне управління application level полями next prev рекорда #iter
+            відповідає модуль kvx_stream. Наприклад, файловая система не надає управління
+            своїми курсорами, тому імплементація fs вимагає наявності полів лінковки.</p>
+
+        <h3>Списки</h3>
+        <p>Однонаправлені списки, чи просто списки, це друга модель. Все таке ж, тільки без повернення назад.
+           Не підтримується пока жодною версією KVX.</p>
+        <figure>
+        <code>
+  -record(ite, { id    = [] :: [] | integer(),
+                 next  = [] :: [] | integer() } ).
+        </code>
+        </figure>
+
+        <h4>kvx_stre — <b>#ite{}</b></h4>
+
+        <p>Цей модуль не реалізовано, і запис не специфікований.</p>
+
+        <h3>Вбудовування в індекс</h3>
+
+        <p>Третя модель представляє собою прямий, більш ефективний спосіб вбудовування простору бізнес-об'єктів
+           в простір ключів розташованої нижче таблиці, і передача управління курсорами BTree таблиці
+           відразу в драйвер, а не в ручний link walking, як це було в riak.
+           Базова частина поліморфних записів складається тільки з імені таблиці
+           та id, і має назву #it. Ця модель використовується в rocksdb бекенді, який з'явився у 6.4.</p>
+
+        <figure>
+        <code>
+  -record(it, { id = [] :: [] | integer() } ).
+        </code>
+        </figure>
+
+        <p>Таким чином, ми можемо емулювати таблиці, в рамках єдиного простору ключів,
+           додаючи їх як префікси до ключа (little endian), який буде автоматично
+           відображатись в головному BTree дереві, також в цьому просторі ви можете
+           зберігати і фіди (стріми), наприклад, топіки: <b>/p2p/maxim/doxtop</b>.
+           Це вимагає спеціальної модифікації kvx_st для работи з записом #it,
+           на відміну від двонаправленого #iter, який працює з драйвером kvx_stream.</p>
+
+        <h4>kvx_st — <b>#it{}</b></h4>
+
+        <p>За керування курсорами по ітератору бази даних відповідає модуль kvx_st.</p>
+
+        <h3>На прикладі</h3>
+
+        <p>Код, який показує головну ідею, на прикладі драйвера rocksdb:</p>
+
+        <figure>
+        <code>
+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).
+        </code>
+        </figure>
+
+      <h3>KVX REPL</h3>
+        <p>Тепер, щоб зробити те ж саме на KVX, ви можете зробити просто:</p>
+
+        <figure>
+        <code>
+1> kvx:ver().
+{version,"KVX ROCKSDB"}
+2> rr(kvx).
+[emails,id_seq,it,iter,kvx,reader,schema,table,writer]
+3> kvx:join().
+ok
+4> kvx:put(#emails{id=1,email="maxim"}).
+5> kvx:put(#emails{id=2,email="doxtop"}).
+6> kvx:put(#writer{id=2}).
+7> kvx:put(#writer{id=1}).
+8> kvx:all(writer).
+[#writer{id = 1,count = 0,cache = [],args = [],first = []},
+ #writer{id = 2,count = 0,cache = [],args = [],first = []}]
+9> kvx:all(emails).
+[#emails{id = 1,next = [],prev = [],email = "maxim"},
+ #emails{id = 2,next = [],prev = [],email = "doxtop"}]
+
+10> kvx:add(#writer{id=chain,args=#emails{email="maxim@synrc.com"}}).
+11> kvx:add(#writer{id=chain,args=#emails{email="vlad@synrc.com"}}).
+12> kvx:add(#writer{id=chain,args=#emails{email="doxtop@synrc.com"}}).
+13> kvx:all(chain).
+[#emails{id = 1555244691729330000,next = [],prev = [],
+         email = "maxim@synrc.com"},
+ #emails{id = 1555244699905648000,next = [],prev = [],
+         email = "doxtop@synrc.com"},
+ #emails{id = 1555244696660271000,next = [],prev = [],
+         email = "vlad@synrc.com"}]
+        </code>
+        </figure>
+
+        <p>Єдиний тест на стріми, який проходить:</p>
+
+        <figure>
+        <code>
+> kvx:check().
+ok
+        </code>
+        </figure>
+
+      <h3>Документація</h3>
+
+       <p>Надіюсь зробити цю рубрику в release notes офіційною та регулярною,
+          на жаль, якщо не брать до уваги man сторінки для модулій драйверів,
+          то залишається лише два модулі, для яких потрібна документація — це <a href="https://kvx.n2o.space/man/kvx.htm">kvx</a> та <a href="https://kvx.n2o.space/man/kvx_stream.htm">kvx_stream</a>.
+          Я, звичайно, формально додав сторінки для всіх модулів, і в майбутньому хочеться,
+          щоб штучний інтелект генерував документацію. Також я зрозумів, що
+          ченджлог та реліз замітки у власному блозі є чудовим способом авторського анонсування!
+          Зробив історію таких сторінок в README.md.</p>
+
+      <h3>На закінчення</h3>
+
+      <p>Репозиторій (що депендить <a href="https://gitlab.com/barrel-db/erlang-rocksdb">rocksdb NIF драйвер</a>, який повільно компілюється,
+         від Бенуа Кісенау, <a href="https://github.com/Vonmo/rocker">Rust-версію Rocker</a> від Максима Молчанова вирішив відкласти,
+         надто часто раст оновлюється, неможливо зафрізити)
+         одразу включає файл конфігурації для rocksdb:</p>
+
+         <p>— <a href="https://github.com/voxoz/kv">voxoz/kv</a></p>
+
+      <p>P.S. Вбудовування в BTree можна застосовувати не лише в таких базах, як rocksdb,
+         але й для mnesia, і для будь-яких баз взагалі.</p>
+
+      <p>P.P.S. Також можна використовувати rocksdb у якості драйвера для mnesia (написаний
+         Ульфом Вігером для проекта Аетерніті), або скоріше різновид таблиці rocksdb_copies —
+         <a href="https://github.com/aeternity/mnesia_rocksdb">mnesia_rocksdb</a>.</p>
+
+    </section>
+</main>
+<footer>Namdak Tonpa <span class="heart">&nbsp;❤&nbsp;</span> 2009—2019</footer>
+
+
+</body>
+</html>

+ 158 - 0
man/ua/kvs.htm

@@ -0,0 +1,158 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8" />
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta name="description" content="" />
+    <meta name="author" content="Maxim Sokhatsky" />
+    <title>KVS</title>
+    <link rel="stylesheet" href="https://synrc.space/synrc.css" />
+</head>
+
+<body>
+
+<nav>
+    <a href='https://n2o.dev'>DEV</a>
+    <a href='https://kvx.n2o.space'>KVS</a>
+    <a href='#' style="background:#ededed;">KVS</a>
+</nav>
+
+<header>
+    <a href="../../index.html"><img src="https://n2o.space/img/Synrc Neo.svg"></a>
+    <h1>KVS</h1>
+</header>
+
+<main>
+    <section>
+
+<h3>ВСТУП</h3>
+
+   <p>Модуль KVS надає інтерфейс користувача для команд консолі.
+      Він має функції відкриття, маніпулювання даними та відновлення даних.
+      Під капотом він обробляє налаштовувані під час виконання бекенди для кожної підтримуваної бази даних.</p>
+
+        <p><blockquote><p><ul>
+            <li><b><a href="#dir">dir/0</a></b> &mdash; повертає перелік таблиць.</li>
+            <li><b><a href="#ver">ver/0</a></b> &mdash; повертає версію KVS.</li>
+            <li><b><a href="#seq">seq/2</a></b> &mdash; генерує новий ідентифікатор послідовностей таблиці.</li>
+            <li><b><a href="#count">count/1</a></b> &mdash; повертає кількість записів в таблиці.</li>
+            <li><b><a href="#put">put/1</a></b> &mdash; зберігає запис, використовуючи id як ключ.</li>
+            <li><b><a href="#get">get/2</a></b> &mdash; повертає запис по його ключу.</li>
+            <li><b><a href="#delete">delete/1</a></b> &mdash; видаляє запис з таблиці.</li>
+            <li><b><a href="#index">index/3</a></b> &mdash; виконує пошук записів по назві поля та його значенню.</li>
+        </ul></p></blockquote></p>
+
+ <p>Ви можете поміняти бекенд, використовуючи змінні оточення env в налаштуваннях додатку.
+    Це добре працює навіть під великим навантаженням.</p>
+
+    </section>
+    <section>
+
+<h3>ВСТАНОВЛЕННЯ</h3>
+
+<p>В sys.config ви вказуєте kvx бекенд та список модулів, які містять експорт
+   функції <b>metainfo/0</b>.</p>
+
+<figure><code>
+  [{kvx, [{dba,store_mnesia},
+          {schema,[kvx,kvx_stream]}]}].
+
+</code></figure>
+
+<h4>dir() -> list({'table',atom()}).</h4>
+
+<p>Повертає актуальні таблиці.</p>
+
+<h4>ver() -> {'version',string()}.</h4>
+
+<p>Повертає версію бекенда.</p>
+
+<h4>dump() -> ok.</h4>
+
+<p>Повертає інформацію про базу даних.</p>
+
+<figure><code>
+ > kvx:dump().
+                NAME                     STORAGE TYPE    MEMORY (MB)   ELEMENTS
+
+              id_seq                      disc_copies           0.00          0
+              writer                      disc_copies           0.00          0
+              emails                      disc_copies           0.00          0
+              reader                      disc_copies           0.00          0
+
+ Snapshot taken: {{2018,11,10},{5,2,38}}
+ ok
+
+</code></figure>
+
+
+    </section>
+    <section>
+
+<h3>SEQ</h3>
+
+<p>Таблиця послідовностей id_seq зберігає лічильники для записів.
+   Лічильники є глобальними та атомарними для кожної підтримуваної бази даних.
+   Послідовності використовуються для генерації унікальних імен записам в розподіленій таблиці.
+   Якщо імена в таблиці не є унікальними,
+   то функція count може повернути значення, що відрізняється від поточної послідовності.
+   </p>
+
+<figure><code>
+  -record(id_seq, { thing = atom(),
+                    id    = 0 :: integer() } ).
+
+</code></figure>
+
+<h4>seq(atom(), integer()) -> integer().</h4>
+
+<p>Збільшує на 1 та повертає id лічильника для конкретної таблиці.</p>
+
+<h4>count(atom()) -> integer().</h4>
+
+<p>Повертає кількість записів в таблиці.</p>
+
+    </section>
+    <section>
+
+<h3>BACKEND</h3>
+
+<p>Функції операцій з даними.
+   </p>
+
+<h4>put(tuple()) -> ok | {error,any()}.</h4>
+
+<p>Зберігає запис.</p>
+
+<h4>get(atom(),any()) -> {ok,any()} | {error, not_found | duplicated }.</h4>
+
+<p>Виконує пошук запису.</p>
+
+<h4>delete(atom(),any()) -> ok | {error,any()}.</h4>
+
+<p>Видаляє запис.</p>
+
+<h4>index(atom(),any(),any()) -> list(tuple()).</h4>
+
+<p>Виконує пошук запису за індексованим полем та заданим значенням.</p>
+
+    </section>
+    <section>
+
+<p>Цей модуль може бути пов'язаним з:
+<a href="kvx_fs.htm"><b>kvx_fs</b></a>,
+<a href="kvx_mnesia.htm"><b>kvx_mnesia</b></a>,
+<a href="kvx_rocks.htm"><b>kvx_rocks</b></a>,
+<a href="kvx_st.htm"><b>kvx_st</b></a>,
+<a href="kvx_stream.htm"><b>kvx_stream</b></a>.
+</p>
+    </section>
+</main>
+
+<footer>
+    2005&mdash;2019 &copy; Synrc Research Center
+</footer>
+
+</body>
+</html>

+ 46 - 0
man/ua/kvs_fs.htm

@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8" />
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta name="description" content="" />
+    <meta name="author" content="Maxim Sokhatsky" />
+    <title>FS</title>
+    <link rel="stylesheet" href="https://synrc.space/synrc.css" />
+</head>
+
+<body>
+
+<nav>
+    <a href='https://n2o.dev'>DEV</a>
+    <a href='https://kvx.n2o.space'>KVS</a>
+    <a href='#' style="background:#ededed;">FS</a>
+</nav>
+
+<header>
+    <a href="../../index.html"><img src="https://n2o.space/img/Synrc Neo.svg"></a>
+    <h1>FS</h1>
+</header>
+
+<main>
+   <section>
+   <h3>ВСТУП</h3>
+   <p>FS — це імплементація <b>filesystem</b> бекенду для KVS.
+      Помістіть властивість {dba,kvx_fs} для додатку kvx у ваш sys.config.</p>
+   <br>
+   </section>
+    <section>
+<p>Цей модуль може бути пов'язаним з:
+<a href="kvx.htm"><b>kvx</b></a>.
+</p>
+
+    </section>
+</main>
+
+<footer>
+    2005&mdash;2019 &copy; Synrc Research Center
+</footer>
+
+</body>
+</html>

+ 48 - 0
man/ua/kvs_mnesia.htm

@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8" />
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta name="description" content="" />
+    <meta name="author" content="Maxim Sokhatsky" />
+    <title>MNESIA</title>
+    <link rel="stylesheet" href="https://synrc.space/synrc.css" />
+</head>
+
+<body>
+
+<nav>
+    <a href='https://n2o.dev'>DEV</a>
+    <a href='https://kvx.n2o.space'>KVS</a>
+    <a href='#' style="background:#ededed;">MNESIA</a>
+</nav>
+
+<header>
+    <a href="../../index.html"><img src="https://n2o.space/img/Synrc Neo.svg"></a>
+    <h1>MNESIA</h1>
+</header>
+
+<main>
+   <article>
+   <section>
+   <h3>ВСТУП</h3>
+   <p>MNESIA — це реалізація бекенду <b>mnesia</b> для KVS.
+      Помістіть властивість {dba,kvx_mnesia} для додатку kvx у ваш sys.config.</p>
+   <br>
+   </section>
+    <section>
+<p>Цей модуль може бути пов'язаним з:
+<a href="kvx.htm"><b>kvx</b></a>.
+</p>
+
+    </section>
+   </article>
+</main>
+
+<footer>
+    2005&mdash;2019 &copy; Synrc Research Center
+</footer>
+
+</body>
+</html>

+ 50 - 0
man/ua/kvs_rocks.htm

@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8" />
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta name="description" content="" />
+    <meta name="author" content="Maxim Sokhatsky" />
+    <title>ROCKS</title>
+    <link rel="stylesheet" href="https://synrc.space/synrc.css" />
+</head>
+
+<body>
+
+<nav>
+    <a href='https://n2o.dev'>DEV</a>
+    <a href='https://kvs.n2o.space'>KVS</a>
+    <a href='#' style="background:#ededed;">ROCKS</a>
+</nav>
+
+<header>
+    <a href="../../index.html"><img src="https://n2o.space/img/Synrc Neo.svg"></a>
+    <h1>ROCKS</h1>
+</header>
+
+<main>
+   <article>
+   <section>
+   <h3>ВСТУП</h3>
+   <p>ROCKS — це реалізація бекенду <b>RocksDB</b> для KVS.
+      Помістіть властивості {dba,kvs_rocks} та, опціонально, {dba_st,kvs_st} для додатку kvx у ваш sys.config.</p>
+   <br>
+   </section>
+    <section>
+<p>Цей модуль може бути пов'язаним з:
+<a href="kvs_st.htm"><b>kvs_st</b></a>,
+<a href="kvs_stream.htm"><b>kvs_stream</b></a>,
+<a href="kvs.htm"><b>kvs</b></a>.
+</p>
+
+    </section>
+   </article>
+</main>
+
+<footer>
+    2005&mdash;2019 &copy; Synrc Research Center
+</footer>
+
+</body>
+</html>

+ 45 - 0
man/ua/kvs_st.htm

@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8" />
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta name="description" content="" />
+    <meta name="author" content="Maxim Sokhatsky" />
+    <title>ST</title>
+    <link rel="stylesheet" href="https://synrc.space/synrc.css" />
+</head>
+<body>
+<nav>
+    <a href='https://n2o.dev'>DEV</a>
+    <a href='https://kvs.n2o.space'>KVS</a>
+    <a href='#' style="background:#ededed;">ST</a>
+</nav>
+<header>
+    <a href="../../index.html"><img src="https://n2o.space/img/Synrc Neo.svg"></a>
+    <h1>ST</h1>
+</header>
+<main>
+    <section>
+
+<h3>ВСТУП</h3>
+
+<p>Модуль ST надає STREAM інтерфейс для бекенду ROCKS.
+   Щоб використовувати модуль ST для потокових операцій,
+   помістіть властивості {dba,kvs_rocks} та {dba_st,kvs_st} для додатку kvx у ваш sys.config.</p>
+    </section>
+    <section>
+<p>Цей модуль може бути пов'язаним з:
+<a href="kvs_stream.htm"><b>kvs_stream</b></a>,
+<a href="kvs_rocks.htm"><b>kvs_rocks</b></a>,
+<a href="kvs.htm"><b>kvs</b></a>.
+</p>
+    </section>
+</main>
+
+<footer>
+    2005&mdash;2019 &copy; Synrc Research Center
+</footer>
+
+</body>
+</html>

+ 173 - 0
man/ua/kvs_stream.htm

@@ -0,0 +1,173 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8" />
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta name="description" content="" />
+    <meta name="author" content="Maxim Sokhatsky" />
+    <title>STREAM</title>
+    <link rel="stylesheet" href="https://synrc.space/synrc.css" />
+</head>
+<body>
+<nav>
+    <a href='https://n2o.dev'>DEV</a>
+    <a href='https://kvs.n2o.space'>KVS</a>
+    <a href='#' style="background:#ededed;">STREAM</a>
+</nav>
+<header>
+    <a href="../../index.html"><img src="https://n2o.space/img/Synrc Neo.svg"></a>
+    <h1>STREAM</h1>
+</header>
+<main>
+    <section>
+
+<h3>ВСТУП</h3>
+
+<p>Модуль STREAM пропонує інтерфейс фолдів, акумуляторів за персистентного зберігання ланцюжків даних.
+   </p>
+
+        <p><blockquote><p><ul>
+            <li><b><a href="#writer">writer/1</a></b> &mdash; створює та повертає курсор запису до бази даних.</li>
+            <li><b><a href="#reader">reader/1</a></b> &mdash; створює та повертає курсор зчитування до бази даних.</li>
+            <li><b><a href="#save">save/1</a></b> &mdash; зберігає курсор до бази даних.</li>
+            <li><b><a href="#load">load_reader/1</a></b> &mdash; підзавантажує збережений курсор зчитування.</li>
+            <li><b><a href="#load">load_writer/1</a></b> &mdash; підзавантажує збережений курсор запису.</li>
+            <li><b><a href="#top">top/1</a></b> &mdash; повертає початок (вершину) ланцюжка.</li>
+            <li><b><a href="#bot">bot/1</a></b> &mdash; повертає закінчення (основу) ланцюжка.</li>
+            <li><b><a href="#next">next/1</a></b> &mdash; переміщає курсор зчитування на наступний елемент.</li>
+            <li><b><a href="#prev">prev/1</a></b> &mdash; переміщає курсор зчитування на попередній елемент.</li>
+            <li><b><a href="#take">take/1</a></b> &mdash; повертає N елементів з курсору зчитування.</li>
+            <li><b><a href="#drop">drop/1</a></b> &mdash; пропускає N елементів з курсору зчитування.</li>
+            <li><b><a href="#add">add/1</a></b> &mdash; додає елемент до списку.</li>
+            <li><b><a href="#append">append/2</a></b> &mdash; додає елемент в канал.</li>
+            <li><b><a href="#append">cut/2</a></b> &mdash; очищає канал до заданої мітки timestamp.</li>
+        </ul></p></blockquote></p>
+
+    <p>
+      Ви може взяти <a style="margin-bottom:30px;"
+       href="https://raw.githubusercontent.com/synrc/kvs/master/src/kvs_stream.erl">kvs_stream</a>
+      і використовувати у своїх додатках без імпортування залежності <b>synrc/kvs</b>,
+      оскільки даний модуль є самодостатнім.
+      Додатками можуть бути: публічні та приватні канали/стрічки новин, FIFO черги,
+   непрочитані повідомлення, чат, блокчейн etc.<br><br>
+    </section>
+    <section>
+
+<h3>WRITER</h3>
+
+<p>Курсор запису передставляє собою додавання деяких кешованих значень до списку-ланцюжка.
+   Наприклад, розмір ланцюжка, перший елемент ланцюжка, кешоване значення
+   попереднього записаного повідомлення, та поле для передачі аргументів stream функціям, таким, як add.</p>
+
+<figure><code>
+  -record(writer, { id    = [] :: term(),
+                    count =  0 :: integer(),
+                    cache = [] :: [] | tuple(),
+                    args  = [] :: term(),
+                    first = [] :: [] | tuple() } ).
+
+</code></figure>
+
+<p>Щоб додати дані до бази даних, спочатку потрібно створити курсор запису,
+   встановити запис з мета-інформацією в поле аргументів, та викликати функцію save.</p>
+
+<h4>writer(term()) -> #writer{}.</h4>
+
+<p>Створює курсор запису.</p>
+
+<h4>add(#writer{}) -> #writer{}.</h4>
+
+<p>Додає елемент до списку, на який вказує курсор запису.</p>
+
+<h4>load_writer(#writer{}) -> #writer{}.</h4>
+
+<p>Підзавантажує курсор запису.</p>
+
+<h4>save(#writer{}) -> #writer{}.</h4>
+
+<p>Переміщує курсор запису до бази даних.</p>
+
+    </section>
+    <section>
+
+<h3>READER</h3>
+
+<figure><figcaption>Курсор зчитування</figcaption><code>
+  -record(reader, { id    = [] :: integer(),
+                    pos   =  0 :: [] | integer(),
+                    cache = [] :: [] | integer(),
+                    args  = [] :: term(),
+                    feed  = [] :: term(),
+                    dir   =  0 :: 0 | 1 } ).
+
+</code></figure>
+
+<h4>reader(integer()) -> #reader{}.</h4>
+
+<p>Створює курсор зчитування.</p>
+
+<h4>load_reader(#reader{}) -> #reader{}.</h4>
+
+<p>Підзавантажує курсор зчитування з бази даних.</p>
+
+<h4>save(#reader{}) -> #reader{}.</h4>
+
+<p>Переміщує курсор зчитування до бази даних.</p>
+
+<h4>top(#reader{}) -> #reader{}.</h4>
+
+<p>Переміщає курсор в початок (вершину) списку.</p>
+
+<h4>bot(#reader{}) -> #reader{}.</h4>
+
+<p>Переміщає курсор в закінчення (основу) списку.</p>
+
+    </section>
+    <section>
+
+<h3>ITER</h3>
+
+<figure><figcaption>KVS Stream Iterator</figcaption><code>
+  -record(iter,   { id    = [] :: [] | integer(),
+                    next  = [] :: [] | integer(),
+                    prev  = [] :: [] | integer() } ).
+
+</code></figure>
+
+<h4>next(#reader{}) -> #reader{}.</h4>
+
+<p>Переміщає курсор на наступний елемент. Споживає дані з вершини.
+   Повертає помилку, якщо список є пустим, в іншому випадку — наступний чи останній елемент.</p>
+
+<h4>prev(#reader{}) -> #reader{}.</h4>
+
+<p>Переміщає курсор на попередній елемент. Споживає дані з основи.
+   Повертає помилку, якщо список є пустим, в іншому випадку — наступний чи останній елемент.</p>
+
+<h4>drop(#reader{}) -> #reader{}.</h4>
+
+<p>Пропускає N елементів, розпочинаючи з курсора.</p>
+
+<h4>take(#reader{}) -> #reader{}.</h4>
+
+<p>Пробує споживати N записів зі stream, використовуючи його поточне значення та напрям.
+   Повертає споживані дані. Зазвичай ви шукаєте певну позицію, і далі споживаєте деякі дані.</p>
+
+    </section>
+    <section>
+
+<p>Цей модуль може бути пов'язаним з:
+<a href="kvs.htm"><b>kvs</b></a>,
+<a href="kvs_st.htm"><b>kvs_st</b></a>.
+</p>
+
+    </section>
+</main>
+
+<footer>
+    2005&mdash;2019 &copy; Synrc Research Center
+</footer>
+
+</body>
+</html>