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,34 @@
1
+ #ifndef _RL_TYPE_SET_H
2
+ #define _RL_TYPE_SET_H
3
+
4
+ #include "page_btree.h"
5
+
6
+ #define RL_TYPE_SET 'S'
7
+
8
+ struct rlite;
9
+
10
+ typedef rl_btree_iterator rl_set_iterator;
11
+
12
+ int rl_set_get_objects(struct rlite *db, const unsigned char *key, long keylen, long *_set_page_number, rl_btree **btree, int update_version, int create);
13
+ int rl_set_iterator_next(rl_set_iterator *iterator, unsigned char **member, long *memberlen);
14
+ int rl_set_iterator_destroy(rl_set_iterator *iterator);
15
+
16
+ int rl_sadd(struct rlite *db, const unsigned char *key, long keylen, int memberc, unsigned char **members, long *memberslen, long *added);
17
+ int rl_sismember(struct rlite *db, const unsigned char *key, long keylen, unsigned char *data, long datalen);
18
+ int rl_scard(struct rlite *db, const unsigned char *key, long keylen, long *card);
19
+ int rl_srem(struct rlite *db, const unsigned char *key, long keylen, int membersc, unsigned char **members, long *memberslen, long *delcount);
20
+ int rl_smove(struct rlite *db, const unsigned char *source, long sourcelen, const unsigned char *destination, long destinationlen, unsigned char *member, long memberlen);
21
+ int rl_smembers(struct rlite *db, rl_set_iterator **iterator, const unsigned char *key, long keylen);
22
+ int rl_srandmembers(struct rlite *db, const unsigned char *key, long keylen, int repeat, long *memberc, unsigned char ***members, long **memberslen);
23
+ int rl_spop(struct rlite *db, const unsigned char *key, long keylen, unsigned char **member, long *memberlen);
24
+ int rl_sdiff(struct rlite *db, int keyc, unsigned char **keys, long *keyslen, long *_membersc, unsigned char ***_members, long **_memberslen);
25
+ int rl_sdiffstore(struct rlite *db, unsigned char *target, long targetlen, int keyc, unsigned char **keys, long *keyslen, long *added);
26
+ int rl_sinter(struct rlite *db, int keyc, unsigned char **keys, long *keyslen, long *_membersc, unsigned char ***_members, long **_memberslen);
27
+ int rl_sinterstore(struct rlite *db, unsigned char *target, long targetlen, int keyc, unsigned char **keys, long *keyslen, long *added);
28
+ int rl_sunion(struct rlite *db, int keyc, unsigned char **keys, long *keyslen, long *_membersc, unsigned char ***_members, long **_memberslen);
29
+ int rl_sunionstore(struct rlite *db, unsigned char *target, long targetlen, int keyc, unsigned char **keys, long *keyslen, long *added);
30
+
31
+ int rl_set_pages(struct rlite *db, long page, short *pages);
32
+ int rl_set_delete(struct rlite *db, long value_page);
33
+
34
+ #endif
@@ -0,0 +1,613 @@
1
+ #include <stdlib.h>
2
+ #include <errno.h>
3
+ #include <math.h>
4
+ #include <ctype.h>
5
+ #include "rlite.h"
6
+ #include "page_multi_string.h"
7
+ #include "type_string.h"
8
+ #include "util.h"
9
+ #include "../deps/hyperloglog.h"
10
+
11
+ static int rl_string_get_objects(rlite *db, const unsigned char *key, long keylen, long *_page_number, unsigned long long *expires, long *version)
12
+ {
13
+ long page_number;
14
+ int retval;
15
+ unsigned char type;
16
+ retval = rl_key_get(db, key, keylen, &type, NULL, &page_number, expires, version);
17
+ if (retval != RL_FOUND) {
18
+ goto cleanup;
19
+ }
20
+ if (type != RL_TYPE_STRING) {
21
+ retval = RL_WRONG_TYPE;
22
+ goto cleanup;
23
+ }
24
+ if (_page_number) {
25
+ *_page_number = page_number;
26
+ }
27
+ retval = RL_OK;
28
+ cleanup:
29
+ return retval;
30
+ }
31
+
32
+ int rl_set(struct rlite *db, const unsigned char *key, long keylen, unsigned char *value, long valuelen, int nx, unsigned long long expires)
33
+ {
34
+ int retval;
35
+ long page_number;
36
+ unsigned char type;
37
+ long value_page, version;
38
+ retval = rl_key_get(db, key, keylen, &type, NULL, &value_page, NULL, &version);
39
+ if (retval == RL_FOUND) {
40
+ if (nx) {
41
+ goto cleanup;
42
+ }
43
+ else {
44
+ RL_CALL(rl_key_delete_with_value, RL_OK, db, key, keylen);
45
+ }
46
+ } else {
47
+ version = rand();
48
+ }
49
+ RL_CALL(rl_multi_string_set, RL_OK, db, &page_number, value, valuelen);
50
+ RL_CALL(rl_key_set, RL_OK, db, key, keylen, RL_TYPE_STRING, page_number, expires, version + 1);
51
+ retval = RL_OK;
52
+ cleanup:
53
+ return retval;
54
+ }
55
+
56
+ int rl_get(struct rlite *db, const unsigned char *key, long keylen, unsigned char **value, long *valuelen)
57
+ {
58
+ long page_number;
59
+ int retval;
60
+ RL_CALL(rl_string_get_objects, RL_OK, db, key, keylen, &page_number, NULL, NULL);
61
+ if (valuelen) {
62
+ RL_CALL(rl_multi_string_get, RL_OK, db, page_number, value, valuelen);
63
+ }
64
+ retval = RL_OK;
65
+ cleanup:
66
+ return retval;
67
+ }
68
+
69
+ int rl_append(struct rlite *db, const unsigned char *key, long keylen, unsigned char *value, long valuelen, long *newlength)
70
+ {
71
+ int retval;
72
+ long page_number;
73
+ long version;
74
+ RL_CALL2(rl_string_get_objects, RL_OK, RL_NOT_FOUND, db, key, keylen, &page_number, NULL, &version);
75
+ if (retval == RL_NOT_FOUND) {
76
+ RL_CALL(rl_multi_string_set, RL_OK, db, &page_number, value, valuelen);
77
+ version = rand();
78
+ RL_CALL(rl_key_set, RL_OK, db, key, keylen, RL_TYPE_STRING, page_number, 0, version);
79
+ if (newlength) {
80
+ *newlength = valuelen;
81
+ }
82
+ }
83
+ else {
84
+ RL_CALL(rl_key_set, RL_OK, db, key, keylen, RL_TYPE_STRING, page_number, 0, version + 1);
85
+ RL_CALL(rl_multi_string_append, RL_OK, db, page_number, value, valuelen, newlength);
86
+ }
87
+ retval = RL_OK;
88
+ cleanup:
89
+ return retval;
90
+ }
91
+
92
+ int rl_getrange(struct rlite *db, const unsigned char *key, long keylen, long start, long stop, unsigned char **value, long *valuelen)
93
+ {
94
+ long page_number;
95
+ int retval;
96
+ RL_CALL(rl_string_get_objects, RL_OK, db, key, keylen, &page_number, NULL, NULL);
97
+ RL_CALL(rl_multi_string_getrange, RL_OK, db, page_number, value, valuelen, start, stop);
98
+ retval = RL_OK;
99
+ cleanup:
100
+ return retval;
101
+ }
102
+
103
+ int rl_setrange(struct rlite *db, const unsigned char *key, long keylen, long index, unsigned char *value, long valuelen, long *newlength)
104
+ {
105
+ long page_number;
106
+ long version;
107
+ unsigned long long expires;
108
+ int retval;
109
+ if (valuelen + index > 512*1024*1024) {
110
+ retval = RL_INVALID_PARAMETERS;
111
+ goto cleanup;
112
+ }
113
+ RL_CALL2(rl_string_get_objects, RL_OK, RL_NOT_FOUND, db, key, keylen, &page_number, &expires, &version);
114
+ if (retval == RL_NOT_FOUND) {
115
+ unsigned char *padding;
116
+ RL_MALLOC(padding, sizeof(unsigned char) * index);
117
+ memset(padding, 0, index);
118
+ RL_CALL(rl_set, RL_OK, db, key, keylen, padding, index, 0, 0);
119
+ rl_free(padding);
120
+ RL_CALL(rl_append, RL_OK, db, key, keylen, value, valuelen, newlength);
121
+ }
122
+ else if (retval == RL_OK) {
123
+ RL_CALL(rl_key_set, RL_OK, db, key, keylen, RL_TYPE_STRING, page_number, expires, version + 1);
124
+ RL_CALL(rl_multi_string_setrange, RL_OK, db, page_number, value, valuelen, index, newlength);
125
+ }
126
+ retval = RL_OK;
127
+ cleanup:
128
+ return retval;
129
+ }
130
+
131
+ int rl_incr(struct rlite *db, const unsigned char *key, long keylen, long long increment, long long *newvalue)
132
+ {
133
+ long page_number;
134
+ int retval;
135
+ unsigned char *value = NULL;
136
+ char *end;
137
+ long valuelen;
138
+ long long lvalue;
139
+ unsigned long long expires;
140
+ RL_CALL2(rl_string_get_objects, RL_OK, RL_NOT_FOUND, db, key, keylen, &page_number, &expires, NULL);
141
+ if (retval == RL_NOT_FOUND) {
142
+ RL_MALLOC(value, sizeof(unsigned char) * MAX_LLONG_DIGITS);
143
+ valuelen = snprintf((char *)value, MAX_LLONG_DIGITS, "%lld", increment);
144
+ if (newvalue) {
145
+ *newvalue = increment;
146
+ }
147
+ retval = rl_set(db, key, keylen, value, valuelen, 1, 0);
148
+ goto cleanup;
149
+ }
150
+ RL_CALL(rl_multi_string_getrange, RL_OK, db, page_number, &value, &valuelen, 0, MAX_LLONG_DIGITS + 1);
151
+ if (valuelen == MAX_LLONG_DIGITS + 1) {
152
+ retval = RL_NAN;
153
+ goto cleanup;
154
+ }
155
+ lvalue = strtoll((char *)value, &end, 10);
156
+ if (isspace(((char *)value)[0]) || end[0] != '\0' || errno == ERANGE) {
157
+ retval = RL_NAN;
158
+ goto cleanup;
159
+ }
160
+ rl_free(value);
161
+ value = NULL;
162
+ if ((increment < 0 && lvalue < 0 && increment < (LLONG_MIN - lvalue)) ||
163
+ (increment > 0 && lvalue > 0 && increment > (LLONG_MAX - lvalue))) {
164
+ retval = RL_OVERFLOW;
165
+ goto cleanup;
166
+ }
167
+ lvalue += increment;
168
+ if (newvalue) {
169
+ *newvalue = lvalue;
170
+ }
171
+ RL_MALLOC(value, sizeof(unsigned char) * MAX_LLONG_DIGITS);
172
+ valuelen = snprintf((char *)value, MAX_LLONG_DIGITS, "%lld", lvalue);
173
+ RL_CALL(rl_set, RL_OK, db, key, keylen, value, valuelen, 0, expires);
174
+ retval = RL_OK;
175
+ cleanup:
176
+ rl_free(value);
177
+ return retval;
178
+ }
179
+
180
+ int rl_incrbyfloat(struct rlite *db, const unsigned char *key, long keylen, double increment, double *newvalue)
181
+ {
182
+ long page_number;
183
+ int retval;
184
+ unsigned char *value = NULL;
185
+ char *end;
186
+ long valuelen;
187
+ double dvalue;
188
+ unsigned long long expires;
189
+ RL_CALL2(rl_string_get_objects, RL_OK, RL_NOT_FOUND, db, key, keylen, &page_number, &expires, NULL);
190
+ if (retval == RL_NOT_FOUND) {
191
+ RL_MALLOC(value, sizeof(unsigned char) * MAX_DOUBLE_DIGITS);
192
+ valuelen = snprintf((char *)value, MAX_DOUBLE_DIGITS, "%lf", increment);
193
+ if (newvalue) {
194
+ *newvalue = increment;
195
+ }
196
+ retval = rl_set(db, key, keylen, value, valuelen, 1, 0);
197
+ goto cleanup;
198
+ }
199
+ RL_CALL(rl_multi_string_getrange, RL_OK, db, page_number, &value, &valuelen, 0, MAX_DOUBLE_DIGITS + 1);
200
+ if (valuelen == MAX_DOUBLE_DIGITS + 1) {
201
+ retval = RL_NAN;
202
+ goto cleanup;
203
+ }
204
+ dvalue = strtold((char *)value, &end);
205
+ if (isspace(((char *)value)[0]) || end[0] != '\0' || errno == ERANGE || isnan(dvalue)) {
206
+ retval = RL_NAN;
207
+ goto cleanup;
208
+ }
209
+ rl_free(value);
210
+ value = NULL;
211
+ dvalue += increment;
212
+ if (isinf(dvalue) || isnan(dvalue)) {
213
+ retval = RL_OVERFLOW;
214
+ goto cleanup;
215
+ }
216
+ if (newvalue) {
217
+ *newvalue = dvalue;
218
+ }
219
+ RL_MALLOC(value, sizeof(unsigned char) * MAX_DOUBLE_DIGITS);
220
+ valuelen = snprintf((char *)value, MAX_DOUBLE_DIGITS, "%lf", dvalue);
221
+ RL_CALL(rl_set, RL_OK, db, key, keylen, value, valuelen, 0, expires);
222
+ retval = RL_OK;
223
+ cleanup:
224
+ rl_free(value);
225
+ return retval;
226
+ }
227
+
228
+ int rl_getbit(struct rlite *db, const unsigned char *key, long keylen, long bitoffset, int *value)
229
+ {
230
+ int retval;
231
+ unsigned char *rangevalue = NULL;
232
+ long rangevaluelen, start;
233
+ start = bitoffset >> 3;
234
+ long bit = 7 - (bitoffset & 0x7);
235
+ RL_CALL2(rl_getrange, RL_OK, RL_NOT_FOUND, db, key, keylen, start, start, &rangevalue, &rangevaluelen);
236
+ if (retval == RL_NOT_FOUND || rangevaluelen == 0) {
237
+ *value = 0;
238
+ retval = RL_OK;
239
+ goto cleanup;
240
+ }
241
+ *value = (rangevalue[0] & (1 << bit)) ? 1 : 0;
242
+ retval = RL_OK;
243
+ cleanup:
244
+ rl_free(rangevalue);
245
+ return retval;
246
+ }
247
+
248
+ int rl_setbit(struct rlite *db, const unsigned char *key, long keylen, long bitoffset, int on, int *previousvalue)
249
+ {
250
+ int retval;
251
+ unsigned char *rangevalue = NULL;
252
+ long rangevaluelen, start;
253
+ char val;
254
+ start = bitoffset >> 3;
255
+ long bit = 7 - (bitoffset & 0x7);
256
+
257
+ /* Limit offset to 512MB in bytes */
258
+ if ((bitoffset < 0) || ((unsigned long long)bitoffset >> 3) >= (512*1024*1024))
259
+ {
260
+ retval = RL_INVALID_PARAMETERS;
261
+ goto cleanup;
262
+ }
263
+
264
+ RL_CALL2(rl_getrange, RL_OK, RL_NOT_FOUND, db, key, keylen, start, start, &rangevalue, &rangevaluelen);
265
+ if (retval == RL_NOT_FOUND || rangevaluelen == 0) {
266
+ val = 0;
267
+ val &= ~(1 << bit);
268
+ val |= ((on & 0x1) << bit);
269
+ retval = rl_setrange(db, key, keylen, start, (unsigned char *)&val, 1, NULL);
270
+ if (previousvalue) {
271
+ *previousvalue = 0;
272
+ }
273
+ goto cleanup;
274
+ }
275
+
276
+ int bitval = rangevalue[0] & (1 << bit);
277
+ if (previousvalue) {
278
+ *previousvalue = bitval ? 1 : 0;
279
+ }
280
+
281
+ rangevalue[0] &= ~(1 << bit);
282
+ rangevalue[0] |= ((on & 0x1) << bit);
283
+ retval = rl_setrange(db, key, keylen, start, rangevalue, 1, NULL);
284
+ cleanup:
285
+ rl_free(rangevalue);
286
+ return retval;
287
+ }
288
+
289
+ int rl_bitop(struct rlite *db, int op, const unsigned char *dest, long destlen, unsigned long keyc, const unsigned char **keys, long *keyslen)
290
+ {
291
+ long ltmp;
292
+ int retval;
293
+ unsigned char **values = NULL, *result;
294
+ unsigned long *valueslen = NULL, i;
295
+ long resultlen;
296
+ RL_MALLOC(valueslen, sizeof(unsigned long) * keyc);
297
+ RL_MALLOC(values, sizeof(unsigned char *) * keyc);
298
+ values[0] = NULL;
299
+ for (i = 0; i < keyc; i++) {
300
+ RL_CALL2(rl_get, RL_OK, RL_NOT_FOUND, db, keys[i], keyslen[i], &values[i], &ltmp);
301
+ if (retval == RL_NOT_FOUND) {
302
+ values[i] = NULL;
303
+ valueslen[i] = 0;
304
+ }
305
+ else if (retval == RL_OK) {
306
+ valueslen[i] = ltmp;
307
+ } else {
308
+ goto cleanup;
309
+ }
310
+ }
311
+ rl_internal_bitop(op, keyc, values, valueslen, &result, &resultlen);
312
+ RL_CALL(rl_set, RL_OK, db, dest, destlen, result, resultlen, 0, 0);
313
+ free(result);
314
+ retval = RL_OK;
315
+ cleanup:
316
+ if (values) {
317
+ if (i > 0) {
318
+ for (i--; i > 0; i--) {
319
+ rl_free(values[i]);
320
+ }
321
+ }
322
+ rl_free(values[0]);
323
+ }
324
+ rl_free(values);
325
+ rl_free(valueslen);
326
+ return retval;
327
+ }
328
+
329
+ int rl_bitcount(struct rlite *db, const unsigned char *key, long keylen, long start, long stop, long *bitcount)
330
+ {
331
+ int retval;
332
+ unsigned char *value;
333
+ long valuelen;
334
+ RL_CALL(rl_getrange, RL_OK, db, key, keylen, start, stop, &value, &valuelen);
335
+ *bitcount = (long)rl_redisPopcount(value, valuelen);
336
+ rl_free(value);
337
+ cleanup:
338
+ return retval;
339
+ }
340
+
341
+ int rl_bitpos(struct rlite *db, const unsigned char *key, long keylen, int bit, long start, long stop, int end_given, long *position)
342
+ {
343
+ int retval;
344
+ unsigned char *value = NULL;
345
+ long valuelen, totalsize;
346
+
347
+ if (bit != 0 && bit != 1) {
348
+ retval = RL_INVALID_PARAMETERS;
349
+ goto cleanup;
350
+ }
351
+
352
+ RL_CALL(rl_getrange, RL_OK, db, key, keylen, start, stop, &value, &valuelen);
353
+
354
+ if (valuelen == 0) {
355
+ *position = -1;
356
+ retval = RL_OK;
357
+ goto cleanup;
358
+ }
359
+
360
+ RL_CALL(rl_get, RL_OK, db, key, keylen, NULL, &totalsize);
361
+ RL_CALL(rl_normalize_string_range, RL_OK, totalsize, &start, &stop);
362
+
363
+ long bytes = stop - start + 1;
364
+ // stop may be after the end of the string and in that case it is treated
365
+ // as if it had 0 padding
366
+ //
367
+ // however, it can also be negative! the following check will handle
368
+ // the negative case (which cannot exceed the string size)
369
+ if (bytes < valuelen) {
370
+ bytes = valuelen;
371
+ }
372
+ long pos = rl_internal_bitpos(value, bytes, bit);
373
+
374
+ /* If we are looking for clear bits, and the user specified an exact
375
+ * range with start-end, we can't consider the right of the range as
376
+ * zero padded (as we do when no explicit end is given).
377
+ *
378
+ * So if rl_internal_bitpos() returns the first bit outside the range,
379
+ * we return -1 to the caller, to mean, in the specified range there
380
+ * is not a single "0" bit. */
381
+ if (end_given && bit == 0 && pos == bytes * 8) {
382
+ *position = -1;
383
+ retval = RL_OK;
384
+ goto cleanup;
385
+ }
386
+
387
+ if (pos != -1) {
388
+ pos += start * 8; /* Adjust for the bytes we skipped. */
389
+ }
390
+
391
+ *position = pos;
392
+ retval = RL_OK;
393
+ cleanup:
394
+ rl_free(value);
395
+ return retval;
396
+ }
397
+
398
+ int rl_pfadd(struct rlite *db, const unsigned char *key, long keylen, int elementc, unsigned char **elements, long *elementslen, int *updated)
399
+ {
400
+ int retval;
401
+ unsigned char *value = NULL;
402
+ long valuelen = 0;
403
+ unsigned long long expires = 0;
404
+
405
+ RL_CALL2(rl_get, RL_OK, RL_NOT_FOUND, db, key, keylen, &value, &valuelen);
406
+ if (retval == RL_OK) {
407
+ RL_CALL(rl_key_get, RL_FOUND, db, key, keylen, NULL, NULL, NULL, &expires, NULL);
408
+ }
409
+ retval = rl_str_pfadd(value, valuelen, elementc, elements, elementslen, &value, &valuelen);
410
+ if (retval != 0 && retval != 1) {
411
+ if (retval == -1) {
412
+ retval = RL_INVALID_STATE;
413
+ } else {
414
+ retval = RL_UNEXPECTED;
415
+ }
416
+ goto cleanup;
417
+ }
418
+ if (updated) {
419
+ *updated = retval;
420
+ }
421
+ if (retval == 1) { // updated?
422
+ RL_CALL(rl_set, RL_OK, db, key, keylen, value, valuelen, 0, expires)
423
+ }
424
+ retval = RL_OK;
425
+ cleanup:
426
+ free(value);
427
+ return retval;
428
+ }
429
+
430
+ int rl_pfcount(struct rlite *db, int keyc, const unsigned char **keys, long *keyslen, long *count)
431
+ {
432
+ int retval;
433
+ unsigned char **argv = NULL;
434
+ long *argvlen = NULL;
435
+ long i;
436
+ unsigned char *newvalue = NULL;
437
+ long newvaluelen;
438
+ unsigned long long expires = 0;
439
+
440
+ RL_MALLOC(argvlen, sizeof(unsigned char *) * keyc);
441
+ RL_MALLOC(argv, sizeof(unsigned char *) * keyc);
442
+ for (i = 0; i < keyc; i++) {
443
+ argv[i] = NULL;
444
+ }
445
+ for (i = 0; i < keyc; i++) {
446
+ RL_CALL2(rl_get, RL_OK, RL_NOT_FOUND, db, keys[i], keyslen[i], &argv[i], &argvlen[i]);
447
+ }
448
+
449
+ retval = rl_str_pfcount(keyc, argv, argvlen, count, &newvalue, &newvaluelen);
450
+ if (retval != 0) {
451
+ if (retval == -1) {
452
+ retval = RL_INVALID_STATE;
453
+ } else {
454
+ retval = RL_UNEXPECTED;
455
+ }
456
+ goto cleanup;
457
+ }
458
+ if (newvalue) {
459
+ RL_CALL2(rl_key_get, RL_FOUND, RL_NOT_FOUND, db, keys[0], keyslen[0], NULL, NULL, NULL, &expires, NULL);
460
+ RL_CALL(rl_set, RL_OK, db, keys[0], keyslen[0], newvalue, newvaluelen, 0, expires);
461
+ }
462
+ retval = RL_OK;
463
+ cleanup:
464
+ for (i = 0; i < keyc; i++) {
465
+ rl_free(argv[i]);
466
+ }
467
+ rl_free(argv);
468
+ rl_free(argvlen);
469
+ return retval;
470
+ }
471
+
472
+ int rl_pfmerge(struct rlite *db, const unsigned char *destkey, long destkeylen, int keyc, const unsigned char **keys, long *keyslen)
473
+ {
474
+ int retval;
475
+ unsigned char **argv = NULL, *newvalue = NULL;
476
+ long *argvlen = NULL, newvaluelen;
477
+ long i;
478
+ int argc = keyc + 1;
479
+ unsigned long long expires = 0;
480
+
481
+ RL_MALLOC(argvlen, sizeof(unsigned char *) * argc);
482
+ RL_MALLOC(argv, sizeof(unsigned char *) * argc);
483
+ for (i = 0; i < argc; i++) {
484
+ argv[i] = NULL;
485
+ }
486
+ for (i = 0; i < keyc; i++) {
487
+ RL_CALL2(rl_get, RL_OK, RL_NOT_FOUND, db, keys[i], keyslen[i], &argv[i], &argvlen[i]);
488
+ }
489
+ RL_CALL2(rl_get, RL_OK, RL_NOT_FOUND, db, destkey, destkeylen, &argv[keyc], &argvlen[keyc]);
490
+ retval = rl_str_pfmerge(argc, argv, argvlen, &newvalue, &newvaluelen);
491
+ if (retval != 0) {
492
+ if (retval == -1) {
493
+ retval = RL_INVALID_STATE;
494
+ } else {
495
+ retval = RL_UNEXPECTED;
496
+ }
497
+ goto cleanup;
498
+ }
499
+
500
+ RL_CALL2(rl_key_get, RL_FOUND, RL_NOT_FOUND, db, destkey, destkeylen, NULL, NULL, NULL, &expires, NULL);
501
+ RL_CALL(rl_set, RL_OK, db, destkey, destkeylen, newvalue, newvaluelen, 0, expires);
502
+ retval = RL_OK;
503
+ cleanup:
504
+ for (i = 0; i < argc; i++) {
505
+ rl_free(argv[i]);
506
+ }
507
+ rl_free(argv);
508
+ rl_free(argvlen);
509
+ free(newvalue);
510
+ return retval;
511
+ }
512
+
513
+ int rl_pfdebug_getreg(struct rlite *db, const unsigned char *key, long keylen, int *size, long **elements)
514
+ {
515
+ int retval;
516
+ unsigned char *value = NULL;
517
+ long valuelen = 0;
518
+ RL_CALL(rl_get, RL_OK, db, key, keylen, &value, &valuelen);
519
+ retval = rl_str_pfdebug_getreg(value, valuelen, size, elements, &value, &valuelen);
520
+ if (retval != 0) {
521
+ if (retval == -1) {
522
+ retval = RL_INVALID_STATE;
523
+ } else if (retval == -3) {
524
+ retval = RL_OUT_OF_MEMORY;
525
+ } else {
526
+ retval = RL_UNEXPECTED;
527
+ }
528
+ goto cleanup;
529
+ }
530
+ retval = RL_OK;
531
+ cleanup:
532
+ free(value);
533
+ return retval;
534
+ }
535
+
536
+ int rl_pfdebug_decode(struct rlite *db, const unsigned char *key, long keylen, unsigned char **value, long *valuelen)
537
+ {
538
+ int retval;
539
+ unsigned char *str = NULL;
540
+ long strlen;
541
+ RL_CALL(rl_get, RL_OK, db, key, keylen, &str, &strlen);
542
+ retval = rl_str_pfdebug_decode(str, strlen, value, valuelen);
543
+ if (retval != 0) {
544
+ if (retval == -1 || retval == -2) {
545
+ retval = RL_INVALID_STATE;
546
+ } else {
547
+ retval = RL_UNEXPECTED;
548
+ }
549
+ goto cleanup;
550
+ }
551
+ retval = RL_OK;
552
+ cleanup:
553
+ rl_free(str);
554
+ return retval;
555
+ }
556
+
557
+ int rl_pfdebug_encoding(struct rlite *db, const unsigned char *key, long keylen, unsigned char **value, long *valuelen)
558
+ {
559
+ int retval;
560
+ unsigned char *str = NULL;
561
+ long strlen;
562
+ RL_CALL(rl_get, RL_OK, db, key, keylen, &str, &strlen);
563
+ retval = rl_str_pfdebug_encoding(str, strlen, value, valuelen);
564
+ if (retval != 0) {
565
+ if (retval == -1) {
566
+ retval = RL_INVALID_STATE;
567
+ } else {
568
+ retval = RL_UNEXPECTED;
569
+ }
570
+ goto cleanup;
571
+ }
572
+ retval = RL_OK;
573
+ cleanup:
574
+ rl_free(str);
575
+ return retval;
576
+ }
577
+
578
+ int rl_pfdebug_todense(struct rlite *db, const unsigned char *key, long keylen, int *converted)
579
+ {
580
+ int retval;
581
+ unsigned char *str = NULL;
582
+ long strlen;
583
+ unsigned long long expires = 0;
584
+ RL_CALL(rl_get, RL_OK, db, key, keylen, &str, &strlen);
585
+ retval = rl_str_pfdebug_todense(str, strlen, &str, &strlen);
586
+ if (retval != 0 && retval != 1) {
587
+ if (retval == -1) {
588
+ retval = RL_INVALID_STATE;
589
+ } else {
590
+ retval = RL_UNEXPECTED;
591
+ }
592
+ goto cleanup;
593
+ }
594
+ *converted = retval;
595
+ if (retval == 1) {
596
+ RL_CALL2(rl_key_get, RL_FOUND, RL_NOT_FOUND, db, key, keylen, NULL, NULL, NULL, &expires, NULL);
597
+ RL_CALL(rl_set, RL_OK, db, key, keylen, str, strlen, 0, expires);
598
+ }
599
+ retval = RL_OK;
600
+ cleanup:
601
+ rl_free(str);
602
+ return retval;
603
+ }
604
+
605
+ int rl_string_pages(struct rlite *db, long page, short *pages)
606
+ {
607
+ return rl_multi_string_pages(db, page, pages);
608
+ }
609
+
610
+ int rl_string_delete(struct rlite *db, long value_page)
611
+ {
612
+ return rl_multi_string_delete(db, value_page);
613
+ }
@@ -0,0 +1,34 @@
1
+ #ifndef _RL_TYPE_STRING_H
2
+ #define _RL_TYPE_STRING_H
3
+
4
+ #include "page_multi_string.h"
5
+
6
+ #define RL_TYPE_STRING 'T'
7
+
8
+ struct rlite;
9
+
10
+ int rl_set(struct rlite *db, const unsigned char *key, long keylen, unsigned char *value, long valuelen, int nx, unsigned long long expires);
11
+ int rl_get(struct rlite *db, const unsigned char *key, long keylen, unsigned char **value, long *valuelen);
12
+ int rl_append(struct rlite *db, const unsigned char *key, long keylen, unsigned char *value, long valuelen, long *newlength);
13
+ int rl_getrange(struct rlite *db, const unsigned char *key, long keylen, long start, long stop, unsigned char **value, long *valuelen);
14
+ int rl_setrange(struct rlite *db, const unsigned char *key, long keylen, long index, unsigned char *value, long valuelen, long *newlength);
15
+ int rl_incr(struct rlite *db, const unsigned char *key, long keylen, long long increment, long long *newvalue);
16
+ int rl_incrbyfloat(struct rlite *db, const unsigned char *key, long keylen, double increment, double *newvalue);
17
+ int rl_getbit(struct rlite *db, const unsigned char *key, long keylen, long offset, int *value);
18
+ int rl_setbit(struct rlite *db, const unsigned char *key, long keylen, long bitoffset, int on, int *previousvalue);
19
+ int rl_bitop(struct rlite *db, int op, const unsigned char *dest, long destlen, unsigned long keylen, const unsigned char **keys, long *keyslen);
20
+ int rl_bitcount(struct rlite *db, const unsigned char *key, long keylen, long start, long stop, long *bitcount);
21
+ int rl_bitpos(struct rlite *db, const unsigned char *key, long keylen, int bit, long start, long stop, int end_given, long *position);
22
+
23
+ int rl_pfadd(struct rlite *db, const unsigned char *key, long keylen, int elementc, unsigned char **elements, long *elementslen, int *updated);
24
+ int rl_pfcount(struct rlite *db, int keyc, const unsigned char **key, long *keylen, long *count);
25
+ int rl_pfmerge(struct rlite *db, const unsigned char *destkey, long destkeylen, int keyc, const unsigned char **keys, long *keyslen);
26
+ int rl_pfdebug_getreg(struct rlite *db, const unsigned char *key, long keylen, int *size, long **elements);
27
+ int rl_pfdebug_decode(struct rlite *db, const unsigned char *key, long keylen, unsigned char **value, long *valuelen);
28
+ int rl_pfdebug_encoding(struct rlite *db, const unsigned char *key, long keylen, unsigned char **value, long *valuelen);
29
+ int rl_pfdebug_todense(struct rlite *db, const unsigned char *key, long keylen, int *converted);
30
+
31
+ int rl_string_pages(struct rlite *db, long page, short *pages);
32
+ int rl_string_delete(struct rlite *db, long value_page);
33
+
34
+ #endif