hirlite 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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,133 @@
|
|
1
|
+
#ifndef _RL_PAGE_BTREE_H
|
2
|
+
#define _RL_PAGE_BTREE_H
|
3
|
+
|
4
|
+
#define rl_btree_nocache_destroy(db, btree) rl_btree_destroy(db, btree)
|
5
|
+
#define rl_btree_node_nocache_destroy(db, node) rl_btree_node_destroy(db, node)
|
6
|
+
|
7
|
+
struct rl_data_type;
|
8
|
+
struct rl_btree;
|
9
|
+
struct rl_btree_node;
|
10
|
+
struct rlite;
|
11
|
+
|
12
|
+
typedef struct {
|
13
|
+
struct rl_data_type *btree_type;
|
14
|
+
struct rl_data_type *btree_node_type;
|
15
|
+
int score_size;
|
16
|
+
int value_size;
|
17
|
+
int (*cmp)(void *v1, void *v2);
|
18
|
+
#ifdef DEBUG
|
19
|
+
int (*formatter)(void *v, char **str, int *size);
|
20
|
+
#endif
|
21
|
+
} rl_btree_type;
|
22
|
+
|
23
|
+
int sha1_cmp(void *v1, void *v2);
|
24
|
+
#ifdef DEBUG
|
25
|
+
int sha1_formatter(void *v, char **str, int *size);
|
26
|
+
#endif
|
27
|
+
|
28
|
+
typedef struct rl_hashkey {
|
29
|
+
long string_page;
|
30
|
+
long value_page;
|
31
|
+
} rl_hashkey;
|
32
|
+
|
33
|
+
typedef struct rl_key {
|
34
|
+
unsigned char type;
|
35
|
+
long string_page;
|
36
|
+
long value_page;
|
37
|
+
unsigned long long expires;
|
38
|
+
long version;
|
39
|
+
} rl_key;
|
40
|
+
|
41
|
+
extern rl_btree_type rl_btree_type_set_long;
|
42
|
+
extern rl_btree_type rl_btree_type_hash_long_long;
|
43
|
+
extern rl_btree_type rl_btree_type_hash_sha1_key;
|
44
|
+
extern rl_btree_type rl_btree_type_hash_sha1_long;
|
45
|
+
extern rl_btree_type rl_btree_type_hash_sha1_hashkey;
|
46
|
+
extern rl_btree_type rl_btree_type_hash_sha1_double;
|
47
|
+
|
48
|
+
typedef struct rl_btree_node {
|
49
|
+
void **scores;
|
50
|
+
// children is null when the node is a leaf
|
51
|
+
// when created, allocs size+1.
|
52
|
+
long *children;
|
53
|
+
void **values;
|
54
|
+
// size is the number of children used; allocs the maximum on creation
|
55
|
+
long size;
|
56
|
+
} rl_btree_node;
|
57
|
+
|
58
|
+
typedef struct rl_btree {
|
59
|
+
struct rlite *db;
|
60
|
+
long max_node_size; // maximum number of scores in a node
|
61
|
+
long height;
|
62
|
+
rl_btree_type *type;
|
63
|
+
long root;
|
64
|
+
long number_of_elements;
|
65
|
+
} rl_btree;
|
66
|
+
|
67
|
+
typedef struct {
|
68
|
+
struct rlite *db;
|
69
|
+
rl_btree *btree;
|
70
|
+
long size;
|
71
|
+
long position;
|
72
|
+
struct rl_btree_iterator_nodes {
|
73
|
+
long position;
|
74
|
+
rl_btree_node *node;
|
75
|
+
} nodes[];
|
76
|
+
} rl_btree_iterator;
|
77
|
+
|
78
|
+
void rl_btree_init();
|
79
|
+
int rl_btree_create_size(struct rlite *db, rl_btree **btree, rl_btree_type *type, long max_node_size);
|
80
|
+
int rl_btree_create(struct rlite *db, rl_btree **btree, rl_btree_type *type);
|
81
|
+
int rl_btree_destroy(struct rlite *db, void *btree);
|
82
|
+
int rl_btree_node_destroy(struct rlite *db, void *node);
|
83
|
+
int rl_btree_add_element(struct rlite *db, rl_btree *btree, long btree_page, void *score, void *value);
|
84
|
+
int rl_btree_update_element(struct rlite *db, rl_btree *btree, void *score, void *value);
|
85
|
+
int rl_btree_remove_element(struct rlite *db, rl_btree *btree, long btree_page, void *score);
|
86
|
+
int rl_btree_find_score(struct rlite *db, rl_btree *btree, void *score, void **value, rl_btree_node *** nodes, long **positions);
|
87
|
+
/**
|
88
|
+
* rl_btree_random_element
|
89
|
+
*
|
90
|
+
* notice that all the elements in the tree do not have the same probability,
|
91
|
+
* and the order in which they were inserted is relevant. For example,
|
92
|
+
* inserting ascendenly will probably results in a lower probability
|
93
|
+
* to the elements with a higher score. The odds are approximately evenly
|
94
|
+
* distributed in the tree nodes, and even within the node, but not all nodes
|
95
|
+
* have the same number of elements.
|
96
|
+
*
|
97
|
+
* A true random element with even probabilities can be done, but it would
|
98
|
+
* be really expensive to generate (O(n) instead of O(log n)).
|
99
|
+
*/
|
100
|
+
int rl_btree_random_element(struct rlite *db, rl_btree *btree, void **score, void **value);
|
101
|
+
int rl_print_btree(struct rlite *db, rl_btree *btree);
|
102
|
+
int rl_btree_is_balanced(struct rlite *db, rl_btree *btree);
|
103
|
+
int rl_flatten_btree(struct rlite *db, rl_btree *btree, void *** scores, long *size);
|
104
|
+
|
105
|
+
int rl_btree_iterator_create(struct rlite *db, rl_btree *btree, rl_btree_iterator **iterator);
|
106
|
+
int rl_btree_iterator_next(rl_btree_iterator *iterator, void **score, void **value);
|
107
|
+
int rl_btree_iterator_destroy(rl_btree_iterator *iterator);
|
108
|
+
|
109
|
+
int rl_btree_serialize(struct rlite *db, void *obj, unsigned char *data);
|
110
|
+
int rl_btree_deserialize(struct rlite *db, void **obj, void *context, unsigned char *data);
|
111
|
+
|
112
|
+
int rl_btree_node_serialize_hash_sha1_key(struct rlite *db, void *obj, unsigned char *data);
|
113
|
+
int rl_btree_node_deserialize_hash_sha1_key(struct rlite *db, void **obj, void *context, unsigned char *data);
|
114
|
+
|
115
|
+
int rl_btree_node_serialize_hash_sha1_long(struct rlite *db, void *obj, unsigned char *data);
|
116
|
+
int rl_btree_node_deserialize_hash_sha1_long(struct rlite *db, void **obj, void *context, unsigned char *data);
|
117
|
+
|
118
|
+
int rl_btree_node_serialize_hash_sha1_hashkey(struct rlite *db, void *obj, unsigned char *data);
|
119
|
+
int rl_btree_node_deserialize_hash_sha1_hashkey(struct rlite *db, void **obj, void *context, unsigned char *data);
|
120
|
+
|
121
|
+
int rl_btree_node_serialize_set_long(struct rlite *db, void *obj, unsigned char *data);
|
122
|
+
int rl_btree_node_deserialize_set_long(struct rlite *db, void **obj, void *context, unsigned char *data);
|
123
|
+
|
124
|
+
int rl_btree_node_serialize_hash_long_long(struct rlite *db, void *obj, unsigned char *data);
|
125
|
+
int rl_btree_node_deserialize_hash_long_long(struct rlite *db, void **obj, void *context, unsigned char *data);
|
126
|
+
|
127
|
+
int rl_btree_node_serialize_hash_sha1_double(struct rlite *db, void *obj, unsigned char *data);
|
128
|
+
int rl_btree_node_deserialize_hash_sha1_double(struct rlite *db, void **obj, void *context, unsigned char *data);
|
129
|
+
|
130
|
+
int rl_btree_pages(struct rlite *db, rl_btree *btree, short *pages);
|
131
|
+
int rl_btree_delete(struct rlite *db, rl_btree *btree);
|
132
|
+
|
133
|
+
#endif
|
@@ -0,0 +1,283 @@
|
|
1
|
+
#include <stdlib.h>
|
2
|
+
#include <string.h>
|
3
|
+
#include "rlite.h"
|
4
|
+
#include "util.h"
|
5
|
+
#include "page_btree.h"
|
6
|
+
#include "page_key.h"
|
7
|
+
#include "page_multi_string.h"
|
8
|
+
#include "type_string.h"
|
9
|
+
#include "type_zset.h"
|
10
|
+
#include "type_hash.h"
|
11
|
+
|
12
|
+
#define TYPES_LENGTH 5
|
13
|
+
rl_type types[TYPES_LENGTH] = {
|
14
|
+
{
|
15
|
+
RL_TYPE_STRING,
|
16
|
+
"string",
|
17
|
+
rl_string_delete
|
18
|
+
},
|
19
|
+
{
|
20
|
+
RL_TYPE_LIST,
|
21
|
+
"list",
|
22
|
+
rl_llist_delete
|
23
|
+
},
|
24
|
+
{
|
25
|
+
RL_TYPE_SET,
|
26
|
+
"set",
|
27
|
+
rl_set_delete
|
28
|
+
},
|
29
|
+
{
|
30
|
+
RL_TYPE_ZSET,
|
31
|
+
"zset",
|
32
|
+
rl_zset_delete
|
33
|
+
},
|
34
|
+
{
|
35
|
+
RL_TYPE_HASH,
|
36
|
+
"hash",
|
37
|
+
rl_hash_delete
|
38
|
+
},
|
39
|
+
};
|
40
|
+
|
41
|
+
static int get_type(char identifier, rl_type **type)
|
42
|
+
{
|
43
|
+
long i;
|
44
|
+
for (i = 0; i < TYPES_LENGTH; i++) {
|
45
|
+
if (types[i].identifier == identifier) {
|
46
|
+
*type = &types[i];
|
47
|
+
return RL_OK;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
return RL_UNEXPECTED;
|
51
|
+
}
|
52
|
+
|
53
|
+
int rl_key_set(rlite *db, const unsigned char *key, long keylen, unsigned char type, long value_page, unsigned long long expires, long version)
|
54
|
+
{
|
55
|
+
int retval;
|
56
|
+
|
57
|
+
rl_key *key_obj = NULL;
|
58
|
+
unsigned char *digest = NULL;
|
59
|
+
RL_CALL2(rl_key_delete, RL_OK, RL_NOT_FOUND, db, key, keylen);
|
60
|
+
RL_MALLOC(digest, sizeof(unsigned char) * 20);
|
61
|
+
RL_CALL(sha1, RL_OK, key, keylen, digest);
|
62
|
+
rl_btree *btree;
|
63
|
+
RL_CALL(rl_get_key_btree, RL_OK, db, &btree, 1);
|
64
|
+
RL_MALLOC(key_obj, sizeof(*key_obj))
|
65
|
+
RL_CALL(rl_multi_string_set, RL_OK, db, &key_obj->string_page, key, keylen);
|
66
|
+
key_obj->type = type;
|
67
|
+
key_obj->value_page = value_page;
|
68
|
+
key_obj->expires = expires;
|
69
|
+
// reserving version=0 for non existent keys
|
70
|
+
if (version == 0) {
|
71
|
+
version = 1;
|
72
|
+
}
|
73
|
+
key_obj->version = version;
|
74
|
+
|
75
|
+
RL_CALL(rl_btree_add_element, RL_OK, db, btree, db->databases[db->selected_database], digest, key_obj);
|
76
|
+
retval = RL_OK;
|
77
|
+
cleanup:
|
78
|
+
if (retval != RL_OK) {
|
79
|
+
rl_free(digest);
|
80
|
+
rl_free(key_obj);
|
81
|
+
}
|
82
|
+
return retval;
|
83
|
+
}
|
84
|
+
|
85
|
+
static int rl_key_get_hash_ignore_expire(struct rlite *db, unsigned char digest[20], unsigned char *type, long *string_page, long *value_page, unsigned long long *expires, long *version, int ignore_expire)
|
86
|
+
{
|
87
|
+
int retval;
|
88
|
+
rl_btree *btree;
|
89
|
+
rl_key *key_obj;
|
90
|
+
RL_CALL(rl_get_key_btree, RL_OK, db, &btree, 0);
|
91
|
+
void *tmp = NULL;
|
92
|
+
retval = rl_btree_find_score(db, btree, digest, &tmp, NULL, NULL);
|
93
|
+
if (retval == RL_FOUND) {
|
94
|
+
key_obj = tmp;
|
95
|
+
if (ignore_expire == 0 && key_obj->expires != 0 && key_obj->expires <= rl_mstime()) {
|
96
|
+
retval = RL_DELETED;
|
97
|
+
goto cleanup;
|
98
|
+
}
|
99
|
+
else {
|
100
|
+
if (type) {
|
101
|
+
*type = key_obj->type;
|
102
|
+
}
|
103
|
+
if (string_page) {
|
104
|
+
*string_page = key_obj->string_page;
|
105
|
+
}
|
106
|
+
if (value_page) {
|
107
|
+
*value_page = key_obj->value_page;
|
108
|
+
}
|
109
|
+
if (expires) {
|
110
|
+
*expires = key_obj->expires;
|
111
|
+
}
|
112
|
+
if (version) {
|
113
|
+
*version = key_obj->version;
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}
|
117
|
+
cleanup:
|
118
|
+
return retval;
|
119
|
+
}
|
120
|
+
|
121
|
+
static int rl_key_get_ignore_expire(struct rlite *db, const unsigned char *key, long keylen, unsigned char *type, long *string_page, long *value_page, unsigned long long *expires, long *version, int ignore_expire)
|
122
|
+
{
|
123
|
+
unsigned char digest[20];
|
124
|
+
int retval;
|
125
|
+
RL_CALL(sha1, RL_OK, key, keylen, digest);
|
126
|
+
RL_CALL2(rl_key_get_hash_ignore_expire, RL_FOUND, RL_DELETED, db, digest, type, string_page, value_page, expires, version, ignore_expire);
|
127
|
+
if (retval == RL_DELETED) {
|
128
|
+
rl_key_delete_with_value(db, key, keylen);
|
129
|
+
if (version) {
|
130
|
+
*version = 0;
|
131
|
+
}
|
132
|
+
retval = RL_NOT_FOUND;
|
133
|
+
}
|
134
|
+
cleanup:
|
135
|
+
return retval;
|
136
|
+
}
|
137
|
+
|
138
|
+
static int rl_key_sha_check_version(struct rlite *db, struct watched_key* key) {
|
139
|
+
int retval;
|
140
|
+
long version;
|
141
|
+
int selected_database = db->selected_database;
|
142
|
+
// if the key has expired, the version is still valid, according to
|
143
|
+
// https://code.google.com/p/redis/issues/detail?id=270
|
144
|
+
// it seems to be relevant to redis being stateful and single process
|
145
|
+
// I don't think it is possible to replicate exactly the behavior, but
|
146
|
+
// this is pretty close.
|
147
|
+
RL_CALL2(rl_key_get_hash_ignore_expire, RL_FOUND, RL_NOT_FOUND, db, key->digest, NULL, NULL, NULL, NULL, &version, 1);
|
148
|
+
if (retval == RL_NOT_FOUND) {
|
149
|
+
version = 0;
|
150
|
+
}
|
151
|
+
if (version != key->version) {
|
152
|
+
retval = RL_OUTDATED;
|
153
|
+
} else {
|
154
|
+
retval = RL_OK;
|
155
|
+
}
|
156
|
+
cleanup:
|
157
|
+
db->selected_database = selected_database;
|
158
|
+
return retval;
|
159
|
+
}
|
160
|
+
|
161
|
+
int rl_check_watched_keys(struct rlite *db, int watched_count, struct watched_key** keys)
|
162
|
+
{
|
163
|
+
int i, retval = RL_OK;
|
164
|
+
|
165
|
+
for (i = 0; i < watched_count; i++) {
|
166
|
+
RL_CALL(rl_key_sha_check_version, RL_OK, db, keys[i]);
|
167
|
+
}
|
168
|
+
cleanup:
|
169
|
+
return retval;
|
170
|
+
}
|
171
|
+
|
172
|
+
int rl_watch(struct rlite *db, struct watched_key** _watched_key, const unsigned char *key, long keylen) {
|
173
|
+
int retval;
|
174
|
+
struct watched_key* wkey = NULL;
|
175
|
+
RL_MALLOC(wkey, sizeof(struct watched_key));
|
176
|
+
wkey->database = db->selected_database;
|
177
|
+
|
178
|
+
RL_CALL(sha1, RL_OK, key, keylen, wkey->digest);
|
179
|
+
RL_CALL2(rl_key_get_hash_ignore_expire, RL_FOUND, RL_NOT_FOUND, db, wkey->digest, NULL, NULL, NULL, NULL, &wkey->version, 1);
|
180
|
+
if (retval == RL_NOT_FOUND) {
|
181
|
+
wkey->version = 0;
|
182
|
+
}
|
183
|
+
|
184
|
+
*_watched_key = wkey;
|
185
|
+
retval = RL_OK;
|
186
|
+
cleanup:
|
187
|
+
if (retval != RL_OK) {
|
188
|
+
rl_free(wkey);
|
189
|
+
}
|
190
|
+
return retval;
|
191
|
+
}
|
192
|
+
|
193
|
+
int rl_key_get(struct rlite *db, const unsigned char *key, long keylen, unsigned char *type, long *string_page, long *value_page, unsigned long long *expires, long *version)
|
194
|
+
{
|
195
|
+
return rl_key_get_ignore_expire(db, key, keylen, type, string_page, value_page, expires, version, 0);
|
196
|
+
}
|
197
|
+
|
198
|
+
int rl_key_get_or_create(struct rlite *db, const unsigned char *key, long keylen, unsigned char type, long *page, long *version)
|
199
|
+
{
|
200
|
+
unsigned char existing_type;
|
201
|
+
int retval = rl_key_get(db, key, keylen, &existing_type, NULL, page, NULL, version);
|
202
|
+
long _version;
|
203
|
+
if (retval == RL_FOUND) {
|
204
|
+
if (existing_type != type) {
|
205
|
+
return RL_WRONG_TYPE;
|
206
|
+
}
|
207
|
+
}
|
208
|
+
else if (retval == RL_NOT_FOUND) {
|
209
|
+
_version = rand();
|
210
|
+
if (version) {
|
211
|
+
*version = _version;
|
212
|
+
}
|
213
|
+
rl_alloc_page_number(db, page);
|
214
|
+
RL_CALL(rl_key_set, RL_OK, db, key, keylen, type, *page, 0, _version);
|
215
|
+
retval = RL_NOT_FOUND;
|
216
|
+
}
|
217
|
+
cleanup:
|
218
|
+
return retval;
|
219
|
+
}
|
220
|
+
|
221
|
+
int rl_key_delete(struct rlite *db, const unsigned char *key, long keylen)
|
222
|
+
{
|
223
|
+
int retval;
|
224
|
+
void *tmp;
|
225
|
+
unsigned char *digest;
|
226
|
+
rl_btree *btree = NULL;
|
227
|
+
rl_key *key_obj = NULL;
|
228
|
+
RL_MALLOC(digest, sizeof(unsigned char) * 20);
|
229
|
+
RL_CALL(sha1, RL_OK, key, keylen, digest);
|
230
|
+
RL_CALL(rl_get_key_btree, RL_OK, db, &btree, 0);
|
231
|
+
retval = rl_btree_find_score(db, btree, digest, &tmp, NULL, NULL);
|
232
|
+
if (retval == RL_FOUND) {
|
233
|
+
key_obj = tmp;
|
234
|
+
RL_CALL(rl_multi_string_delete, RL_OK, db, key_obj->string_page);
|
235
|
+
retval = rl_btree_remove_element(db, btree, db->databases[db->selected_database], digest);
|
236
|
+
if (retval == RL_DELETED) {
|
237
|
+
db->databases[db->selected_database] = 0;
|
238
|
+
retval = RL_OK;
|
239
|
+
}
|
240
|
+
else if (retval != RL_OK) {
|
241
|
+
goto cleanup;
|
242
|
+
}
|
243
|
+
}
|
244
|
+
cleanup:
|
245
|
+
rl_free(digest);
|
246
|
+
return retval;
|
247
|
+
}
|
248
|
+
|
249
|
+
int rl_key_expires(struct rlite *db, const unsigned char *key, long keylen, unsigned long long expires)
|
250
|
+
{
|
251
|
+
int retval;
|
252
|
+
unsigned char type;
|
253
|
+
long string_page, value_page, version;
|
254
|
+
RL_CALL(rl_key_get, RL_FOUND, db, key, keylen, &type, &string_page, &value_page, NULL, &version);
|
255
|
+
RL_CALL(rl_key_set, RL_OK, db, key, keylen, type, value_page, expires, version + 1);
|
256
|
+
cleanup:
|
257
|
+
return retval;
|
258
|
+
}
|
259
|
+
|
260
|
+
int rl_key_delete_value(struct rlite *db, unsigned char identifier, long value_page)
|
261
|
+
{
|
262
|
+
int retval;
|
263
|
+
rl_type *type;
|
264
|
+
RL_CALL(get_type, RL_OK, identifier, &type);
|
265
|
+
RL_CALL(type->delete, RL_OK, db, value_page);
|
266
|
+
retval = RL_OK;
|
267
|
+
cleanup:
|
268
|
+
return retval;
|
269
|
+
}
|
270
|
+
|
271
|
+
int rl_key_delete_with_value(struct rlite *db, const unsigned char *key, long keylen)
|
272
|
+
{
|
273
|
+
int retval;
|
274
|
+
unsigned char identifier;
|
275
|
+
long value_page;
|
276
|
+
unsigned long long expires;
|
277
|
+
RL_CALL(rl_key_get_ignore_expire, RL_FOUND, db, key, keylen, &identifier, NULL, &value_page, &expires, NULL, 1);
|
278
|
+
RL_CALL(rl_key_delete_value, RL_OK, db, identifier, value_page);
|
279
|
+
RL_CALL(rl_key_delete, RL_OK, db, key, keylen);
|
280
|
+
retval = expires != 0 && expires <= rl_mstime() ? RL_NOT_FOUND : RL_OK;
|
281
|
+
cleanup:
|
282
|
+
return retval;
|
283
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#ifndef _RL_OBJ_KEY_H
|
2
|
+
#define _RL_OBJ_KEY_H
|
3
|
+
|
4
|
+
struct rlite;
|
5
|
+
struct watched_key;
|
6
|
+
|
7
|
+
typedef struct {
|
8
|
+
char identifier;
|
9
|
+
const char *name;
|
10
|
+
int (*delete)(struct rlite *db, long value_page);
|
11
|
+
} rl_type;
|
12
|
+
|
13
|
+
extern rl_type types[];
|
14
|
+
|
15
|
+
int rl_key_get_or_create(struct rlite *db, const unsigned char *key, long keylen, unsigned char type, long *page, long *version);
|
16
|
+
int rl_key_get(struct rlite *db, const unsigned char *key, long keylen, unsigned char *type, long *string_page, long *value_page, unsigned long long *expires, long *version);
|
17
|
+
int rl_check_watched_keys(struct rlite *db, int watched_count, struct watched_key** keys);
|
18
|
+
int rl_key_set(struct rlite *db, const unsigned char *key, long keylen, unsigned char type, long page, unsigned long long expires, long version);
|
19
|
+
int rl_key_delete(struct rlite *db, const unsigned char *key, long keylen);
|
20
|
+
int rl_key_expires(struct rlite *db, const unsigned char *key, long keylen, unsigned long long expires);
|
21
|
+
int rl_key_delete_value(struct rlite *db, unsigned char identifier, long value_page);
|
22
|
+
int rl_key_delete_with_value(struct rlite *db, const unsigned char *key, long keylen);
|
23
|
+
int rl_watch(struct rlite *db, struct watched_key** _watched_key, const unsigned char *key, long keylen);
|
24
|
+
|
25
|
+
#endif
|