hirlite 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/LICENSE +28 -0
- data/Rakefile +51 -0
- data/ext/hirlite_ext/extconf.rb +33 -0
- data/ext/hirlite_ext/hirlite_ext.c +14 -0
- data/ext/hirlite_ext/hirlite_ext.h +38 -0
- data/ext/hirlite_ext/rlite.c +351 -0
- data/lib/hirlite/rlite.rb +1 -0
- data/lib/hirlite/version.rb +3 -0
- data/lib/hirlite.rb +2 -0
- data/vendor/rlite/Makefile +6 -0
- data/vendor/rlite/deps/crc64.c +191 -0
- data/vendor/rlite/deps/crc64.h +3 -0
- data/vendor/rlite/deps/endianconv.h +73 -0
- data/vendor/rlite/deps/hyperloglog.c +1547 -0
- data/vendor/rlite/deps/hyperloglog.h +14 -0
- data/vendor/rlite/deps/lzf.h +100 -0
- data/vendor/rlite/deps/lzfP.h +159 -0
- data/vendor/rlite/deps/lzf_c.c +295 -0
- data/vendor/rlite/deps/lzf_d.c +150 -0
- data/vendor/rlite/deps/sha1.c +227 -0
- data/vendor/rlite/deps/sha1.h +19 -0
- data/vendor/rlite/deps/utilfromredis.c +397 -0
- data/vendor/rlite/deps/utilfromredis.h +11 -0
- data/vendor/rlite/src/Makefile +79 -0
- data/vendor/rlite/src/constants.h +15 -0
- data/vendor/rlite/src/dump.c +191 -0
- data/vendor/rlite/src/dump.h +3 -0
- data/vendor/rlite/src/hirlite.c +3985 -0
- data/vendor/rlite/src/hirlite.h +186 -0
- data/vendor/rlite/src/page_btree.c +1556 -0
- data/vendor/rlite/src/page_btree.h +133 -0
- data/vendor/rlite/src/page_key.c +283 -0
- data/vendor/rlite/src/page_key.h +25 -0
- data/vendor/rlite/src/page_list.c +718 -0
- data/vendor/rlite/src/page_list.h +70 -0
- data/vendor/rlite/src/page_long.c +61 -0
- data/vendor/rlite/src/page_long.h +14 -0
- data/vendor/rlite/src/page_multi_string.c +538 -0
- data/vendor/rlite/src/page_multi_string.h +18 -0
- data/vendor/rlite/src/page_skiplist.c +689 -0
- data/vendor/rlite/src/page_skiplist.h +70 -0
- data/vendor/rlite/src/page_string.c +55 -0
- data/vendor/rlite/src/page_string.h +12 -0
- data/vendor/rlite/src/pqsort.c +185 -0
- data/vendor/rlite/src/pqsort.h +40 -0
- data/vendor/rlite/src/restore.c +401 -0
- data/vendor/rlite/src/restore.h +3 -0
- data/vendor/rlite/src/rlite.c +1309 -0
- data/vendor/rlite/src/rlite.h +159 -0
- data/vendor/rlite/src/sort.c +530 -0
- data/vendor/rlite/src/sort.h +18 -0
- data/vendor/rlite/src/status.h +19 -0
- data/vendor/rlite/src/type_hash.c +607 -0
- data/vendor/rlite/src/type_hash.h +29 -0
- data/vendor/rlite/src/type_list.c +477 -0
- data/vendor/rlite/src/type_list.h +23 -0
- data/vendor/rlite/src/type_set.c +796 -0
- data/vendor/rlite/src/type_set.h +34 -0
- data/vendor/rlite/src/type_string.c +613 -0
- data/vendor/rlite/src/type_string.h +34 -0
- data/vendor/rlite/src/type_zset.c +1147 -0
- data/vendor/rlite/src/type_zset.h +50 -0
- data/vendor/rlite/src/util.c +334 -0
- data/vendor/rlite/src/util.h +71 -0
- 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], <mp);
|
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
|