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,70 @@
|
|
1
|
+
#ifndef _RL_PAGE_LIST_H
|
2
|
+
#define _RL_PAGE_LIST_H
|
3
|
+
|
4
|
+
struct rlite;
|
5
|
+
struct rl_list;
|
6
|
+
struct rl_list_node;
|
7
|
+
|
8
|
+
#define rl_list_nocache_destroy(db, list) rl_list_destroy(db, list)
|
9
|
+
#define rl_list_node_nocache_destroy(db, node) rl_list_node_destroy(db, node)
|
10
|
+
|
11
|
+
typedef struct {
|
12
|
+
struct rl_data_type *list_type;
|
13
|
+
struct rl_data_type *list_node_type;
|
14
|
+
int element_size;
|
15
|
+
int (*cmp)(void *v1, void *v2);
|
16
|
+
#ifdef DEBUG
|
17
|
+
int (*formatter)(void *v, char **str, int *size);
|
18
|
+
#endif
|
19
|
+
} rl_list_type;
|
20
|
+
|
21
|
+
extern rl_list_type rl_list_type_long;
|
22
|
+
|
23
|
+
typedef struct rl_list_node {
|
24
|
+
long size;
|
25
|
+
long left;
|
26
|
+
long right;
|
27
|
+
void **elements;
|
28
|
+
} rl_list_node;
|
29
|
+
|
30
|
+
typedef struct rl_list {
|
31
|
+
long max_node_size; // maximum number of elements in a node
|
32
|
+
long size;
|
33
|
+
rl_list_type *type;
|
34
|
+
long left;
|
35
|
+
long right;
|
36
|
+
} rl_list;
|
37
|
+
|
38
|
+
typedef struct rl_list_iterator {
|
39
|
+
struct rlite *db;
|
40
|
+
rl_list *list;
|
41
|
+
rl_list_node *node;
|
42
|
+
int direction; // 1 for right, -1 for left
|
43
|
+
long node_position;
|
44
|
+
} rl_list_iterator;
|
45
|
+
|
46
|
+
void rl_list_init();
|
47
|
+
int rl_list_create(struct rlite *db, rl_list **_list, rl_list_type *type);
|
48
|
+
int rl_list_destroy(struct rlite *db, void *list);
|
49
|
+
int rl_list_node_destroy(struct rlite *db, void *node);
|
50
|
+
int rl_list_get_element(struct rlite *db, rl_list *list, void **element, long position);
|
51
|
+
int rl_list_add_element(struct rlite *db, rl_list *list, long list_page, void *element, long position);
|
52
|
+
int rl_list_remove_element(struct rlite *db, rl_list *list, long list_page, long position);
|
53
|
+
int rl_list_find_element(struct rlite *db, rl_list *list, void *element, void **found_element, long *position, rl_list_node **found_node, long *found_node_page);
|
54
|
+
int rl_list_iterator_create(struct rlite *db, rl_list_iterator **iterator, rl_list *list, int direction);
|
55
|
+
int rl_list_iterator_destroy(struct rlite *db, rl_list_iterator *iterator);
|
56
|
+
int rl_list_iterator_next(rl_list_iterator *iterator, void **element);
|
57
|
+
int rl_print_list(struct rlite *db, rl_list *list);
|
58
|
+
int rl_list_is_balanced(struct rlite *db, rl_list *list);
|
59
|
+
int rl_flatten_list(struct rlite *db, rl_list *list, void **elements);
|
60
|
+
|
61
|
+
int rl_list_serialize(struct rlite *db, void *obj, unsigned char *data);
|
62
|
+
int rl_list_deserialize(struct rlite *db, void **obj, void *context, unsigned char *data);
|
63
|
+
|
64
|
+
int rl_list_node_serialize_long(struct rlite *db, void *obj, unsigned char *data);
|
65
|
+
int rl_list_node_deserialize_long(struct rlite *db, void **obj, void *context, unsigned char *data);
|
66
|
+
|
67
|
+
int rl_list_pages(struct rlite *db, rl_list *list, short *pages);
|
68
|
+
int rl_list_delete(struct rlite *db, rl_list *list);
|
69
|
+
|
70
|
+
#endif
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#include <stdlib.h>
|
2
|
+
#include <string.h>
|
3
|
+
#include "rlite.h"
|
4
|
+
#include "page_long.h"
|
5
|
+
#include "util.h"
|
6
|
+
|
7
|
+
int rl_long_serialize(rlite *UNUSED(db), void *obj, unsigned char *data)
|
8
|
+
{
|
9
|
+
put_4bytes(data, *(long *)obj);
|
10
|
+
return RL_OK;
|
11
|
+
}
|
12
|
+
|
13
|
+
int rl_long_deserialize(rlite *UNUSED(db), void **obj, void *UNUSED(context), unsigned char *data)
|
14
|
+
{
|
15
|
+
int retval;
|
16
|
+
long *value;
|
17
|
+
RL_MALLOC(value, sizeof(long));
|
18
|
+
*value = get_4bytes(data);
|
19
|
+
*obj = value;
|
20
|
+
retval = RL_OK;
|
21
|
+
cleanup:
|
22
|
+
return retval;
|
23
|
+
}
|
24
|
+
|
25
|
+
int rl_long_destroy(rlite *UNUSED(db), void *obj)
|
26
|
+
{
|
27
|
+
free(obj);
|
28
|
+
return RL_OK;
|
29
|
+
}
|
30
|
+
|
31
|
+
int rl_long_set(rlite *db, long value, long number)
|
32
|
+
{
|
33
|
+
int retval;
|
34
|
+
long *val;
|
35
|
+
RL_MALLOC(val, sizeof(*val));
|
36
|
+
*val = value;
|
37
|
+
RL_CALL(rl_write, RL_OK, db, &rl_data_type_long, number, val);
|
38
|
+
|
39
|
+
retval = RL_OK;
|
40
|
+
cleanup:
|
41
|
+
return retval;
|
42
|
+
}
|
43
|
+
|
44
|
+
int rl_long_create(struct rlite *db, long value, long *number)
|
45
|
+
{
|
46
|
+
if (number) {
|
47
|
+
*number = db->next_empty_page;
|
48
|
+
}
|
49
|
+
return rl_long_set(db, value, db->next_empty_page);
|
50
|
+
}
|
51
|
+
|
52
|
+
int rl_long_get(rlite *db, long *value, long number)
|
53
|
+
{
|
54
|
+
void *data;
|
55
|
+
int retval;
|
56
|
+
RL_CALL(rl_read, RL_FOUND, db, &rl_data_type_long, number, NULL, &data, 1);
|
57
|
+
*value = *(long *)data;
|
58
|
+
retval = RL_OK;
|
59
|
+
cleanup:
|
60
|
+
return retval;
|
61
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#ifndef _RL_PAGE_LONG_H
|
2
|
+
#define _RL_PAGE_LONG_H
|
3
|
+
|
4
|
+
struct rlite;
|
5
|
+
|
6
|
+
int rl_long_serialize(struct rlite *db, void *obj, unsigned char *data);
|
7
|
+
int rl_long_deserialize(struct rlite *db, void **obj, void *context, unsigned char *data);
|
8
|
+
int rl_long_destroy(struct rlite *db, void *obj);
|
9
|
+
int rl_long_create(struct rlite *db, long value, long *number);
|
10
|
+
int rl_long_get(struct rlite *db, long *value, long number);
|
11
|
+
int rl_long_set(struct rlite *db, long value, long number);
|
12
|
+
|
13
|
+
#endif
|
14
|
+
|
@@ -0,0 +1,538 @@
|
|
1
|
+
#include <stdlib.h>
|
2
|
+
#include <string.h>
|
3
|
+
#include "../deps/sha1.h"
|
4
|
+
#include "rlite.h"
|
5
|
+
#include "page_list.h"
|
6
|
+
#include "page_string.h"
|
7
|
+
#include "page_multi_string.h"
|
8
|
+
#include "util.h"
|
9
|
+
|
10
|
+
int rl_normalize_string_range(long totalsize, long *start, long *stop)
|
11
|
+
{
|
12
|
+
if (*start < 0) {
|
13
|
+
*start += totalsize;
|
14
|
+
if (*start < 0) {
|
15
|
+
*start = 0;
|
16
|
+
}
|
17
|
+
}
|
18
|
+
if (*stop < 0) {
|
19
|
+
*stop += totalsize;
|
20
|
+
if (*stop < 0) {
|
21
|
+
*stop = 0;
|
22
|
+
}
|
23
|
+
}
|
24
|
+
if (*start >= totalsize) {
|
25
|
+
*start = totalsize;
|
26
|
+
}
|
27
|
+
if (*stop >= totalsize) {
|
28
|
+
*stop = totalsize - 1;
|
29
|
+
}
|
30
|
+
return RL_OK;
|
31
|
+
}
|
32
|
+
|
33
|
+
int rl_multi_string_cmp(struct rlite *db, long p1, long p2, int *cmp)
|
34
|
+
{
|
35
|
+
rl_list *list1 = NULL, *list2 = NULL;
|
36
|
+
rl_list_node *node1 = NULL, *node2 = NULL;
|
37
|
+
void *_list, *_node;
|
38
|
+
unsigned char *str1, *str2;
|
39
|
+
|
40
|
+
int retval;
|
41
|
+
RL_CALL(rl_read, RL_FOUND, db, &rl_data_type_list_long, p1, &rl_list_type_long, &_list, 0);
|
42
|
+
list1 = _list;
|
43
|
+
RL_CALL(rl_read, RL_FOUND, db, &rl_data_type_list_long, p2, &rl_list_type_long, &_list, 0);
|
44
|
+
list2 = _list;
|
45
|
+
|
46
|
+
long node_number1 = list1->left, node_number2 = list2->left, i;
|
47
|
+
int first = 1;
|
48
|
+
while (1) {
|
49
|
+
if (node_number1 == 0 || node_number2 == 0) {
|
50
|
+
if (node_number1 == 0 && node_number2 == 0) {
|
51
|
+
*cmp = 0;
|
52
|
+
}
|
53
|
+
else if (node_number1 == 0) {
|
54
|
+
*cmp = -1;
|
55
|
+
}
|
56
|
+
else {
|
57
|
+
*cmp = 1;
|
58
|
+
}
|
59
|
+
retval = RL_OK;
|
60
|
+
goto cleanup;
|
61
|
+
}
|
62
|
+
RL_CALL(rl_read, RL_FOUND, db, list1->type->list_node_type, node_number1, list1, &_node, 0);
|
63
|
+
node1 = _node;
|
64
|
+
RL_CALL(rl_read, RL_FOUND, db, list2->type->list_node_type, node_number2, list2, &_node, 0);
|
65
|
+
node2 = _node;
|
66
|
+
if (first) {
|
67
|
+
if (*(long *)node1->elements[0] == 0) {
|
68
|
+
*cmp = -1;
|
69
|
+
retval = RL_OK;
|
70
|
+
goto cleanup;
|
71
|
+
}
|
72
|
+
if (*(long *)node2->elements[0] == 0) {
|
73
|
+
*cmp = 1;
|
74
|
+
retval = RL_OK;
|
75
|
+
goto cleanup;
|
76
|
+
}
|
77
|
+
}
|
78
|
+
for (i = first ? 1 : 0; i < node1->size; i++) {
|
79
|
+
first = 0;
|
80
|
+
RL_CALL(rl_string_get, RL_OK, db, &str1, *(long *)node1->elements[i]);
|
81
|
+
RL_CALL(rl_string_get, RL_OK, db, &str2, *(long *)node2->elements[i]);
|
82
|
+
*cmp = memcmp(str1, str2, db->page_size);
|
83
|
+
if (*cmp != 0) {
|
84
|
+
if (*cmp < 0) {
|
85
|
+
*cmp = -1;
|
86
|
+
}
|
87
|
+
else {
|
88
|
+
*cmp = 1;
|
89
|
+
}
|
90
|
+
goto cleanup;
|
91
|
+
}
|
92
|
+
}
|
93
|
+
node_number1 = node1->right;
|
94
|
+
node_number2 = node2->right;
|
95
|
+
rl_list_node_nocache_destroy(db, node1);
|
96
|
+
rl_list_node_nocache_destroy(db, node2);
|
97
|
+
node1 = node2 = NULL;
|
98
|
+
}
|
99
|
+
cleanup:
|
100
|
+
rl_list_nocache_destroy(db, list1);
|
101
|
+
rl_list_nocache_destroy(db, list2);
|
102
|
+
if (node1) {
|
103
|
+
rl_list_node_nocache_destroy(db, node1);
|
104
|
+
}
|
105
|
+
if (node2) {
|
106
|
+
rl_list_node_nocache_destroy(db, node2);
|
107
|
+
}
|
108
|
+
return retval;
|
109
|
+
}
|
110
|
+
|
111
|
+
int rl_multi_string_cmp_str(struct rlite *db, long p1, unsigned char *str, long len, int *cmp)
|
112
|
+
{
|
113
|
+
rl_list *list1 = NULL;
|
114
|
+
rl_list_node *node1 = NULL;
|
115
|
+
void *_list, *_node;
|
116
|
+
unsigned char *str1;
|
117
|
+
|
118
|
+
int retval;
|
119
|
+
RL_CALL(rl_read, RL_FOUND, db, &rl_data_type_list_long, p1, &rl_list_type_long, &_list, 0);
|
120
|
+
list1 = _list;
|
121
|
+
|
122
|
+
long node_number1 = list1->left, i, pos = 0;
|
123
|
+
int first = 1;
|
124
|
+
long cmplen;
|
125
|
+
long stored_length = 0;
|
126
|
+
*cmp = 0;
|
127
|
+
do {
|
128
|
+
if (node_number1 == 0) {
|
129
|
+
*cmp = len == 0 ? 0 : -1;
|
130
|
+
break;
|
131
|
+
}
|
132
|
+
RL_CALL(rl_read, RL_FOUND, db, list1->type->list_node_type, node_number1, list1, &_node, 0);
|
133
|
+
node1 = _node;
|
134
|
+
if (first) {
|
135
|
+
stored_length = *(long *)node1->elements[0];
|
136
|
+
if (stored_length == 0) {
|
137
|
+
*cmp = len == 0 ? 0 : -1;
|
138
|
+
}
|
139
|
+
}
|
140
|
+
for (i = first ? 1 : 0; i < node1->size; i++) {
|
141
|
+
RL_CALL(rl_string_get, RL_OK, db, &str1, *(long *)node1->elements[i]);
|
142
|
+
cmplen = db->page_size < len - pos ? db->page_size : len - pos;
|
143
|
+
if (cmplen == 0) {
|
144
|
+
// finished with str, the page_multi_string starts with str
|
145
|
+
*cmp = 1;
|
146
|
+
break;
|
147
|
+
}
|
148
|
+
*cmp = memcmp(str1, &str[pos], cmplen);
|
149
|
+
if (*cmp != 0) {
|
150
|
+
if (*cmp < 0) {
|
151
|
+
*cmp = -1;
|
152
|
+
}
|
153
|
+
else {
|
154
|
+
*cmp = 1;
|
155
|
+
}
|
156
|
+
goto cleanup;
|
157
|
+
}
|
158
|
+
pos += cmplen;
|
159
|
+
}
|
160
|
+
if (*cmp == 0 && len == pos && stored_length != len) {
|
161
|
+
*cmp = stored_length > len ? 1 : -1;
|
162
|
+
}
|
163
|
+
first = 0;
|
164
|
+
node_number1 = node1->right;
|
165
|
+
rl_list_node_nocache_destroy(db, node1);
|
166
|
+
node1 = NULL;
|
167
|
+
}
|
168
|
+
while (len > pos);
|
169
|
+
retval = RL_OK;
|
170
|
+
cleanup:
|
171
|
+
rl_list_nocache_destroy(db, list1);
|
172
|
+
if (node1) {
|
173
|
+
rl_list_node_nocache_destroy(db, node1);
|
174
|
+
}
|
175
|
+
return retval;
|
176
|
+
}
|
177
|
+
|
178
|
+
static int append(struct rlite *db, rl_list *list, long list_page_number, const unsigned char *data, long size)
|
179
|
+
{
|
180
|
+
int retval = RL_OK;
|
181
|
+
long *page;
|
182
|
+
long pos = 0, to_copy;
|
183
|
+
unsigned char *string = NULL;
|
184
|
+
while (pos < size) {
|
185
|
+
RL_MALLOC(page, sizeof(*page));
|
186
|
+
retval = rl_string_create(db, &string, page);
|
187
|
+
if (retval != RL_OK) {
|
188
|
+
goto cleanup;
|
189
|
+
}
|
190
|
+
to_copy = db->page_size;
|
191
|
+
if (pos + to_copy > size) {
|
192
|
+
to_copy = size - pos;
|
193
|
+
}
|
194
|
+
memcpy(string, &data[pos], sizeof(unsigned char) * to_copy);
|
195
|
+
string = NULL;
|
196
|
+
RL_CALL(rl_list_add_element, RL_OK, db, list, list_page_number, page, -1);
|
197
|
+
page = NULL;
|
198
|
+
pos += to_copy;
|
199
|
+
}
|
200
|
+
cleanup:
|
201
|
+
rl_free(string);
|
202
|
+
rl_free(page);
|
203
|
+
return retval;
|
204
|
+
}
|
205
|
+
|
206
|
+
int rl_multi_string_append(struct rlite *db, long number, const unsigned char *data, long datasize, long *newlength)
|
207
|
+
{
|
208
|
+
rl_list *list = NULL;
|
209
|
+
unsigned char *tmp_data;
|
210
|
+
void *tmp;
|
211
|
+
int retval;
|
212
|
+
long size, cpsize;
|
213
|
+
long string_page_number;
|
214
|
+
|
215
|
+
RL_CALL(rl_read, RL_FOUND, db, &rl_data_type_list_long, number, &rl_list_type_long, &tmp, 0);
|
216
|
+
list = tmp;
|
217
|
+
|
218
|
+
RL_CALL(rl_list_get_element, RL_FOUND, db, list, &tmp, 0);
|
219
|
+
size = *(long *)tmp;
|
220
|
+
RL_MALLOC(tmp, sizeof(long));
|
221
|
+
*(long *)tmp = size + datasize;
|
222
|
+
RL_CALL(rl_list_add_element, RL_OK, db, list, number, tmp, 0);
|
223
|
+
RL_CALL(rl_list_remove_element, RL_OK, db, list, number, 1);
|
224
|
+
if (newlength) {
|
225
|
+
*newlength = size + datasize;
|
226
|
+
}
|
227
|
+
|
228
|
+
size = size % db->page_size;
|
229
|
+
|
230
|
+
if (size > 0) {
|
231
|
+
RL_CALL(rl_list_get_element, RL_FOUND, db, list, &tmp, -1);
|
232
|
+
string_page_number = *(long *)tmp;
|
233
|
+
RL_CALL(rl_string_get, RL_OK, db, &tmp_data, string_page_number);
|
234
|
+
cpsize = db->page_size - size;
|
235
|
+
if (cpsize > datasize) {
|
236
|
+
cpsize = datasize;
|
237
|
+
}
|
238
|
+
memcpy(&tmp_data[size], data, cpsize * sizeof(unsigned char));
|
239
|
+
RL_CALL(rl_write, RL_OK, db, &rl_data_type_string, string_page_number, tmp_data);
|
240
|
+
data = &data[cpsize];
|
241
|
+
datasize -= cpsize;
|
242
|
+
}
|
243
|
+
|
244
|
+
if (datasize > 0) {
|
245
|
+
RL_CALL(append, RL_OK, db, list, number, data, datasize);
|
246
|
+
}
|
247
|
+
|
248
|
+
retval = RL_OK;
|
249
|
+
cleanup:
|
250
|
+
return retval;
|
251
|
+
}
|
252
|
+
|
253
|
+
int rl_multi_string_getrange(struct rlite *db, long number, unsigned char **_data, long *size, long start, long stop)
|
254
|
+
{
|
255
|
+
long totalsize;
|
256
|
+
rl_list *list = NULL;
|
257
|
+
rl_list_node *node = NULL;
|
258
|
+
void *_list, *tmp;
|
259
|
+
unsigned char *data = NULL;
|
260
|
+
int retval;
|
261
|
+
RL_CALL(rl_read, RL_FOUND, db, &rl_data_type_list_long, number, &rl_list_type_long, &_list, 0);
|
262
|
+
list = _list;
|
263
|
+
unsigned char *tmp_data;
|
264
|
+
long i, pos = 0, pagesize, pagestart;
|
265
|
+
|
266
|
+
RL_CALL(rl_list_get_element, RL_FOUND, db, list, &tmp, 0);
|
267
|
+
totalsize = *(long *)tmp;
|
268
|
+
if (totalsize == 0) {
|
269
|
+
*size = 0;
|
270
|
+
if (_data) {
|
271
|
+
*_data = NULL;
|
272
|
+
}
|
273
|
+
retval = RL_OK;
|
274
|
+
goto cleanup;
|
275
|
+
}
|
276
|
+
rl_normalize_string_range(totalsize, &start, &stop);
|
277
|
+
if (stop < start) {
|
278
|
+
*size = 0;
|
279
|
+
if (_data) {
|
280
|
+
*_data = NULL;
|
281
|
+
}
|
282
|
+
retval = RL_OK;
|
283
|
+
goto cleanup;
|
284
|
+
}
|
285
|
+
*size = stop - start + 1;
|
286
|
+
if (!_data) {
|
287
|
+
retval = RL_OK;
|
288
|
+
goto cleanup;
|
289
|
+
}
|
290
|
+
|
291
|
+
RL_MALLOC(data, sizeof(unsigned char) * (*size + 1));
|
292
|
+
|
293
|
+
i = start / db->page_size;
|
294
|
+
pagestart = start % db->page_size;
|
295
|
+
// pos = i * db->page_size + pagestart;
|
296
|
+
// the first element in the list is the length of the array, skip to the second
|
297
|
+
for (i++; i < list->size; i++) {
|
298
|
+
RL_CALL(rl_list_get_element, RL_FOUND, db, list, &tmp, i);
|
299
|
+
RL_CALL(rl_string_get, RL_OK, db, &tmp_data, *(long *)tmp);
|
300
|
+
pagesize = db->page_size - pagestart;
|
301
|
+
if (pos + pagesize > *size) {
|
302
|
+
pagesize = *size - pos;
|
303
|
+
}
|
304
|
+
memcpy(&data[pos], &tmp_data[pagestart], sizeof(unsigned char) * pagesize);
|
305
|
+
pos += pagesize;
|
306
|
+
pagestart = 0;
|
307
|
+
}
|
308
|
+
data[*size] = 0;
|
309
|
+
*_data = data;
|
310
|
+
retval = RL_OK;
|
311
|
+
cleanup:
|
312
|
+
if (retval != RL_OK) {
|
313
|
+
rl_free(data);
|
314
|
+
}
|
315
|
+
if (list) {
|
316
|
+
rl_list_nocache_destroy(db, list);
|
317
|
+
}
|
318
|
+
if (node) {
|
319
|
+
rl_list_node_nocache_destroy(db, node);
|
320
|
+
}
|
321
|
+
return retval;
|
322
|
+
}
|
323
|
+
|
324
|
+
int rl_multi_string_get(struct rlite *db, long number, unsigned char **_data, long *size)
|
325
|
+
{
|
326
|
+
return rl_multi_string_getrange(db, number, _data, size, 0, -1);
|
327
|
+
}
|
328
|
+
|
329
|
+
int rl_multi_string_set(struct rlite *db, long *number, const unsigned char *data, long size)
|
330
|
+
{
|
331
|
+
int retval;
|
332
|
+
long *page = NULL;
|
333
|
+
rl_list *list = NULL;
|
334
|
+
RL_CALL(rl_list_create, RL_OK, db, &list, &rl_list_type_long);
|
335
|
+
*number = db->next_empty_page;
|
336
|
+
RL_CALL(rl_write, RL_OK, db, &rl_data_type_list_long, *number, list);
|
337
|
+
RL_MALLOC(page, sizeof(*page));
|
338
|
+
*page = size;
|
339
|
+
RL_CALL(rl_list_add_element, RL_OK, db, list, *number, page, -1);
|
340
|
+
page = NULL;
|
341
|
+
RL_CALL(append, RL_OK, db, list, *number, data, size);
|
342
|
+
cleanup:
|
343
|
+
return retval;
|
344
|
+
}
|
345
|
+
int rl_multi_string_setrange(struct rlite *db, long number, const unsigned char *data, long size, long offset, long *newlength)
|
346
|
+
{
|
347
|
+
long oldsize, newsize;
|
348
|
+
rl_list *list = NULL;
|
349
|
+
void *_list, *tmp;
|
350
|
+
int retval;
|
351
|
+
RL_CALL(rl_read, RL_FOUND, db, &rl_data_type_list_long, number, &rl_list_type_long, &_list, 1);
|
352
|
+
list = _list;
|
353
|
+
unsigned char *tmp_data;
|
354
|
+
long i, pagesize, pagestart, page;
|
355
|
+
if (offset < 0) {
|
356
|
+
retval = RL_INVALID_PARAMETERS;
|
357
|
+
goto cleanup;
|
358
|
+
}
|
359
|
+
|
360
|
+
RL_CALL(rl_list_get_element, RL_FOUND, db, list, &tmp, 0);
|
361
|
+
oldsize = *(long *)tmp;
|
362
|
+
if (oldsize > offset) {
|
363
|
+
i = offset / db->page_size;
|
364
|
+
pagestart = offset % db->page_size;
|
365
|
+
|
366
|
+
newsize = offset + size;
|
367
|
+
if (newsize > (list->size - 1) * db->page_size) {
|
368
|
+
newsize = (list->size - 1) * db->page_size;
|
369
|
+
}
|
370
|
+
if (newsize > oldsize) {
|
371
|
+
RL_CALL(rl_list_remove_element, RL_OK, db, list, number, 0);
|
372
|
+
RL_MALLOC(tmp, sizeof(long));
|
373
|
+
*(long *)tmp = newsize;
|
374
|
+
RL_CALL(rl_list_add_element, RL_OK, db, list, number, tmp, 0);
|
375
|
+
}
|
376
|
+
|
377
|
+
for (i++; size > 0 && i < list->size; i++) {
|
378
|
+
RL_CALL(rl_list_get_element, RL_FOUND, db, list, &tmp, i);
|
379
|
+
page = *(long *)tmp;
|
380
|
+
RL_CALL(rl_string_get, RL_OK, db, &tmp_data, page);
|
381
|
+
pagesize = db->page_size - pagestart;
|
382
|
+
if (pagesize > size) {
|
383
|
+
pagesize = size;
|
384
|
+
}
|
385
|
+
memcpy(&tmp_data[pagestart], data, sizeof(char) * pagesize);
|
386
|
+
RL_CALL(rl_write, RL_OK, db, &rl_data_type_string, page, tmp_data);
|
387
|
+
|
388
|
+
// if there's more bytes that did not enter in this page it will be caught with an append
|
389
|
+
if (oldsize < pagesize + pagestart) {
|
390
|
+
oldsize = pagesize + pagestart;
|
391
|
+
}
|
392
|
+
data += pagesize;
|
393
|
+
offset += pagesize;
|
394
|
+
size -= pagesize;
|
395
|
+
pagestart = 0;
|
396
|
+
}
|
397
|
+
if (newlength) {
|
398
|
+
*newlength = oldsize;
|
399
|
+
}
|
400
|
+
}
|
401
|
+
|
402
|
+
if (oldsize < offset) {
|
403
|
+
RL_MALLOC(tmp_data, sizeof(char) * (size + offset - oldsize));
|
404
|
+
memset(tmp_data, 0, offset - oldsize);
|
405
|
+
memcpy(&tmp_data[offset - oldsize], data, sizeof(char) * size);
|
406
|
+
RL_CALL(rl_multi_string_append, RL_OK, db, number, tmp_data, size + offset - oldsize, newlength);
|
407
|
+
rl_free(tmp_data);
|
408
|
+
}
|
409
|
+
else if (oldsize == offset && size > 0) {
|
410
|
+
RL_CALL(rl_multi_string_append, RL_OK, db, number, data, size, newlength);
|
411
|
+
}
|
412
|
+
retval = RL_OK;
|
413
|
+
cleanup:
|
414
|
+
return retval;
|
415
|
+
}
|
416
|
+
|
417
|
+
|
418
|
+
int rl_multi_string_sha1(struct rlite *db, unsigned char digest[20], long number)
|
419
|
+
{
|
420
|
+
unsigned char *data;
|
421
|
+
long datalen;
|
422
|
+
SHA1_CTX sha;
|
423
|
+
SHA1Init(&sha);
|
424
|
+
|
425
|
+
void *tmp;
|
426
|
+
rl_list *list;
|
427
|
+
rl_list_iterator *iterator = NULL;
|
428
|
+
int retval;
|
429
|
+
RL_CALL(rl_read, RL_FOUND, db, &rl_data_type_list_long, number, &rl_list_type_long, &tmp, 0);
|
430
|
+
list = tmp;
|
431
|
+
|
432
|
+
RL_CALL(rl_list_iterator_create, RL_OK, db, &iterator, list, 1);
|
433
|
+
|
434
|
+
long size = 0;
|
435
|
+
while ((retval = rl_list_iterator_next(iterator, &tmp)) == RL_OK) {
|
436
|
+
if (size == 0) {
|
437
|
+
size = *(long *)tmp;
|
438
|
+
rl_free(tmp);
|
439
|
+
continue;
|
440
|
+
}
|
441
|
+
RL_CALL(rl_string_get, RL_OK, db, &data, *(long *)tmp);
|
442
|
+
datalen = size > db->page_size ? db->page_size : size;
|
443
|
+
SHA1Update(&sha, data, datalen);
|
444
|
+
size -= datalen;
|
445
|
+
rl_free(tmp);
|
446
|
+
}
|
447
|
+
iterator = NULL;
|
448
|
+
|
449
|
+
if (retval != RL_END) {
|
450
|
+
goto cleanup;
|
451
|
+
}
|
452
|
+
|
453
|
+
RL_CALL(rl_list_nocache_destroy, RL_OK, db, list);
|
454
|
+
|
455
|
+
SHA1Final(digest, &sha);
|
456
|
+
retval = RL_OK;
|
457
|
+
cleanup:
|
458
|
+
if (iterator) {
|
459
|
+
rl_list_iterator_destroy(db, iterator);
|
460
|
+
}
|
461
|
+
return retval;
|
462
|
+
}
|
463
|
+
|
464
|
+
int rl_multi_string_pages(struct rlite *db, long page, short *pages)
|
465
|
+
{
|
466
|
+
void *tmp;
|
467
|
+
rl_list *list;
|
468
|
+
rl_list_iterator *iterator = NULL;
|
469
|
+
int retval;
|
470
|
+
RL_CALL(rl_read, RL_FOUND, db, &rl_data_type_list_long, page, &rl_list_type_long, &tmp, 0);
|
471
|
+
list = tmp;
|
472
|
+
|
473
|
+
RL_CALL(rl_list_pages, RL_OK, db, list, pages);
|
474
|
+
RL_CALL(rl_list_iterator_create, RL_OK, db, &iterator, list, 1);
|
475
|
+
|
476
|
+
int first = 1;
|
477
|
+
while ((retval = rl_list_iterator_next(iterator, &tmp)) == RL_OK) {
|
478
|
+
if (first) {
|
479
|
+
first = 0;
|
480
|
+
}
|
481
|
+
else {
|
482
|
+
pages[*(long *)tmp] = 1;
|
483
|
+
}
|
484
|
+
rl_free(tmp);
|
485
|
+
}
|
486
|
+
iterator = NULL;
|
487
|
+
|
488
|
+
if (retval != RL_END) {
|
489
|
+
goto cleanup;
|
490
|
+
}
|
491
|
+
|
492
|
+
RL_CALL(rl_list_nocache_destroy, RL_OK, db, list);
|
493
|
+
|
494
|
+
retval = RL_OK;
|
495
|
+
cleanup:
|
496
|
+
if (iterator) {
|
497
|
+
rl_list_iterator_destroy(db, iterator);
|
498
|
+
}
|
499
|
+
return retval;
|
500
|
+
}
|
501
|
+
|
502
|
+
int rl_multi_string_delete(struct rlite *db, long page)
|
503
|
+
{
|
504
|
+
void *tmp;
|
505
|
+
rl_list *list;
|
506
|
+
rl_list_iterator *iterator = NULL;
|
507
|
+
int retval;
|
508
|
+
RL_CALL(rl_read, RL_FOUND, db, &rl_data_type_list_long, page, &rl_list_type_long, &tmp, 1);
|
509
|
+
list = tmp;
|
510
|
+
|
511
|
+
RL_CALL(rl_list_iterator_create, RL_OK, db, &iterator, list, 1);
|
512
|
+
|
513
|
+
int first = 1;
|
514
|
+
while ((retval = rl_list_iterator_next(iterator, &tmp)) == RL_OK) {
|
515
|
+
if (first) {
|
516
|
+
first = 0;
|
517
|
+
}
|
518
|
+
else {
|
519
|
+
RL_CALL(rl_delete, RL_OK, db, *(long *)tmp);
|
520
|
+
}
|
521
|
+
rl_free(tmp);
|
522
|
+
}
|
523
|
+
iterator = NULL;
|
524
|
+
|
525
|
+
if (retval != RL_END) {
|
526
|
+
goto cleanup;
|
527
|
+
}
|
528
|
+
|
529
|
+
RL_CALL(rl_list_delete, RL_OK, db, list);
|
530
|
+
RL_CALL(rl_delete, RL_OK, db, page);
|
531
|
+
|
532
|
+
retval = RL_OK;
|
533
|
+
cleanup:
|
534
|
+
if (iterator) {
|
535
|
+
rl_list_iterator_destroy(db, iterator);
|
536
|
+
}
|
537
|
+
return retval;
|
538
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#ifndef _RL_OBJ_STRING_H
|
2
|
+
#define _RL_OBJ_STRING_H
|
3
|
+
|
4
|
+
struct rlite;
|
5
|
+
|
6
|
+
int rl_normalize_string_range(long totalsize, long *start, long *stop);
|
7
|
+
int rl_multi_string_cmp(struct rlite *db, long p1, long p2, int *cmp);
|
8
|
+
int rl_multi_string_cmp_str(struct rlite *db, long p1, unsigned char *str, long len, int *cmp);
|
9
|
+
int rl_multi_string_getrange(struct rlite *db, long number, unsigned char **_data, long *size, long start, long stop);
|
10
|
+
int rl_multi_string_get(struct rlite *db, long number, unsigned char **data, long *size);
|
11
|
+
int rl_multi_string_setrange(struct rlite *db, long number, const unsigned char *data, long size, long offset, long *newlength);
|
12
|
+
int rl_multi_string_set(struct rlite *db, long *number, const unsigned char *data, long size);
|
13
|
+
int rl_multi_string_append(struct rlite *db, long number, const unsigned char *data, long datasize, long *newlength);
|
14
|
+
int rl_multi_string_sha1(struct rlite *db, unsigned char data[20], long number);
|
15
|
+
int rl_multi_string_pages(struct rlite *db, long page, short *pages);
|
16
|
+
int rl_multi_string_delete(struct rlite *db, long page);
|
17
|
+
|
18
|
+
#endif
|