Feathercoin  0.5.0
P2P Digital Currency
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
c_test.c
Go to the documentation of this file.
1 /* Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2  Use of this source code is governed by a BSD-style license that can be
3  found in the LICENSE file. See the AUTHORS file for names of contributors. */
4 
5 #include "leveldb/c.h"
6 
7 #include <stddef.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <sys/types.h>
12 #include <unistd.h>
13 
14 const char* phase = "";
15 static char dbname[200];
16 
17 static void StartPhase(const char* name) {
18  fprintf(stderr, "=== Test %s\n", name);
19  phase = name;
20 }
21 
22 static const char* GetTempDir(void) {
23  const char* ret = getenv("TEST_TMPDIR");
24  if (ret == NULL || ret[0] == '\0')
25  ret = "/tmp";
26  return ret;
27 }
28 
29 #define CheckNoError(err) \
30  if ((err) != NULL) { \
31  fprintf(stderr, "%s:%d: %s: %s\n", __FILE__, __LINE__, phase, (err)); \
32  abort(); \
33  }
34 
35 #define CheckCondition(cond) \
36  if (!(cond)) { \
37  fprintf(stderr, "%s:%d: %s: %s\n", __FILE__, __LINE__, phase, #cond); \
38  abort(); \
39  }
40 
41 static void CheckEqual(const char* expected, const char* v, size_t n) {
42  if (expected == NULL && v == NULL) {
43  // ok
44  } else if (expected != NULL && v != NULL && n == strlen(expected) &&
45  memcmp(expected, v, n) == 0) {
46  // ok
47  return;
48  } else {
49  fprintf(stderr, "%s: expected '%s', got '%s'\n",
50  phase,
51  (expected ? expected : "(null)"),
52  (v ? v : "(null"));
53  abort();
54  }
55 }
56 
57 static void Free(char** ptr) {
58  if (*ptr) {
59  free(*ptr);
60  *ptr = NULL;
61  }
62 }
63 
64 static void CheckGet(
65  leveldb_t* db,
66  const leveldb_readoptions_t* options,
67  const char* key,
68  const char* expected) {
69  char* err = NULL;
70  size_t val_len;
71  char* val;
72  val = leveldb_get(db, options, key, strlen(key), &val_len, &err);
73  CheckNoError(err);
74  CheckEqual(expected, val, val_len);
75  Free(&val);
76 }
77 
78 static void CheckIter(leveldb_iterator_t* iter,
79  const char* key, const char* val) {
80  size_t len;
81  const char* str;
82  str = leveldb_iter_key(iter, &len);
83  CheckEqual(key, str, len);
84  str = leveldb_iter_value(iter, &len);
85  CheckEqual(val, str, len);
86 }
87 
88 // Callback from leveldb_writebatch_iterate()
89 static void CheckPut(void* ptr,
90  const char* k, size_t klen,
91  const char* v, size_t vlen) {
92  int* state = (int*) ptr;
93  CheckCondition(*state < 2);
94  switch (*state) {
95  case 0:
96  CheckEqual("bar", k, klen);
97  CheckEqual("b", v, vlen);
98  break;
99  case 1:
100  CheckEqual("box", k, klen);
101  CheckEqual("c", v, vlen);
102  break;
103  }
104  (*state)++;
105 }
106 
107 // Callback from leveldb_writebatch_iterate()
108 static void CheckDel(void* ptr, const char* k, size_t klen) {
109  int* state = (int*) ptr;
110  CheckCondition(*state == 2);
111  CheckEqual("bar", k, klen);
112  (*state)++;
113 }
114 
115 static void CmpDestroy(void* arg) { }
116 
117 static int CmpCompare(void* arg, const char* a, size_t alen,
118  const char* b, size_t blen) {
119  int n = (alen < blen) ? alen : blen;
120  int r = memcmp(a, b, n);
121  if (r == 0) {
122  if (alen < blen) r = -1;
123  else if (alen > blen) r = +1;
124  }
125  return r;
126 }
127 
128 static const char* CmpName(void* arg) {
129  return "foo";
130 }
131 
132 // Custom filter policy
133 static unsigned char fake_filter_result = 1;
134 static void FilterDestroy(void* arg) { }
135 static const char* FilterName(void* arg) {
136  return "TestFilter";
137 }
138 static char* FilterCreate(
139  void* arg,
140  const char* const* key_array, const size_t* key_length_array,
141  int num_keys,
142  size_t* filter_length) {
143  *filter_length = 4;
144  char* result = malloc(4);
145  memcpy(result, "fake", 4);
146  return result;
147 }
148 unsigned char FilterKeyMatch(
149  void* arg,
150  const char* key, size_t length,
151  const char* filter, size_t filter_length) {
152  CheckCondition(filter_length == 4);
153  CheckCondition(memcmp(filter, "fake", 4) == 0);
154  return fake_filter_result;
155 }
156 
157 int main(int argc, char** argv) {
158  leveldb_t* db;
160  leveldb_cache_t* cache;
161  leveldb_env_t* env;
162  leveldb_options_t* options;
163  leveldb_readoptions_t* roptions;
164  leveldb_writeoptions_t* woptions;
165  char* err = NULL;
166  int run = -1;
167 
170 
171  snprintf(dbname, sizeof(dbname),
172  "%s/leveldb_c_test-%d",
173  GetTempDir(),
174  ((int) geteuid()));
175 
176  StartPhase("create_objects");
177  cmp = leveldb_comparator_create(NULL, CmpDestroy, CmpCompare, CmpName);
179  cache = leveldb_cache_create_lru(100000);
180 
181  options = leveldb_options_create();
182  leveldb_options_set_comparator(options, cmp);
184  leveldb_options_set_cache(options, cache);
185  leveldb_options_set_env(options, env);
186  leveldb_options_set_info_log(options, NULL);
187  leveldb_options_set_write_buffer_size(options, 100000);
190  leveldb_options_set_block_size(options, 1024);
193 
194  roptions = leveldb_readoptions_create();
197 
198  woptions = leveldb_writeoptions_create();
199  leveldb_writeoptions_set_sync(woptions, 1);
200 
201  StartPhase("destroy");
202  leveldb_destroy_db(options, dbname, &err);
203  Free(&err);
204 
205  StartPhase("open_error");
206  db = leveldb_open(options, dbname, &err);
207  CheckCondition(err != NULL);
208  Free(&err);
209 
210  StartPhase("leveldb_free");
211  db = leveldb_open(options, dbname, &err);
212  CheckCondition(err != NULL);
213  leveldb_free(err);
214  err = NULL;
215 
216  StartPhase("open");
218  db = leveldb_open(options, dbname, &err);
219  CheckNoError(err);
220  CheckGet(db, roptions, "foo", NULL);
221 
222  StartPhase("put");
223  leveldb_put(db, woptions, "foo", 3, "hello", 5, &err);
224  CheckNoError(err);
225  CheckGet(db, roptions, "foo", "hello");
226 
227  StartPhase("compactall");
228  leveldb_compact_range(db, NULL, 0, NULL, 0);
229  CheckGet(db, roptions, "foo", "hello");
230 
231  StartPhase("compactrange");
232  leveldb_compact_range(db, "a", 1, "z", 1);
233  CheckGet(db, roptions, "foo", "hello");
234 
235  StartPhase("writebatch");
236  {
238  leveldb_writebatch_put(wb, "foo", 3, "a", 1);
240  leveldb_writebatch_put(wb, "bar", 3, "b", 1);
241  leveldb_writebatch_put(wb, "box", 3, "c", 1);
242  leveldb_writebatch_delete(wb, "bar", 3);
243  leveldb_write(db, woptions, wb, &err);
244  CheckNoError(err);
245  CheckGet(db, roptions, "foo", "hello");
246  CheckGet(db, roptions, "bar", NULL);
247  CheckGet(db, roptions, "box", "c");
248  int pos = 0;
249  leveldb_writebatch_iterate(wb, &pos, CheckPut, CheckDel);
250  CheckCondition(pos == 3);
252  }
253 
254  StartPhase("iter");
255  {
256  leveldb_iterator_t* iter = leveldb_create_iterator(db, roptions);
260  CheckIter(iter, "box", "c");
261  leveldb_iter_next(iter);
262  CheckIter(iter, "foo", "hello");
263  leveldb_iter_prev(iter);
264  CheckIter(iter, "box", "c");
265  leveldb_iter_prev(iter);
268  CheckIter(iter, "foo", "hello");
269  leveldb_iter_seek(iter, "b", 1);
270  CheckIter(iter, "box", "c");
271  leveldb_iter_get_error(iter, &err);
272  CheckNoError(err);
273  leveldb_iter_destroy(iter);
274  }
275 
276  StartPhase("approximate_sizes");
277  {
278  int i;
279  int n = 20000;
280  char keybuf[100];
281  char valbuf[100];
282  uint64_t sizes[2];
283  const char* start[2] = { "a", "k00000000000000010000" };
284  size_t start_len[2] = { 1, 21 };
285  const char* limit[2] = { "k00000000000000010000", "z" };
286  size_t limit_len[2] = { 21, 1 };
287  leveldb_writeoptions_set_sync(woptions, 0);
288  for (i = 0; i < n; i++) {
289  snprintf(keybuf, sizeof(keybuf), "k%020d", i);
290  snprintf(valbuf, sizeof(valbuf), "v%020d", i);
291  leveldb_put(db, woptions, keybuf, strlen(keybuf), valbuf, strlen(valbuf),
292  &err);
293  CheckNoError(err);
294  }
295  leveldb_approximate_sizes(db, 2, start, start_len, limit, limit_len, sizes);
296  CheckCondition(sizes[0] > 0);
297  CheckCondition(sizes[1] > 0);
298  }
299 
300  StartPhase("property");
301  {
302  char* prop = leveldb_property_value(db, "nosuchprop");
303  CheckCondition(prop == NULL);
304  prop = leveldb_property_value(db, "leveldb.stats");
305  CheckCondition(prop != NULL);
306  Free(&prop);
307  }
308 
309  StartPhase("snapshot");
310  {
311  const leveldb_snapshot_t* snap;
312  snap = leveldb_create_snapshot(db);
313  leveldb_delete(db, woptions, "foo", 3, &err);
314  CheckNoError(err);
315  leveldb_readoptions_set_snapshot(roptions, snap);
316  CheckGet(db, roptions, "foo", "hello");
317  leveldb_readoptions_set_snapshot(roptions, NULL);
318  CheckGet(db, roptions, "foo", NULL);
319  leveldb_release_snapshot(db, snap);
320  }
321 
322  StartPhase("repair");
323  {
324  leveldb_close(db);
327  leveldb_repair_db(options, dbname, &err);
328  CheckNoError(err);
329  db = leveldb_open(options, dbname, &err);
330  CheckNoError(err);
331  CheckGet(db, roptions, "foo", NULL);
332  CheckGet(db, roptions, "bar", NULL);
333  CheckGet(db, roptions, "box", "c");
336  }
337 
338  StartPhase("filter");
339  for (run = 0; run < 2; run++) {
340  // First run uses custom filter, second run uses bloom filter
341  CheckNoError(err);
342  leveldb_filterpolicy_t* policy;
343  if (run == 0) {
345  NULL, FilterDestroy, FilterCreate, FilterKeyMatch, FilterName);
346  } else {
348  }
349 
350  // Create new database
351  leveldb_close(db);
352  leveldb_destroy_db(options, dbname, &err);
353  leveldb_options_set_filter_policy(options, policy);
354  db = leveldb_open(options, dbname, &err);
355  CheckNoError(err);
356  leveldb_put(db, woptions, "foo", 3, "foovalue", 8, &err);
357  CheckNoError(err);
358  leveldb_put(db, woptions, "bar", 3, "barvalue", 8, &err);
359  CheckNoError(err);
360  leveldb_compact_range(db, NULL, 0, NULL, 0);
361 
362  fake_filter_result = 1;
363  CheckGet(db, roptions, "foo", "foovalue");
364  CheckGet(db, roptions, "bar", "barvalue");
365  if (phase == 0) {
366  // Must not find value when custom filter returns false
367  fake_filter_result = 0;
368  CheckGet(db, roptions, "foo", NULL);
369  CheckGet(db, roptions, "bar", NULL);
370  fake_filter_result = 1;
371 
372  CheckGet(db, roptions, "foo", "foovalue");
373  CheckGet(db, roptions, "bar", "barvalue");
374  }
375  leveldb_options_set_filter_policy(options, NULL);
377  }
378 
379  StartPhase("cleanup");
380  leveldb_close(db);
381  leveldb_options_destroy(options);
382  leveldb_readoptions_destroy(roptions);
384  leveldb_cache_destroy(cache);
386  leveldb_env_destroy(env);
387 
388  fprintf(stderr, "PASS\n");
389  return 0;
390 }
void leveldb_writebatch_clear(leveldb_writebatch_t *b)
Definition: c.cc:345
void leveldb_options_set_cache(leveldb_options_t *opt, leveldb_cache_t *c)
Definition: c.cc:437
void leveldb_options_set_paranoid_checks(leveldb_options_t *opt, unsigned char v)
Definition: c.cc:416
char * leveldb_get(leveldb_t *db, const leveldb_readoptions_t *options, const char *key, size_t keylen, size_t *vallen, char **errptr)
Definition: c.cc:197
void leveldb_cache_destroy(leveldb_cache_t *cache)
Definition: c.cc:566
void leveldb_iter_seek_to_last(leveldb_iterator_t *iter)
Definition: c.cc:305
void leveldb_options_set_block_restart_interval(leveldb_options_t *opt, int n)
Definition: c.cc:445
int leveldb_minor_version()
Definition: c.cc:591
void leveldb_release_snapshot(leveldb_t *db, const leveldb_snapshot_t *snapshot)
Definition: c.cc:233
unsigned char FilterKeyMatch(void *arg, const char *key, size_t length, const char *filter, size_t filter_length)
Definition: c_test.c:148
bool start
Definition: db_bench.cc:282
const char * leveldb_iter_key(const leveldb_iterator_t *iter, size_t *klen)
Definition: c.cc:321
void leveldb_iter_prev(leveldb_iterator_t *iter)
Definition: c.cc:317
int leveldb_major_version()
Definition: c.cc:587
void leveldb_options_set_create_if_missing(leveldb_options_t *opt, unsigned char v)
Definition: c.cc:406
Definition: c.cc:46
void leveldb_destroy_db(const leveldb_options_t *options, const char *name, char **errptr)
Definition: c.cc:278
void leveldb_options_set_filter_policy(leveldb_options_t *opt, leveldb_filterpolicy_t *policy)
Definition: c.cc:400
leveldb_writebatch_t * leveldb_writebatch_create()
Definition: c.cc:337
void leveldb_iter_next(leveldb_iterator_t *iter)
Definition: c.cc:313
leveldb_comparator_t * leveldb_comparator_create(void *state, void(*destructor)(void *), int(*compare)(void *, const char *a, size_t alen, const char *b, size_t blen), const char *(*name)(void *))
Definition: c.cc:453
void leveldb_put(leveldb_t *db, const leveldb_writeoptions_t *options, const char *key, size_t keylen, const char *val, size_t vallen, char **errptr)
Definition: c.cc:170
leveldb_readoptions_t * leveldb_readoptions_create()
Definition: c.cc:522
void leveldb_write(leveldb_t *db, const leveldb_writeoptions_t *options, leveldb_writebatch_t *batch, char **errptr)
Definition: c.cc:189
void leveldb_iter_get_error(const leveldb_iterator_t *iter, char **errptr)
Definition: c.cc:333
void leveldb_options_destroy(leveldb_options_t *options)
Definition: c.cc:390
void leveldb_writebatch_destroy(leveldb_writebatch_t *b)
Definition: c.cc:341
const leveldb_snapshot_t * leveldb_create_snapshot(leveldb_t *db)
Definition: c.cc:226
void leveldb_writebatch_delete(leveldb_writebatch_t *b, const char *key, size_t klen)
Definition: c.cc:356
char * leveldb_property_value(leveldb_t *db, const char *propname)
Definition: c.cc:240
void leveldb_iter_destroy(leveldb_iterator_t *iter)
Definition: c.cc:292
void leveldb_iter_seek_to_first(leveldb_iterator_t *iter)
Definition: c.cc:301
unsigned long long uint64_t
Definition: stdint.h:22
void leveldb_free(void *ptr)
Definition: c.cc:583
leveldb_writeoptions_t * leveldb_writeoptions_create()
Definition: c.cc:547
MTState * state
Definition: db_test.cc:1708
leveldb_env_t * leveldb_create_default_env()
Definition: c.cc:571
void leveldb_writebatch_put(leveldb_writebatch_t *b, const char *key, size_t klen, const char *val, size_t vlen)
Definition: c.cc:349
unsigned char leveldb_iter_valid(const leveldb_iterator_t *iter)
Definition: c.cc:297
void leveldb_options_set_comparator(leveldb_options_t *opt, leveldb_comparator_t *cmp)
Definition: c.cc:394
void leveldb_options_set_max_open_files(leveldb_options_t *opt, int n)
Definition: c.cc:433
const char * leveldb_iter_value(const leveldb_iterator_t *iter, size_t *vlen)
Definition: c.cc:327
void leveldb_compact_range(leveldb_t *db, const char *start_key, size_t start_key_len, const char *limit_key, size_t limit_key_len)
Definition: c.cc:267
void leveldb_options_set_error_if_exists(leveldb_options_t *opt, unsigned char v)
Definition: c.cc:411
#define CheckCondition(cond)
Definition: c_test.c:35
void leveldb_close(leveldb_t *db)
Definition: c.cc:165
void leveldb_options_set_info_log(leveldb_options_t *opt, leveldb_logger_t *l)
Definition: c.cc:425
leveldb_filterpolicy_t * leveldb_filterpolicy_create(void *state, void(*destructor)(void *), char *(*create_filter)(void *, const char *const *key_array, const size_t *key_length_array, int num_keys, size_t *filter_length), unsigned char(*key_may_match)(void *, const char *key, size_t length, const char *filter, size_t filter_length), const char *(*name)(void *))
Definition: c.cc:473
void leveldb_readoptions_set_snapshot(leveldb_readoptions_t *opt, const leveldb_snapshot_t *snap)
Definition: c.cc:541
void leveldb_options_set_compression(leveldb_options_t *opt, int t)
Definition: c.cc:449
void leveldb_filterpolicy_destroy(leveldb_filterpolicy_t *filter)
Definition: c.cc:495
#define CheckNoError(err)
Definition: c_test.c:29
void leveldb_delete(leveldb_t *db, const leveldb_writeoptions_t *options, const char *key, size_t keylen, char **errptr)
Definition: c.cc:180
leveldb_filterpolicy_t * leveldb_filterpolicy_create_bloom(int bits_per_key)
Definition: c.cc:499
const Comparator * cmp
Definition: table_test.cc:80
const char * phase
Definition: c_test.c:14
leveldb_options_t * leveldb_options_create()
Definition: c.cc:386
void leveldb_iter_seek(leveldb_iterator_t *iter, const char *k, size_t klen)
Definition: c.cc:309
void leveldb_env_destroy(leveldb_env_t *env)
Definition: c.cc:578
void leveldb_readoptions_destroy(leveldb_readoptions_t *opt)
Definition: c.cc:526
void leveldb_readoptions_set_verify_checksums(leveldb_readoptions_t *opt, unsigned char v)
Definition: c.cc:530
void leveldb_approximate_sizes(leveldb_t *db, int num_ranges, const char *const *range_start_key, const size_t *range_start_key_len, const char *const *range_limit_key, const size_t *range_limit_key_len, uint64_t *sizes)
Definition: c.cc:252
void leveldb_comparator_destroy(leveldb_comparator_t *cmp)
Definition: c.cc:469
void leveldb_writeoptions_destroy(leveldb_writeoptions_t *opt)
Definition: c.cc:551
void leveldb_options_set_env(leveldb_options_t *opt, leveldb_env_t *env)
Definition: c.cc:421
void leveldb_readoptions_set_fill_cache(leveldb_readoptions_t *opt, unsigned char v)
Definition: c.cc:536
void leveldb_options_set_write_buffer_size(leveldb_options_t *opt, size_t s)
Definition: c.cc:429
leveldb_iterator_t * leveldb_create_iterator(leveldb_t *db, const leveldb_readoptions_t *options)
Definition: c.cc:218
leveldb_cache_t * leveldb_cache_create_lru(size_t capacity)
Definition: c.cc:560
void leveldb_writeoptions_set_sync(leveldb_writeoptions_t *opt, unsigned char v)
Definition: c.cc:555
leveldb_t * leveldb_open(const leveldb_options_t *options, const char *name, char **errptr)
Definition: c.cc:152
void * arg
Definition: env_posix.cc:716
const char * name
Definition: testharness.cc:18
void leveldb_repair_db(const leveldb_options_t *options, const char *name, char **errptr)
Definition: c.cc:285
void leveldb_options_set_block_size(leveldb_options_t *opt, size_t s)
Definition: c.cc:441
void leveldb_writebatch_iterate(leveldb_writebatch_t *b, void *state, void(*put)(void *, const char *k, size_t klen, const char *v, size_t vlen), void(*deleted)(void *, const char *k, size_t klen))
Definition: c.cc:362
int main(int argc, char **argv)
Definition: c_test.c:157