nmdb: Add LevelDB support
[nmdb.git] / nmdb / be-leveldb.c
blobaad0f88ba1158bb620d445a3241e98b95143c8e3
2 #if BE_ENABLE_LEVELDB
4 #include <leveldb/c.h> /* LevelDB C API */
5 #include <string.h> /* memcpy() */
6 #include <stdlib.h>
8 #include "be.h"
11 int xleveldb_set(struct db_conn *db, const unsigned char *key, size_t ksize,
12 unsigned char *val, size_t vsize);
13 int xleveldb_get(struct db_conn *db, const unsigned char *key, size_t ksize,
14 unsigned char *val, size_t *vsize);
15 int xleveldb_del(struct db_conn *db, const unsigned char *key, size_t ksize);
16 int xleveldb_close(struct db_conn *db);
17 int xleveldb_firstkey(struct db_conn *db, unsigned char *key, size_t *ksize);
18 int xleveldb_nextkey(struct db_conn *db,
19 const unsigned char *key, size_t ksize,
20 unsigned char *nextkey, size_t *nksize);
22 struct db_conn *xleveldb_open(const char *name, int flags)
24 struct db_conn *db;
25 leveldb_options_t *options;
26 leveldb_t *level_db;
28 options = leveldb_options_create();
29 if (options == NULL)
30 return NULL;
32 leveldb_options_set_create_if_missing(options, 1);
34 level_db = leveldb_open(options, name, NULL);
36 leveldb_options_destroy(options);
38 if (level_db == NULL)
39 return NULL;
41 db = malloc(sizeof(struct db_conn));
42 if (db == NULL) {
43 leveldb_close(level_db);
44 return NULL;
47 db->conn = level_db;
48 db->set = xleveldb_set;
49 db->get = xleveldb_get;
50 db->del = xleveldb_del;
51 db->firstkey = xleveldb_firstkey;
52 db->nextkey = xleveldb_nextkey;
53 db->close = xleveldb_close;
55 return db;
59 int xleveldb_close(struct db_conn *db)
61 leveldb_close(db->conn);
62 free(db);
63 return 1;
67 int xleveldb_set(struct db_conn *db, const unsigned char *key, size_t ksize,
68 unsigned char *val, size_t vsize)
70 leveldb_writeoptions_t *options = leveldb_writeoptions_create();
71 char *err, *origerr;
73 err = origerr = malloc(1);
74 leveldb_put(db->conn, options,
75 (const char *) key, ksize,
76 (const char *) val, vsize, &err);
77 free(err);
79 leveldb_writeoptions_destroy(options);
81 return err == origerr;
85 int xleveldb_get(struct db_conn *db, const unsigned char *key, size_t ksize,
86 unsigned char *val, size_t *vsize)
88 int rv;
89 char *db_val = NULL;
90 size_t db_vsize;
91 leveldb_readoptions_t *options = leveldb_readoptions_create();
92 char *err, *origerr;
94 err = origerr = malloc(1);
95 db_val = leveldb_get(db->conn, options,
96 (const char *) key, ksize, &db_vsize, &err);
98 free(err);
99 leveldb_readoptions_destroy(options);
101 if (err != origerr || db_val == NULL || db_vsize > *vsize) {
102 rv = 0;
103 goto exit;
106 *vsize = db_vsize;
107 memcpy(val, db_val, db_vsize);
108 rv = 1;
110 exit:
111 free(db_val);
112 return rv;
116 int xleveldb_del(struct db_conn *db, const unsigned char *key, size_t ksize)
118 leveldb_writeoptions_t *options = leveldb_writeoptions_create();
119 char *err, *origerr;
121 err = origerr = malloc(1);
122 leveldb_delete(db->conn, options,
123 (const char *) key, ksize, &err);
124 free(err);
126 leveldb_writeoptions_destroy(options);
128 return err == origerr;
132 int xleveldb_firstkey(struct db_conn *db, unsigned char *key, size_t *ksize)
134 int rv = 0;
135 const char *db_key;
136 size_t db_ksize;
138 leveldb_readoptions_t *options = leveldb_readoptions_create();
139 leveldb_iterator_t *it = leveldb_create_iterator(db->conn, options);
141 leveldb_iter_seek_to_first(it);
142 if (! leveldb_iter_valid(it)) {
143 rv = 0;
144 goto exit;
147 db_key = leveldb_iter_key(it, &db_ksize);
149 if (db_key == NULL || db_ksize > *ksize) {
150 rv = 0;
151 goto exit;
154 *ksize = db_ksize;
155 memcpy(key, db_key, db_ksize);
156 rv = 1;
158 exit:
159 leveldb_readoptions_destroy(options);
160 leveldb_iter_destroy(it);
161 return rv;
165 int xleveldb_nextkey(struct db_conn *db,
166 const unsigned char *key, size_t ksize,
167 unsigned char *nextkey, size_t *nksize)
169 int rv;
170 const char *db_nextkey;
171 size_t db_nksize = 0;
173 leveldb_readoptions_t *options = leveldb_readoptions_create();
174 leveldb_iterator_t *it = leveldb_create_iterator(db->conn, options);
176 leveldb_iter_seek(it, (const char *) key, ksize);
177 if (! leveldb_iter_valid(it)) {
178 rv = 0;
179 goto exit;
182 leveldb_iter_next(it);
183 if (! leveldb_iter_valid(it)) {
184 rv = 0;
185 goto exit;
188 db_nextkey = leveldb_iter_key(it, &db_nksize);
190 if (db_nextkey == NULL || db_nksize > *nksize) {
191 rv = 0;
192 goto exit;
195 *nksize = db_nksize;
196 memcpy(nextkey, db_nextkey, db_nksize);
197 rv = 1;
199 exit:
200 leveldb_iter_destroy(it);
201 leveldb_readoptions_destroy(options);
202 return rv;
205 #else
207 #include <stddef.h> /* NULL */
209 struct db_conn *leveldb_open(const char *name, int flags)
211 return NULL;
214 #endif