hirlite 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +15 -0
  2. data/LICENSE +28 -0
  3. data/Rakefile +51 -0
  4. data/ext/hirlite_ext/extconf.rb +33 -0
  5. data/ext/hirlite_ext/hirlite_ext.c +14 -0
  6. data/ext/hirlite_ext/hirlite_ext.h +38 -0
  7. data/ext/hirlite_ext/rlite.c +351 -0
  8. data/lib/hirlite/rlite.rb +1 -0
  9. data/lib/hirlite/version.rb +3 -0
  10. data/lib/hirlite.rb +2 -0
  11. data/vendor/rlite/Makefile +6 -0
  12. data/vendor/rlite/deps/crc64.c +191 -0
  13. data/vendor/rlite/deps/crc64.h +3 -0
  14. data/vendor/rlite/deps/endianconv.h +73 -0
  15. data/vendor/rlite/deps/hyperloglog.c +1547 -0
  16. data/vendor/rlite/deps/hyperloglog.h +14 -0
  17. data/vendor/rlite/deps/lzf.h +100 -0
  18. data/vendor/rlite/deps/lzfP.h +159 -0
  19. data/vendor/rlite/deps/lzf_c.c +295 -0
  20. data/vendor/rlite/deps/lzf_d.c +150 -0
  21. data/vendor/rlite/deps/sha1.c +227 -0
  22. data/vendor/rlite/deps/sha1.h +19 -0
  23. data/vendor/rlite/deps/utilfromredis.c +397 -0
  24. data/vendor/rlite/deps/utilfromredis.h +11 -0
  25. data/vendor/rlite/src/Makefile +79 -0
  26. data/vendor/rlite/src/constants.h +15 -0
  27. data/vendor/rlite/src/dump.c +191 -0
  28. data/vendor/rlite/src/dump.h +3 -0
  29. data/vendor/rlite/src/hirlite.c +3985 -0
  30. data/vendor/rlite/src/hirlite.h +186 -0
  31. data/vendor/rlite/src/page_btree.c +1556 -0
  32. data/vendor/rlite/src/page_btree.h +133 -0
  33. data/vendor/rlite/src/page_key.c +283 -0
  34. data/vendor/rlite/src/page_key.h +25 -0
  35. data/vendor/rlite/src/page_list.c +718 -0
  36. data/vendor/rlite/src/page_list.h +70 -0
  37. data/vendor/rlite/src/page_long.c +61 -0
  38. data/vendor/rlite/src/page_long.h +14 -0
  39. data/vendor/rlite/src/page_multi_string.c +538 -0
  40. data/vendor/rlite/src/page_multi_string.h +18 -0
  41. data/vendor/rlite/src/page_skiplist.c +689 -0
  42. data/vendor/rlite/src/page_skiplist.h +70 -0
  43. data/vendor/rlite/src/page_string.c +55 -0
  44. data/vendor/rlite/src/page_string.h +12 -0
  45. data/vendor/rlite/src/pqsort.c +185 -0
  46. data/vendor/rlite/src/pqsort.h +40 -0
  47. data/vendor/rlite/src/restore.c +401 -0
  48. data/vendor/rlite/src/restore.h +3 -0
  49. data/vendor/rlite/src/rlite.c +1309 -0
  50. data/vendor/rlite/src/rlite.h +159 -0
  51. data/vendor/rlite/src/sort.c +530 -0
  52. data/vendor/rlite/src/sort.h +18 -0
  53. data/vendor/rlite/src/status.h +19 -0
  54. data/vendor/rlite/src/type_hash.c +607 -0
  55. data/vendor/rlite/src/type_hash.h +29 -0
  56. data/vendor/rlite/src/type_list.c +477 -0
  57. data/vendor/rlite/src/type_list.h +23 -0
  58. data/vendor/rlite/src/type_set.c +796 -0
  59. data/vendor/rlite/src/type_set.h +34 -0
  60. data/vendor/rlite/src/type_string.c +613 -0
  61. data/vendor/rlite/src/type_string.h +34 -0
  62. data/vendor/rlite/src/type_zset.c +1147 -0
  63. data/vendor/rlite/src/type_zset.h +50 -0
  64. data/vendor/rlite/src/util.c +334 -0
  65. data/vendor/rlite/src/util.h +71 -0
  66. metadata +151 -0
@@ -0,0 +1,477 @@
1
+ #include <stdlib.h>
2
+ #include "rlite.h"
3
+ #include "page_multi_string.h"
4
+ #include "type_list.h"
5
+ #include "page_list.h"
6
+ #include "util.h"
7
+
8
+ static int rl_llist_create(rlite *db, long list_page, rl_list **_list)
9
+ {
10
+ rl_list *list = NULL;
11
+
12
+ int retval;
13
+ RL_CALL(rl_list_create, RL_OK, db, &list, &rl_list_type_long);
14
+ RL_CALL(rl_write, RL_OK, db, &rl_data_type_list_long, list_page, list);
15
+
16
+ if (_list) {
17
+ *_list = list;
18
+ }
19
+ cleanup:
20
+ return retval;
21
+ }
22
+
23
+ static int rl_llist_read(rlite *db, long list_page_number, rl_list **list)
24
+ {
25
+ void *tmp;
26
+ int retval;
27
+ RL_CALL(rl_read, RL_FOUND, db, &rl_data_type_list_long, list_page_number, &rl_list_type_long, &tmp, 1);
28
+ *list = tmp;
29
+ retval = RL_OK;
30
+ cleanup:
31
+ return retval;
32
+ }
33
+
34
+ static int rl_llist_get_objects(rlite *db, const unsigned char *key, long keylen, long *_list_page_number, rl_list **list, int update_version, int create)
35
+ {
36
+ long list_page_number, version;
37
+ int retval;
38
+ unsigned long long expires = 0;
39
+ if (create) {
40
+ retval = rl_key_get_or_create(db, key, keylen, RL_TYPE_LIST, &list_page_number, &version);
41
+ if (retval != RL_FOUND && retval != RL_NOT_FOUND) {
42
+ goto cleanup;
43
+ }
44
+ else if (retval == RL_NOT_FOUND) {
45
+ retval = rl_llist_create(db, list_page_number, list);
46
+ goto cleanup;
47
+ }
48
+ else {
49
+ RL_CALL(rl_llist_read, RL_OK, db, list_page_number, list);
50
+ }
51
+ }
52
+ else {
53
+ unsigned char type;
54
+ retval = rl_key_get(db, key, keylen, &type, NULL, &list_page_number, &expires, &version);
55
+ if (retval != RL_FOUND) {
56
+ goto cleanup;
57
+ }
58
+ if (type != RL_TYPE_LIST) {
59
+ retval = RL_WRONG_TYPE;
60
+ goto cleanup;
61
+ }
62
+ RL_CALL(rl_llist_read, RL_OK, db, list_page_number, list);
63
+ }
64
+ if (update_version) {
65
+ RL_CALL(rl_key_set, RL_OK, db, key, keylen, RL_TYPE_LIST, list_page_number, expires, version + 1);
66
+ }
67
+ cleanup:
68
+ if (_list_page_number) {
69
+ *_list_page_number = list_page_number;
70
+ }
71
+ return retval;
72
+ }
73
+
74
+ int rl_push(struct rlite *db, const unsigned char *key, long keylen, int create, int left, int valuec, unsigned char **values, long *valueslen, long *size)
75
+ {
76
+ rl_list *list;
77
+ long list_page_number;
78
+ int retval, i;
79
+ long *value = NULL;
80
+ RL_CALL(rl_llist_get_objects, RL_OK, db, key, keylen, &list_page_number, &list, 1, create ? 1 : 0);
81
+ for (i = 0; i < valuec; i++) {
82
+ RL_MALLOC(value, sizeof(*value));
83
+ RL_CALL(rl_multi_string_set, RL_OK, db, value, values[i], valueslen[i]);
84
+ RL_CALL(rl_list_add_element, RL_OK, db, list, list_page_number, value, left ? 0 : -1);
85
+ }
86
+ if (size) {
87
+ *size = list->size;
88
+ }
89
+ retval = RL_OK;
90
+ cleanup:
91
+ return retval;
92
+ }
93
+
94
+ int rl_llen(struct rlite *db, const unsigned char *key, long keylen, long *len)
95
+ {
96
+ rl_list *list;
97
+ int retval;
98
+ RL_CALL(rl_llist_get_objects, RL_OK, db, key, keylen, NULL, &list, 0, 0);
99
+ *len = list->size;
100
+ retval = RL_OK;
101
+ cleanup:
102
+ return retval;
103
+ }
104
+
105
+ int rl_pop(struct rlite *db, const unsigned char *key, long keylen, unsigned char **value, long *valuelen, int left)
106
+ {
107
+ rl_list *list;
108
+ int retval;
109
+ void *tmp;
110
+ long page, list_page;
111
+ long position = left ? 0 : -1;
112
+ RL_CALL(rl_llist_get_objects, RL_OK, db, key, keylen, &list_page, &list, 1, 0);
113
+ RL_CALL(rl_list_get_element, RL_FOUND, db, list, (void **)&tmp, position);
114
+ page = *(long *)tmp;
115
+ retval = rl_list_remove_element(db, list, list_page, position);
116
+ if (retval == RL_DELETED) {
117
+ RL_CALL(rl_key_delete, RL_OK, db, key, keylen);
118
+ }
119
+ else if (retval != RL_OK) {
120
+ goto cleanup;
121
+ }
122
+ RL_CALL(rl_multi_string_get, RL_OK, db, page, value, valuelen);
123
+ RL_CALL(rl_multi_string_delete, RL_OK, db, page);
124
+ retval = RL_OK;
125
+ cleanup:
126
+ return retval;
127
+ }
128
+
129
+ int rl_lindex(struct rlite *db, const unsigned char *key, long keylen, long index, unsigned char **value, long *valuelen)
130
+ {
131
+ rl_list *list;
132
+ int retval;
133
+ void *tmp;
134
+ long page, list_page;
135
+ RL_CALL(rl_llist_get_objects, RL_OK, db, key, keylen, &list_page, &list, 0, 0);
136
+ RL_CALL(rl_list_get_element, RL_FOUND, db, list, (void **)&tmp, index);
137
+ page = *(long *)tmp;
138
+ RL_CALL(rl_multi_string_get, RL_OK, db, page, value, valuelen);
139
+ retval = RL_OK;
140
+ cleanup:
141
+ return retval;
142
+ }
143
+
144
+ int rl_lrange(struct rlite *db, const unsigned char *key, long keylen, long start, long stop, long *size, unsigned char ***_values, long **_valueslen)
145
+ {
146
+ rl_list *list;
147
+ rl_list_iterator *iterator;
148
+ int retval;
149
+ long len;
150
+ long i;
151
+ void *tmp = NULL;
152
+ unsigned char **values = NULL;
153
+ long *valueslen = NULL;
154
+ RL_CALL(rl_llist_get_objects, RL_OK, db, key, keylen, NULL, &list, 0, 0);
155
+ len = list->size;
156
+
157
+ if (start < 0) {
158
+ start += len;
159
+ if (start < 0) {
160
+ start = 0;
161
+ }
162
+ }
163
+
164
+ if (stop < 0) {
165
+ stop += len;
166
+ }
167
+ if (stop >= len) {
168
+ stop = len - 1;
169
+ }
170
+ if (start > stop) {
171
+ *size = 0;
172
+ retval = RL_OK;
173
+ goto cleanup;
174
+ }
175
+
176
+ *size = stop - start + 1;
177
+
178
+ RL_MALLOC(values, sizeof(unsigned char *) * (*size));
179
+ RL_MALLOC(valueslen, sizeof(unsigned char *) * (*size));
180
+ RL_CALL(rl_list_iterator_create, RL_OK, db, &iterator, list, 1);
181
+ i = 0;
182
+ while (i <= stop && (retval = rl_list_iterator_next(iterator, i >= start ? &tmp : NULL)) == RL_OK) {
183
+ if (tmp) {
184
+ RL_CALL(rl_multi_string_get, RL_OK, db, *(long *)tmp, &values[i - start], &valueslen[i - start]);
185
+ rl_free(tmp);
186
+ }
187
+ i++;
188
+ }
189
+
190
+ if (retval != RL_END) {
191
+ rl_list_iterator_destroy(db, iterator);
192
+ if (retval != RL_OK) {
193
+ goto cleanup;
194
+ }
195
+ }
196
+
197
+ *_values = values;
198
+ *_valueslen = valueslen;
199
+ retval = RL_OK;
200
+ cleanup:
201
+ if (retval != RL_OK) {
202
+ rl_free(values);
203
+ rl_free(valueslen);
204
+ }
205
+ return retval;
206
+ }
207
+
208
+ int rl_linsert(struct rlite *db, const unsigned char *key, long keylen, int after, unsigned char *pivot, long pivotlen, unsigned char *value, long valuelen, long *size)
209
+ {
210
+ rl_list *list;
211
+ rl_list_iterator *iterator;
212
+ int retval, cmp;
213
+ void *tmp;
214
+ long list_page, *value_page;
215
+ long member;
216
+ long pos = 0;
217
+ RL_CALL(rl_llist_get_objects, RL_OK, db, key, keylen, &list_page, &list, 1, 0);
218
+ RL_CALL(rl_list_iterator_create, RL_OK, db, &iterator, list, 1);
219
+ while ((retval = rl_list_iterator_next(iterator, &tmp)) == RL_OK) {
220
+ member = *(long *)tmp;
221
+ rl_free(tmp);
222
+ RL_CALL(rl_multi_string_cmp_str, RL_OK, db, member, pivot, pivotlen, &cmp);
223
+ if (cmp == 0) {
224
+ retval = RL_FOUND;
225
+ break;
226
+ }
227
+ pos++;
228
+ }
229
+
230
+ if (retval == RL_END) {
231
+ retval = RL_NOT_FOUND;
232
+ }
233
+ else {
234
+ rl_list_iterator_destroy(db, iterator);
235
+ }
236
+ if (retval == RL_FOUND) {
237
+ RL_MALLOC(value_page, sizeof(*value_page));
238
+ RL_CALL(rl_multi_string_set, RL_OK, db, value_page, value, valuelen);
239
+ RL_CALL(rl_list_add_element, RL_OK, db, list, list_page, value_page, pos + (after ? 1 : 0));
240
+ retval = RL_OK;
241
+ }
242
+ if (size) {
243
+ *size = list->size;
244
+ }
245
+ cleanup:
246
+ return retval;
247
+ }
248
+
249
+ static int search(struct rlite *db, rl_list *list, unsigned char *value, long valuelen, long start, int direction, long *page, long *position)
250
+ {
251
+ rl_list_iterator *iterator;
252
+ int retval, cmp;
253
+ long member;
254
+ long pos = direction > 0 ? 0 : list->size - 1;
255
+ void *tmp = NULL;
256
+ RL_CALL(rl_list_iterator_create, RL_OK, db, &iterator, list, direction);
257
+ while ((retval = rl_list_iterator_next(iterator, ((direction > 0 && pos >= start) || (direction < 0 && pos <= start)) ? &tmp : NULL)) == RL_OK) {
258
+ if (tmp == NULL) {
259
+ pos += direction;
260
+ continue;
261
+ }
262
+ member = *(long *)tmp;
263
+ rl_free(tmp);
264
+ RL_CALL(rl_multi_string_cmp_str, RL_OK, db, member, value, valuelen, &cmp);
265
+ if (cmp == 0) {
266
+ if (page) {
267
+ *page = member;
268
+ }
269
+ *position = pos;
270
+ retval = RL_FOUND;
271
+ break;
272
+ }
273
+ else {
274
+ pos += direction;
275
+ }
276
+ }
277
+
278
+ if (retval != RL_END) {
279
+ rl_list_iterator_destroy(db, iterator);
280
+ }
281
+ else {
282
+ retval = RL_NOT_FOUND;
283
+ }
284
+ cleanup:
285
+ return retval;
286
+ }
287
+
288
+ int rl_lrem(struct rlite *db, const unsigned char *key, long keylen, int direction, long maxcount, unsigned char *value, long valuelen, long *_count)
289
+ {
290
+ rl_list *list;
291
+ int retval;
292
+ long list_page, count = 0, pos, page = 0;
293
+
294
+ RL_CALL(rl_llist_get_objects, RL_OK, db, key, keylen, &list_page, &list, 0, 0);
295
+ pos = direction > 0 ? 0 : list->size - 1;
296
+ if (maxcount == 0) {
297
+ maxcount = list->size;
298
+ }
299
+
300
+ while (1) {
301
+ retval = search(db, list, value, valuelen, pos, direction, &page, &pos);
302
+ if (retval == RL_NOT_FOUND) {
303
+ break;
304
+ }
305
+ else if (retval == RL_FOUND) {
306
+ count++;
307
+ RL_CALL(rl_multi_string_delete, RL_OK, db, page);
308
+ retval = rl_list_remove_element(db, list, list_page, pos);
309
+ if (retval == RL_DELETED) {
310
+ RL_CALL(rl_key_delete, RL_OK, db, key, keylen);
311
+ retval = RL_DELETED;
312
+ break;
313
+ }
314
+ else if (retval != RL_OK) {
315
+ goto cleanup;
316
+ }
317
+ if (direction < 0) {
318
+ // this element was already skipped
319
+ pos += direction;
320
+ }
321
+ if (count == maxcount) {
322
+ break;
323
+ }
324
+ }
325
+ else {
326
+ goto cleanup;
327
+ }
328
+ }
329
+ *_count = count;
330
+ if (retval != RL_DELETED) {
331
+ retval = RL_OK;
332
+ }
333
+ cleanup:
334
+ return retval;
335
+ }
336
+
337
+ int rl_lset(struct rlite *db, const unsigned char *key, long keylen, long index, unsigned char *value, long valuelen)
338
+ {
339
+ rl_list *list;
340
+ int retval;
341
+ long list_page, *value_page;
342
+ void *tmp;
343
+
344
+ RL_CALL(rl_llist_get_objects, RL_OK, db, key, keylen, &list_page, &list, 1, 0);
345
+
346
+ // first add the new one and then delete the old one
347
+ // we could instead add an update to page_list
348
+ // but don't delete first since we might delete the only element
349
+
350
+ if (index < 0) {
351
+ index += list->size;
352
+ if (index < 0) {
353
+ retval = RL_INVALID_PARAMETERS;
354
+ goto cleanup;
355
+ }
356
+ }
357
+ if (index >= list->size) {
358
+ retval = RL_INVALID_PARAMETERS;
359
+ goto cleanup;
360
+ }
361
+
362
+ RL_MALLOC(value_page, sizeof(*value_page));
363
+ RL_CALL(rl_multi_string_set, RL_OK, db, value_page, value, valuelen);
364
+ RL_CALL(rl_list_add_element, RL_OK, db, list, list_page, value_page, index + 1);
365
+
366
+ RL_CALL(rl_list_get_element, RL_FOUND, db, list, (void **)&tmp, index);
367
+ RL_CALL(rl_multi_string_delete, RL_OK, db, *(long *)tmp);
368
+ RL_CALL(rl_list_remove_element, RL_OK, db, list, list_page, index);
369
+ retval = RL_OK;
370
+ cleanup:
371
+ return retval;
372
+ }
373
+
374
+ int rl_ltrim(struct rlite *db, const unsigned char *key, long keylen, long start, long stop)
375
+ {
376
+ rl_list *list;
377
+ int retval;
378
+ long i, list_page;
379
+ void *tmp;
380
+
381
+ RL_CALL(rl_llist_get_objects, RL_OK, db, key, keylen, &list_page, &list, 1, 0);
382
+ if (start < 0) {
383
+ start += list->size;
384
+ if (start < 0) {
385
+ start = 0;
386
+ }
387
+ }
388
+
389
+ if (stop < 0) {
390
+ stop += list->size;
391
+ }
392
+ if (stop >= list->size) {
393
+ stop = list->size - 1;
394
+ }
395
+
396
+ if (start > stop) {
397
+ RL_CALL(rl_key_delete_with_value, RL_OK, db, key, keylen);
398
+ retval = RL_DELETED;
399
+ goto cleanup;
400
+ }
401
+ for (i = 0; i < start; i++) {
402
+ RL_CALL(rl_list_get_element, RL_FOUND, db, list, (void **)&tmp, 0);
403
+ RL_CALL(rl_multi_string_delete, RL_OK, db, *(long *)tmp);
404
+ RL_CALL(rl_list_remove_element, RL_OK, db, list, list_page, 0);
405
+ }
406
+ while (list->size > stop - start + 1) {
407
+ RL_CALL(rl_list_get_element, RL_FOUND, db, list, (void **)&tmp, -1);
408
+ RL_CALL(rl_multi_string_delete, RL_OK, db, *(long *)tmp);
409
+ RL_CALL(rl_list_remove_element, RL_OK, db, list, list_page, -1);
410
+ }
411
+ retval = RL_OK;
412
+ cleanup:
413
+ return retval;
414
+ }
415
+
416
+ int rl_llist_pages(struct rlite *db, long page, short *pages)
417
+ {
418
+ rl_list *list;
419
+ rl_list_iterator *iterator;
420
+ int retval;
421
+ void *tmp;
422
+ long member;
423
+
424
+ RL_CALL(rl_read, RL_FOUND, db, &rl_data_type_list_long, page, &rl_list_type_long, &tmp, 1);
425
+ list = tmp;
426
+
427
+ RL_CALL(rl_list_pages, RL_OK, db, list, pages);
428
+
429
+ RL_CALL(rl_list_iterator_create, RL_OK, db, &iterator, list, 1);
430
+ while ((retval = rl_list_iterator_next(iterator, &tmp)) == RL_OK) {
431
+ member = *(long *)tmp;
432
+ pages[member] = 1;
433
+ RL_CALL(rl_multi_string_pages, RL_OK, db, member, pages);
434
+ rl_free(tmp);
435
+ }
436
+ iterator = NULL;
437
+
438
+ if (retval != RL_END) {
439
+ goto cleanup;
440
+ }
441
+ retval = RL_OK;
442
+ cleanup:
443
+ if (retval != RL_OK) {
444
+ if (iterator) {
445
+ rl_list_iterator_destroy(db, iterator);
446
+ }
447
+ }
448
+ return retval;
449
+ }
450
+
451
+ int rl_llist_delete(rlite *db, long value_page)
452
+ {
453
+ rl_list *list = NULL;
454
+ rl_list_iterator *iterator;
455
+ long member;
456
+ int retval;
457
+ void *tmp;
458
+ RL_CALL(rl_read, RL_FOUND, db, &rl_data_type_list_long, value_page, &rl_list_type_long, &tmp, 1);
459
+ list = tmp;
460
+ RL_CALL(rl_list_iterator_create, RL_OK, db, &iterator, list, 1);
461
+ while ((retval = rl_list_iterator_next(iterator, &tmp)) == RL_OK) {
462
+ member = *(long *)tmp;
463
+ rl_multi_string_delete(db, member);
464
+ rl_free(tmp);
465
+ }
466
+ iterator = NULL;
467
+
468
+ if (retval != RL_END) {
469
+ goto cleanup;
470
+ }
471
+
472
+ RL_CALL(rl_list_delete, RL_OK, db, list);
473
+ RL_CALL(rl_delete, RL_OK, db, value_page);
474
+ retval = RL_OK;
475
+ cleanup:
476
+ return retval;
477
+ }
@@ -0,0 +1,23 @@
1
+ #ifndef _RL_TYPE_LIST_H
2
+ #define _RL_TYPE_LIST_H
3
+
4
+ #include "page_list.h"
5
+
6
+ #define RL_TYPE_LIST 'L'
7
+
8
+ struct rlite;
9
+
10
+ int rl_push(struct rlite *db, const unsigned char *key, long keylen, int create, int left, int valuec, unsigned char **values, long *valueslen, long *size);
11
+ int rl_llen(struct rlite *db, const unsigned char *key, long keylen, long *len);
12
+ int rl_pop(struct rlite *db, const unsigned char *key, long keylen, unsigned char **value, long *valuelen, int left);
13
+ int rl_lindex(struct rlite *db, const unsigned char *key, long keylen, long index, unsigned char **value, long *valuelen);
14
+ int rl_linsert(struct rlite *db, const unsigned char *key, long keylen, int after, unsigned char *pivot, long pivotlen, unsigned char *value, long valuelen, long *size);
15
+ int rl_lrange(struct rlite *db, const unsigned char *key, long keylen, long start, long stop, long *size, unsigned char ***values, long **valueslen);
16
+ int rl_lrem(struct rlite *db, const unsigned char *key, long keylen, int direction, long maxcount, unsigned char *value, long valuelen, long *count);
17
+ int rl_lset(struct rlite *db, const unsigned char *key, long keylen, long index, unsigned char *value, long valuelen);
18
+ int rl_ltrim(struct rlite *db, const unsigned char *key, long keylen, long start, long stop);
19
+
20
+ int rl_llist_pages(struct rlite *db, long page, short *pages);
21
+ int rl_llist_delete(struct rlite *db, long value_page);
22
+
23
+ #endif