• Home
Name Date Size #Lines LOC

..--

cmake/Modules/12-May-2024-554474

installer/12-May-2024-6660

man/12-May-2024-1611

src/12-May-2024-37,73329,474

tools/win32/12-May-2024-71

BUILD.gnD12-May-20242.7 KiB116105

CMakeLists.txtD12-May-20245 KiB149130

ChangelogD12-May-202418.6 KiB533331

DOXYMAIN.mdD12-May-20246 11

Doxyfile.inD12-May-20241.1 KiB3828

LICENSED12-May-20241.1 KiB2217

OAT.xmlD12-May-20249.8 KiB16196

README.OpenSourceD12-May-2024303 1211

README.mdD12-May-20248.4 KiB344286

WINDOWS.mdD12-May-2024654 4631

bundle.jsonD12-May-2024808 3232

pvs_studio_analyze.shD12-May-2024438 2015

release.shD12-May-2024534 2215

win64-tc.cmakeD12-May-20241.2 KiB3027

README.OpenSource

1[
2  {
3    "Name": "IOWOW",
4    "License": "MIT License",
5    "License File": "LICENSE",
6    "Version Number": "v1.4.10",
7    "Owner": "kutcher.zhou@huawei.com",
8    "Upstream URL": "https://github.com/Softmotions/iowow",
9    "Description": "The skiplist based persistent key/value storage engine"
10  }
11]
12

README.md

1IOWOW - The C11 persistent key/value database engine based on [skip list](https://en.wikipedia.org/wiki/Skip_list)
2==================================================================================================================
3
4![Build Status](https://dev.softmotions.com/jenkins/buildStatus/icon?job=iowow_test)
5[![Join ejdb2 telegram](https://img.shields.io/badge/join-ejdb2%20telegram-0088cc.svg)](https://t.me/ejdb2)
6[![license](https://img.shields.io/github/license/Softmotions/ejdb.svg)](https://github.com/Softmotions/iowow/blob/master/LICENSE)
7![Maintained](https://img.shields.io/maintenance/yes/2020.svg)
8
9Website http://iowow.io
10
11# Key components
12
13* [iwkv.h](https://github.com/Softmotions/iowow/blob/master/src/kv/iwkv.h) Persistent key/value database engine
14* [iwfsmfile.h](https://github.com/Softmotions/iowow/blob/master/src/fs/iwfsmfile.h) File blocks allocation manager like `malloc()` on files
15
16# IWKV
17
18## Features
19
20* Support of multiple key-value databases within a single file
21* Online database backups
22* Native support of integer keys
23* [Write Ahead Logging (WAL) support](http://iowow.io/wal)
24* Ultra-fast traversal of database records
25* Compound keys support
26* Good performance comparing its main competitors: `lmdb`, `leveldb`, `kyoto cabinet`
27* Tiny C11 library (200Kb) can be easily embedded into any software
28
29[![Presentation](https://iowow.io/articles/iowow-presentation-cover-small.png)](https://iowow.io/articles/intro/)
30
31
32## Used by
33
34* EJDB - Embeddable JSON database engine. http://ejdb.org
35
36## Limitations
37
38* Maximum iwkv storage file size: `512 GB (0x7fffffff80)`
39* Total size of a single key+value record must be not greater than `255Mb (0xfffffff)`
40* In-memory cache for every opened database takes `~130Kb`, cache can be disposed by `iwkv_db_cache_release()`
41
42# Supported platforms
43
44## Linux
45### Ubuntu/Debian
46#### PPA repository
47
48```sh
49sudo add-apt-repository ppa:adamansky/iwowow
50sudo apt-get update
51sudo apt-get install iowow
52```
53
54#### Building debian packages
55
56```sh
57mkdir build && cd build
58cmake .. -DCMAKE_BUILD_TYPE=Release -DPACKAGE_DEB=ON
59make package
60```
61
62### RPM based Linux distributions
63```sh
64mkdir build && cd build
65cmake .. -DCMAKE_BUILD_TYPE=Release -DPACKAGE_RPM=ON
66make package
67```
68
69## FreeBSD
70
71Successfully tested on FreeBSD 10/11
72
73## OSX
74
75Successfully tested on OSX 10.12/10.13
76
77## Windows
78
79[Cross-compilation for windows](http://iowow.io/iw/win)
80
81
82## MIPS based systems (+big-endian)
83
84Successfully tested on Debian 9.4, MIPS 32, gcc 6.x compiler.
85
86# Examples
87
88[src/kv/examples](https://github.com/Softmotions/iowow/tree/master/src/kv/examples)
89
90## Store and retrieve records
91
92```c
93#include <iowow/iwkv.h>
94#include <string.h>
95#include <stdlib.h>
96
97int main() {
98  IWKV_OPTS opts = {
99    .path = "example1.db",
100    .oflags = IWKV_TRUNC // Cleanup database before open
101  };
102  IWKV iwkv;
103  IWDB mydb;
104  iwrc rc = iwkv_open(&opts, &iwkv);
105  if (rc) {
106    iwlog_ecode_error3(rc);
107    return 1;
108  }
109  // Now open mydb
110  // - Database id: 1
111  rc = iwkv_db(iwkv, 1, 0, &mydb);
112  if (rc) {
113    iwlog_ecode_error2(rc, "Failed to open mydb");
114    return 1;
115  }
116  // Work with db: put/get value
117  IWKV_val key, val;
118  key.data = "foo";
119  key.size = strlen(key.data);
120  val.data = "bar";
121  val.size = strlen(val.data);
122
123  fprintf(stdout, "put: %.*s => %.*s\n",
124          (int) key.size, (char *) key.data,
125          (int) val.size, (char *) val.data);
126
127  rc = iwkv_put(mydb, &key, &val, 0);
128  if (rc) {
129    iwlog_ecode_error3(rc);
130    return rc;
131  }
132  // Retrieve value associated with `foo` key
133  val.data = 0;
134  val.size = 0;
135  rc = iwkv_get(mydb, &key, &val);
136  if (rc) {
137    iwlog_ecode_error3(rc);
138    return rc;
139  }
140
141  fprintf(stdout, "get: %.*s => %.*s\n",
142          (int) key.size, (char *) key.data,
143          (int) val.size, (char *) val.data);
144
145  iwkv_val_dispose(&val);
146  iwkv_close(&iwkv);
147  return 0;
148}
149```
150**Compile and run:**
151
152```sh
153gcc -std=gnu11 -Wall -pedantic -c -o example1.o example1.c
154gcc -o example1 example1.o -liowow
155
156./example1
157  put: foo => bar
158  get: foo => bar
159```
160
161## Cursor iteration example
162
163```c
164///
165/// Fills database with a set of football table records
166/// then traverse records according to club name in ascending and descending orders.
167///
168
169#include "iwkv.h"
170#include <string.h>
171#include <stdlib.h>
172#include <stdint.h>
173
174static struct data_s {
175  const char *club;
176  uint8_t     points;
177} _points[] = {
178
179  { "Aston Villa",              25  },
180  { "Manchester City",          57  },
181  { "Arsenal",                  40  },
182  { "Everton",                  37  },
183  { "West Ham United",          27  },
184  { "Tottenham Hotspur",        41  },
185  { "Wolverhampton Wanderers",  43  },
186  { "Norwich City",             21  },
187  { "Leicester City",           53  },
188  { "Manchester United",        45  },
189  { "Newcastle United",         35  },
190  { "Brighton & Hove Albion",   29  },
191  { "AFC Bournemouth",          27  },
192  { "Crystal Palace",           39  },
193  { "Sheffield United",         43  },
194  { "Burnley",                  39  },
195  { "Southampton",              34  },
196  { "Watford",                  27  },
197  { "Chelsea",                  48  },
198  { "Liverpool",                82  },
199};
200
201static iwrc run(void) {
202  IWKV_OPTS opts = {
203    .path = "cursor1.db",
204    .oflags = IWKV_TRUNC // Cleanup database before open
205  };
206  IWKV iwkv;
207  IWDB db;
208  IWKV_cursor cur = 0;
209  iwrc rc = iwkv_open(&opts, &iwkv);
210  RCRET(rc);
211
212  rc = iwkv_db(iwkv, 1, 0, &db);
213  RCGO(rc, finish);
214
215  for (int i = 0; i < sizeof(_points) / sizeof(_points[0]); ++i) {
216    struct data_s *n = &_points[i];
217    IWKV_val key = { .data = (void *) n->club, .size = strlen(n->club) };
218    IWKV_val val = { .data = &n->points, .size = sizeof(n->points) };
219    RCC(rc, finish, iwkv_put(db, &key, &val, 0));
220  }
221
222  fprintf(stdout, ">>>> Traverse in descending order\n");
223  RCC(rc, finish, iwkv_cursor_open(db, &cur, IWKV_CURSOR_BEFORE_FIRST, 0));
224  while ((rc = iwkv_cursor_to(cur, IWKV_CURSOR_NEXT)) == 0) {
225    IWKV_val key, val;
226    RCC(rc, finish, iwkv_cursor_get(cur, &key, &val));
227    fprintf(stdout, "%.*s: %u\n",
228            (int) key.size, (char *) key.data,
229            *(uint8_t *) val.data);
230    iwkv_kv_dispose(&key, &val);
231  }
232  rc = 0;
233  iwkv_cursor_close(&cur);
234
235  fprintf(stdout, "\n>>>> Traverse in ascending order\n");
236  RCC(rc, finish, iwkv_cursor_open(db, &cur, IWKV_CURSOR_AFTER_LAST, 0));
237  while ((rc = iwkv_cursor_to(cur, IWKV_CURSOR_PREV)) == 0) {
238    IWKV_val key, val;
239    RCC(rc, finish, iwkv_cursor_get(cur, &key, &val));
240    fprintf(stdout, "%.*s: %u\n",
241            (int) key.size, (char *) key.data,
242            *(uint8_t *) val.data);
243    iwkv_kv_dispose(&key, &val);
244  }
245  rc = 0;
246  iwkv_cursor_close(&cur);
247
248  // Select all keys greater or equal than: Manchester United
249  {
250    fprintf(stdout, "\n>>>> Records GE: %s\n", _points[9].club);
251    IWKV_val key = { .data = (void *) _points[9].club, .size = strlen(_points[9].club) }, val;
252    RCC(rc, finish, iwkv_cursor_open(db, &cur, IWKV_CURSOR_GE, &key));
253    do {
254      RCC(rc, finish, iwkv_cursor_get(cur, &key, &val));
255      fprintf(stdout, "%.*s: %u\n",
256              (int) key.size, (char *) key.data,
257              *(uint8_t *) val.data);
258      iwkv_kv_dispose(&key, &val);
259    } while ((rc = iwkv_cursor_to(cur, IWKV_CURSOR_NEXT)) == 0);
260    rc = 0;
261  }
262  iwkv_cursor_close(&cur);
263
264finish:
265  if (cur) {
266    iwkv_cursor_close(&cur);
267  }
268  iwkv_close(&iwkv);
269  return rc;
270}
271
272int main() {
273  iwrc rc = run();
274  if (rc) {
275    iwlog_ecode_error3(rc);
276    return 1;
277  }
278  return 0;
279}
280```
281
282Output:
283```
284>>>> Traverse in descending order
285Wolverhampton Wanderers: 43
286West Ham United: 27
287Watford: 27
288Tottenham Hotspur: 41
289Southampton: 34
290Sheffield United: 43
291Norwich City: 21
292Newcastle United: 35
293Manchester United: 45
294Manchester City: 57
295Liverpool: 82
296Leicester City: 53
297Everton: 37
298Crystal Palace: 39
299Chelsea: 48
300Burnley: 39
301Brighton & Hove Albion: 29
302Aston Villa: 25
303Arsenal: 40
304AFC Bournemouth: 27
305
306>>>> Traverse in ascending order
307AFC Bournemouth: 27
308Arsenal: 40
309Aston Villa: 25
310Brighton & Hove Albion: 29
311Burnley: 39
312Chelsea: 48
313Crystal Palace: 39
314Everton: 37
315Leicester City: 53
316Liverpool: 82
317Manchester City: 57
318Manchester United: 45
319Newcastle United: 35
320Norwich City: 21
321Sheffield United: 43
322Southampton: 34
323Tottenham Hotspur: 41
324Watford: 27
325West Ham United: 27
326Wolverhampton Wanderers: 43
327
328>>>> Records GE: Manchester United
329Manchester United: 45
330Manchester City: 57
331Liverpool: 82
332Leicester City: 53
333Everton: 37
334Crystal Palace: 39
335Chelsea: 48
336Burnley: 39
337Brighton & Hove Albion: 29
338Aston Villa: 25
339Arsenal: 40
340AFC Bournemouth: 27
341```
342
343
344