Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

bplus: bp_removev, bp_removevs

bplus: update_cb and return_cb should return 0 on fail
  • Loading branch information...
commit 04885c3fe68c93865c5df57ea5349398899bc06a 1 parent d3afa02
Fedor Indutny authored
17 include/bplus.h
@@ -23,6 +23,8 @@ typedef int (*bp_compare_cb)(const bp_key_t* a, const bp_key_t* b);
23 23 typedef int (*bp_update_cb)(void* arg,
24 24 const bp_value_t* previous,
25 25 const bp_value_t* value);
  26 +typedef int (*bp_remove_cb)(void* arg,
  27 + const bp_value_t* value);
26 28 typedef void (*bp_range_cb)(void* arg,
27 29 const bp_key_t* key,
28 30 const bp_value_t* value);
@@ -61,6 +63,7 @@ int bp_sets(bp_db_t* tree,
61 63
62 64 /*
63 65 * Update or create value by key (with solving conflicts)
  66 + * **MVCC**
64 67 */
65 68 int bp_update(bp_db_t* tree,
66 69 const bp_key_t* key,
@@ -87,6 +90,7 @@ int bp_bulk_sets(bp_db_t* tree,
87 90
88 91 /*
89 92 * Update multiple values by keys
  93 + * **MVCC**
90 94 */
91 95 int bp_bulk_update(bp_db_t* tree,
92 96 const uint64_t count,
@@ -108,6 +112,19 @@ int bp_remove(bp_db_t* tree, const bp_key_t* key);
108 112 int bp_removes(bp_db_t* tree, const char* key);
109 113
110 114 /*
  115 + * Remove value by key only if it's equal to specified one
  116 + * **MVCC**
  117 + */
  118 +int bp_removev(bp_db_t* tree,
  119 + const bp_key_t* key,
  120 + bp_remove_cb remove_cb,
  121 + void *arg);
  122 +int bp_removevs(bp_db_t* tree,
  123 + const char* key,
  124 + bp_remove_cb remove_cb,
  125 + void *arg);
  126 +
  127 +/*
111 128 * Get all values in range
112 129 * Note: value will be automatically freed after invokation of callback
113 130 */
1  include/private/errors.h
@@ -22,5 +22,6 @@
22 22 #define BP_ESPLITPAGE 0x402
23 23 #define BP_EEMPTYPAGE 0x403
24 24 #define BP_EUPDATECONFLICT 0x404
  25 +#define BP_EREMOVECONFLICT 0x405
25 26
26 27 #endif /* _PRIVATE_ERRORS_H_ */
6 include/private/pages.h
@@ -79,7 +79,11 @@ int bp__page_bulk_insert(bp_db_t* t,
79 79 bp_value_t** values,
80 80 bp_update_cb update_cb,
81 81 void* arg);
82   -int bp__page_remove(bp_db_t* t, bp__page_t* page, const bp_key_t* key);
  82 +int bp__page_remove(bp_db_t* t,
  83 + bp__page_t* page,
  84 + const bp_key_t* key,
  85 + bp_remove_cb remove_cb,
  86 + void* arg);
83 87 int bp__page_copy(bp_db_t* source, bp_db_t* target, bp__page_t* page);
84 88
85 89 int bp__page_remove_idx(bp_db_t* t, bp__page_t* page, const uint64_t index);
24 src/bplus.c
@@ -156,12 +156,15 @@ int bp_bulk_set(bp_db_t* tree,
156 156 }
157 157
158 158
159   -int bp_remove(bp_db_t* tree, const bp_key_t* key) {
  159 +int bp_removev(bp_db_t* tree,
  160 + const bp_key_t* key,
  161 + bp_remove_cb remove_cb,
  162 + void *arg) {
160 163 int ret;
161 164
162 165 bp__rwlock_wrlock(&tree->rwlock);
163 166
164   - ret = bp__page_remove(tree, tree->head.page, key);
  167 + ret = bp__page_remove(tree, tree->head.page, key, remove_cb, arg);
165 168 if (ret == BP_OK) {
166 169 ret = bp__tree_write_head((bp__writer_t*) tree, NULL);
167 170 }
@@ -172,6 +175,11 @@ int bp_remove(bp_db_t* tree, const bp_key_t* key) {
172 175 }
173 176
174 177
  178 +int bp_remove(bp_db_t* tree, const bp_key_t* key) {
  179 + return bp_removev(tree, key, NULL, NULL);
  180 +}
  181 +
  182 +
175 183 int bp_compact(bp_db_t* tree) {
176 184 int ret;
177 185 char* compacted_name;
@@ -339,12 +347,20 @@ int bp_bulk_sets(bp_db_t* tree,
339 347 }
340 348
341 349
342   -int bp_removes(bp_db_t* tree, const char* key) {
  350 +int bp_removevs(bp_db_t* tree,
  351 + const char* key,
  352 + bp_remove_cb remove_cb,
  353 + void *arg) {
343 354 bp_key_t bkey;
344 355
345 356 BP__STOVAL(key, bkey);
346 357
347   - return bp_remove(tree, &bkey);
  358 + return bp_removev(tree, &bkey, remove_cb, arg);
  359 +}
  360 +
  361 +
  362 +int bp_removes(bp_db_t* tree, const char* key) {
  363 + return bp_removevs(tree, key, NULL, NULL);
348 364 }
349 365
350 366
28 src/pages.c
@@ -222,9 +222,10 @@ int bp__page_save_value(bp_db_t* t,
222 222 ret = bp__page_load_value(t, page, index, &prev_value);
223 223 if (ret != BP_OK) return ret;
224 224
225   - if (update_cb(arg, &prev_value, value) != BP_OK) {
226   - return BP_EUPDATECONFLICT;
227   - }
  225 + ret = update_cb(arg, &prev_value, value);
  226 + free(prev_value.value);
  227 +
  228 + if (!ret) return BP_EUPDATECONFLICT;
228 229 }
229 230 previous.offset = page->keys[index].offset;
230 231 previous.length = page->keys[index].config;
@@ -540,7 +541,11 @@ int bp__page_bulk_insert(bp_db_t* t,
540 541 }
541 542
542 543
543   -int bp__page_remove(bp_db_t* t, bp__page_t* page, const bp_key_t* key) {
  544 +int bp__page_remove(bp_db_t* t,
  545 + bp__page_t* page,
  546 + const bp_key_t* key,
  547 + bp_remove_cb remove_cb,
  548 + void* arg) {
544 549 int ret;
545 550 bp__page_search_res_t res;
546 551 ret = bp__page_search(t, page, key, kLoad, &res);
@@ -548,12 +553,25 @@ int bp__page_remove(bp_db_t* t, bp__page_t* page, const bp_key_t* key) {
548 553
549 554 if (res.child == NULL) {
550 555 if (res.cmp != 0) return BP_ENOTFOUND;
  556 +
  557 + /* remove only if remove_cb returns BP_OK */
  558 + if (remove_cb != NULL) {
  559 + bp_value_t prev_val;
  560 +
  561 + ret = bp__page_load_value(t, page, res.index, &prev_val);
  562 + if (ret != BP_OK) return ret;
  563 +
  564 + ret = remove_cb(arg, &prev_val);
  565 + free(prev_val.value);
  566 +
  567 + if (!ret) return BP_EREMOVECONFLICT;
  568 + }
551 569 bp__page_remove_idx(t, page, res.index);
552 570
553 571 if (page->length == 0 && !page->is_head) return BP_EEMPTYPAGE;
554 572 } else {
555 573 /* Insert kv in child page */
556   - ret = bp__page_remove(t, res.child, key);
  574 + ret = bp__page_remove(t, res.child, key, remove_cb, arg);
557 575
558 576 if (ret != BP_OK && ret != BP_EEMPTYPAGE) {
559 577 return ret;
10 test/test-api.cc
@@ -4,7 +4,12 @@ int update_cb(void* arg, const bp_value_t* previous, const bp_value_t* curr) {
4 4 char* expected = (char*) arg;
5 5 assert(strcmp(previous->value, expected) == 0);
6 6
7   - return BP_OK;
  7 + return 1;
  8 +}
  9 +
  10 +int remove_cb(void* arg, const bp_value_t* value) {
  11 + char* expected = (char*) arg;
  12 + return strcmp(value->value, expected) == 0;
8 13 }
9 14
10 15 TEST_START("API test", "api")
@@ -104,7 +109,8 @@ TEST_START("API test", "api")
104 109
105 110 for (i = 0; i < n; i++) {
106 111 sprintf(key, "some key %d", i);
107   - assert(bp_removes(&db, key) == BP_OK);
  112 + sprintf(expected, "some another value %d", i);
  113 + assert(bp_removevs(&db, key, remove_cb, (void*) expected) == BP_OK);
108 114 }
109 115
110 116 assert(bp_compact(&db) == BP_OK);
2  test/test-bulk.cc
@@ -2,7 +2,7 @@
2 2
3 3 int update_cb(void* arg, const bp_value_t* previous, const bp_value_t* curr) {
4 4 int i = (unsigned char) previous->value[5];
5   - return i % 2 == 0 ? BP_OK : 1;
  5 + return i % 2 == 0 ? 1 : 0;
6 6 }
7 7
8 8 TEST_START("bulk set test", "bulk-set")

0 comments on commit 04885c3

Please sign in to comment.
Something went wrong with that request. Please try again.