Commit 5ad53816 authored by Yoni Fogel's avatar Yoni Fogel

Addresses #293

Updated code based on review,
updated Makefile

git-svn-id: file:///svn/tokudb@2018 c7de825b-a66e-492c-adef-691d508d4ae1
parent 35b35f73
...@@ -3,18 +3,29 @@ ...@@ -3,18 +3,29 @@
LIBNAME=liblocktree LIBNAME=liblocktree
OPTFLAGS = -O0 ifneq ($(OPT),)
ifeq ($(GCOV),GCOV) OPTFLAGS = -O4
else
OPTFLAGS = -O0 -g3 -ggdb3
endif
ifneq ($(GCOV),)
GCOV_FLAGS = -fprofile-arcs -ftest-coverage GCOV_FLAGS = -fprofile-arcs -ftest-coverage
else else
GCOV_FLAGS = GCOV_FLAGS =
endif endif
CFLAGS = -W -Wall -Werror -g3 -ggdb3 -fPIC $(OPTFLAGS) $(GCOV_FLAGS) CFLAGS = -W -Wall -Werror -fPIC $(OPTFLAGS) $(GCOV_FLAGS)
CFLAGS += -Wbad-function-cast -Wcast-align -Wconversion -Waggregate-return
CFLAGS += -Wmissing-noreturn -Wmissing-format-attribute
ifneq ($(W),)
CFLAGS+= -Wunreachable-code
endif
CPPFLAGS = -I. -I.. -I../range_tree -I../../include -I../../newbrt -L../range_tree CPPFLAGS = -I. -I.. -I../range_tree -I../../include -I../../newbrt -L../range_tree
CPPFLAGS += -D_GNU_SOURCE -D_THREAD_SAFE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE CPPFLAGS += -D_GNU_SOURCE -D_THREAD_SAFE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
ifeq ($(OSX),OSX)
ifneq ($(OSX),)
LIBEXT=dylib LIBEXT=dylib
SHARED=-dynamiclib SHARED=-dynamiclib
CFLAGS+=-fno-common CFLAGS+=-fno-common
......
...@@ -31,12 +31,16 @@ static int __toku_infinite_compare(void* a, void* b) { ...@@ -31,12 +31,16 @@ static int __toku_infinite_compare(void* a, void* b) {
if (a == toku_lt_infinity) return 1; if (a == toku_lt_infinity) return 1;
if (b == toku_lt_infinity) return -1; if (b == toku_lt_infinity) return -1;
if (a == toku_lt_neg_infinity) return -1; if (a == toku_lt_neg_infinity) return -1;
assert(b == toku_lt_neg_infinity); assert(b == toku_lt_neg_infinity); return 1;
return 1;
} }
static BOOL __toku_lt_is_infinite(const void* p) { static BOOL __toku_lt_is_infinite(const void* p) {
return (p == toku_lt_infinity) || (p == toku_lt_neg_infinity); if (p == toku_lt_infinity || p == toku_lt_neg_infinity) {
DBT* dbt = (DBT*)p;
assert(!dbt->data && !dbt->size);
return TRUE;
}
return FALSE;
} }
/* Verifies that NULL data and size are consistent. /* Verifies that NULL data and size are consistent.
...@@ -91,7 +95,7 @@ int toku_lt_point_cmp(void* a, void* b) { ...@@ -91,7 +95,7 @@ int toku_lt_point_cmp(void* a, void* b) {
__toku_recreate_DBT(&point_2, y->data_payload, y->data_len)); __toku_recreate_DBT(&point_2, y->data_payload, y->data_len));
} }
static int __toku_p_free(toku_lock_tree* tree, toku_point* point) { static void __toku_p_free(toku_lock_tree* tree, toku_point* point) {
assert(point); assert(point);
tree->payload_used -= point->key_len; tree->payload_used -= point->key_len;
tree->payload_used -= point->data_len; tree->payload_used -= point->data_len;
...@@ -103,7 +107,6 @@ static int __toku_p_free(toku_lock_tree* tree, toku_point* point) { ...@@ -103,7 +107,6 @@ static int __toku_p_free(toku_lock_tree* tree, toku_point* point) {
tree->free(point->data_payload); tree->free(point->data_payload);
} }
tree->free(point); tree->free(point);
return 0;
} }
/* /*
...@@ -372,7 +375,7 @@ static int __toku_lt_meets_peer(toku_lock_tree* tree, toku_range* query, ...@@ -372,7 +375,7 @@ static int __toku_lt_meets_peer(toku_lock_tree* tree, toku_range* query,
r = toku_rt_find(rt, query, 2, &buf, &buflen, &numfound); r = toku_rt_find(rt, query, 2, &buf, &buflen, &numfound);
if (r!=0) return r; if (r!=0) return r;
assert(numfound <= 2); assert(numfound <= 2);
*met = numfound == 2 || (numfound == 1 && buf[0].data != txn); *met = numfound == 2 || (numfound == 1 && buf[0].data != self);
return 0; return 0;
} }
...@@ -385,9 +388,7 @@ static int __toku_lt_check_borderwrite_conflict(toku_lock_tree* tree, ...@@ -385,9 +388,7 @@ static int __toku_lt_check_borderwrite_conflict(toku_lock_tree* tree,
assert(tree && txn && query); assert(tree && txn && query);
toku_conflict conflict; toku_conflict conflict;
DB_TXN* peer; DB_TXN* peer;
toku_range_tree* borderwrite = tree->borderwrite;
toku_range_tree* peer_selfwrite; toku_range_tree* peer_selfwrite;
assert(borderwrite);
int r; int r;
r = __toku_lt_borderwrite_conflict(tree, txn, query, &conflict, &peer); r = __toku_lt_borderwrite_conflict(tree, txn, query, &conflict, &peer);
...@@ -395,7 +396,7 @@ static int __toku_lt_check_borderwrite_conflict(toku_lock_tree* tree, ...@@ -395,7 +396,7 @@ static int __toku_lt_check_borderwrite_conflict(toku_lock_tree* tree,
if (conflict == TOKU_MAYBE_CONFLICT) { if (conflict == TOKU_MAYBE_CONFLICT) {
assert(peer); assert(peer);
peer_selfwrite = __toku_lt_ifexist_selfwrite(tree, peer); peer_selfwrite = __toku_lt_ifexist_selfwrite(tree, peer);
assert(peer_selfwrite); if (!peer_selfwrite) return __toku_lt_panic(tree);
BOOL met; BOOL met;
r = __toku_lt_meets(tree, query, peer_selfwrite, &met); r = __toku_lt_meets(tree, query, peer_selfwrite, &met);
...@@ -461,7 +462,7 @@ static void __toku_init_insert(toku_range* to_insert, ...@@ -461,7 +462,7 @@ static void __toku_init_insert(toku_range* to_insert,
to_insert->data = txn; to_insert->data = txn;
} }
static void __toku_lt_extend_extreme(toku_lock_tree* tree,toku_range* to_insert, static int __toku_lt_extend_extreme(toku_lock_tree* tree,toku_range* to_insert,
BOOL* alloc_left, BOOL* alloc_right, BOOL* alloc_left, BOOL* alloc_right,
unsigned numfound) { unsigned numfound) {
assert(to_insert && tree && alloc_left && alloc_right); assert(to_insert && tree && alloc_left && alloc_right);
...@@ -471,24 +472,27 @@ static void __toku_lt_extend_extreme(toku_lock_tree* tree,toku_range* to_insert, ...@@ -471,24 +472,27 @@ static void __toku_lt_extend_extreme(toku_lock_tree* tree,toku_range* to_insert,
/* Find the extreme left end-point among overlapping ranges */ /* Find the extreme left end-point among overlapping ranges */
if ((c = toku_lt_point_cmp(tree->buf[i].left, to_insert->left)) if ((c = toku_lt_point_cmp(tree->buf[i].left, to_insert->left))
<= 0) { <= 0) {
assert(*alloc_left || c < 0); if (!(*alloc_left || c < 0) ||
assert(tree->buf[i].left != to_insert->left); !(tree->buf[i].left != to_insert->left) ||
assert(tree->buf[i].left != to_insert->right); !(tree->buf[i].left != to_insert->right)) {
return __toku_lt_panic(tree); }
*alloc_left = FALSE; *alloc_left = FALSE;
to_insert->left = tree->buf[i].left; to_insert->left = tree->buf[i].left;
} }
/* Find the extreme right end-point */ /* Find the extreme right end-point */
if ((c = toku_lt_point_cmp(tree->buf[i].right, to_insert->right)) if ((c = toku_lt_point_cmp(tree->buf[i].right, to_insert->right))
>= 0) { >= 0) {
assert(*alloc_right || c > 0); if (!(*alloc_right || c > 0) ||
assert(tree->buf[i].right != to_insert->left || !(tree->buf[i].right != to_insert->left ||
(tree->buf[i].left == to_insert->left && (tree->buf[i].left == to_insert->left &&
tree->buf[i].left == tree->buf[i].right)); tree->buf[i].left == tree->buf[i].right)) ||
assert(tree->buf[i].right != to_insert->right); !(tree->buf[i].right != to_insert->right)) {
return __toku_lt_panic(tree); }
*alloc_right = FALSE; *alloc_right = FALSE;
to_insert->right = tree->buf[i].right; to_insert->right = tree->buf[i].right;
} }
} }
return 0;
} }
static int __toku_lt_alloc_extreme(toku_lock_tree* tree, toku_range* to_insert, static int __toku_lt_alloc_extreme(toku_lock_tree* tree, toku_range* to_insert,
...@@ -524,16 +528,18 @@ static int __toku_lt_alloc_extreme(toku_lock_tree* tree, toku_range* to_insert, ...@@ -524,16 +528,18 @@ static int __toku_lt_alloc_extreme(toku_lock_tree* tree, toku_range* to_insert,
return 0; return 0;
} }
static void __toku_lt_delete_overlapping_ranges(toku_lock_tree* tree, static int __toku_lt_delete_overlapping_ranges(toku_lock_tree* tree,
toku_range_tree* rt, toku_range_tree* rt,
unsigned numfound) { unsigned numfound) {
assert(tree && rt); assert(tree && rt);
int r; int r;
unsigned i; unsigned i;
assert(numfound <= tree->buflen);
for (i = 0; i < numfound; i++) { for (i = 0; i < numfound; i++) {
r = toku_rt_delete(rt, &tree->buf[i]); r = toku_rt_delete(rt, &tree->buf[i]);
if (r!=0) return __toku_lt_panic(tree, r); if (r!=0) return r;
} }
return 0;
} }
/* Returns whether the point already exists /* Returns whether the point already exists
...@@ -546,6 +552,7 @@ static BOOL __toku_lt_p_independent(toku_point* point, toku_range* range) { ...@@ -546,6 +552,7 @@ static BOOL __toku_lt_p_independent(toku_point* point, toku_range* range) {
static void __toku_lt_free_points(toku_lock_tree* tree, toku_range* to_insert, static void __toku_lt_free_points(toku_lock_tree* tree, toku_range* to_insert,
unsigned numfound) { unsigned numfound) {
assert(tree && to_insert); assert(tree && to_insert);
assert(numfound <= tree->buflen);
unsigned i; unsigned i;
for (i = 0; i < numfound; i++) { for (i = 0; i < numfound; i++) {
...@@ -587,6 +594,7 @@ static int __toku_consolidate(toku_lock_tree* tree, ...@@ -587,6 +594,7 @@ static int __toku_consolidate(toku_lock_tree* tree,
r = toku_rt_find(selfread, query, 0, &tree->buf, &tree->buflen, r = toku_rt_find(selfread, query, 0, &tree->buf, &tree->buflen,
&numfound); &numfound);
if (r!=0) return r; if (r!=0) return r;
assert(numfound <= tree->buflen);
/* Find the extreme left and right point of the consolidated interval */ /* Find the extreme left and right point of the consolidated interval */
__toku_lt_extend_extreme(tree, to_insert, &alloc_left, &alloc_right, __toku_lt_extend_extreme(tree, to_insert, &alloc_left, &alloc_right,
...@@ -602,12 +610,16 @@ static int __toku_consolidate(toku_lock_tree* tree, ...@@ -602,12 +610,16 @@ static int __toku_consolidate(toku_lock_tree* tree,
} }
if (r!=0) return r; if (r!=0) return r;
/* From this point on we have to panic if we cannot finish. */
/* Delete overlapping ranges from selfread ... */ /* Delete overlapping ranges from selfread ... */
__toku_lt_delete_overlapping_ranges(tree, selfread, numfound); r = __toku_lt_delete_overlapping_ranges(tree, selfread, numfound);
if (r!=0) return __toku_lt_panic(tree);
/* ... and mainread. /* ... and mainread.
Growth direction: if we had no overlaps, the next line Growth direction: if we had no overlaps, the next line
should be commented out */ should be commented out */
__toku_lt_delete_overlapping_ranges(tree, mainread, numfound); r = __toku_lt_delete_overlapping_ranges(tree, mainread, numfound);
if (r!=0) return __toku_lt_panic(tree);
/* Free all the points from ranges in tree->buf[0]..tree->buf[numfound-1] */ /* Free all the points from ranges in tree->buf[0]..tree->buf[numfound-1] */
__toku_lt_free_points(tree, to_insert, numfound); __toku_lt_free_points(tree, to_insert, numfound);
...@@ -618,11 +630,12 @@ static int __toku_consolidate(toku_lock_tree* tree, ...@@ -618,11 +630,12 @@ static int __toku_consolidate(toku_lock_tree* tree,
if (0) { if (0) {
died2: died2:
r2 = toku_rt_delete(selfread, to_insert); r2 = toku_rt_delete(selfread, to_insert);
if (r2!=0) return __toku_lt_panic(tree, r); if (r2!=0) return __toku_lt_panic(tree);
goto died1; goto died1;
} }
if (r!=0) { if (r!=0) {
if (numfound) r = __toku_lt_panic(tree, r); /* If we deleted/merged anything, this is a panic situation. */
if (numfound) return __toku_lt_panic(tree);
goto died1; goto died1;
} }
assert(tree->mainread); assert(tree->mainread);
...@@ -630,15 +643,16 @@ static int __toku_consolidate(toku_lock_tree* tree, ...@@ -630,15 +643,16 @@ static int __toku_consolidate(toku_lock_tree* tree,
/* Insert extreme range into mainread. */ /* Insert extreme range into mainread. */
r = toku_rt_insert(tree->mainread, to_insert); r = toku_rt_insert(tree->mainread, to_insert);
if (r!=0) { if (r!=0) {
if (numfound) r = __toku_lt_panic(tree, r); /* If we deleted/merged anything, this is a panic situation. */
if (numfound) return __toku_lt_panic(tree);
goto died2; goto died2;
} }
return 0; return 0;
} }
static void __toku_lt_free_contents(toku_lock_tree* tree, toku_range_tree* rt) { static int __toku_lt_free_contents(toku_lock_tree* tree, toku_range_tree* rt) {
assert(tree); assert(tree);
if (!rt) return; if (!rt) return 0;
int r; int r;
...@@ -664,17 +678,18 @@ static void __toku_lt_free_contents(toku_lock_tree* tree, toku_range_tree* rt) { ...@@ -664,17 +678,18 @@ static void __toku_lt_free_contents(toku_lock_tree* tree, toku_range_tree* rt) {
do { do {
r = toku_rt_find(rt, &query, 1, &tree->buf, &tree->buflen, r = toku_rt_find(rt, &query, 1, &tree->buf, &tree->buflen,
&numfound); &numfound);
if (r!=0) return __toku_lt_panic(tree, r); if (r!=0) return __toku_lt_panic(tree);
if (!numfound) break; if (!numfound) break;
assert(numfound == 1); assert(numfound == 1);
r = toku_rt_delete(rt, &tree->buf[0]); r = toku_rt_delete(rt, &tree->buf[0]);
if (r!=0) return __toku_lt_panic(tree, r); if (r!=0) return r;
__toku_lt_free_points(tree, &query, numfound); __toku_lt_free_points(tree, &query, numfound);
} while (TRUE); } while (TRUE);
} }
else __toku_lt_panic(tree, r); else return r;
r = toku_rt_close(rt); r = toku_rt_close(rt);
assert(r == 0); if (r!=0) return r;
return 0;
} }
int toku_lt_create(toku_lock_tree** ptree, DB* db, BOOL duplicates, int toku_lt_create(toku_lock_tree** ptree, DB* db, BOOL duplicates,
...@@ -690,71 +705,60 @@ int toku_lt_create(toku_lock_tree** ptree, DB* db, BOOL duplicates, ...@@ -690,71 +705,60 @@ int toku_lt_create(toku_lock_tree** ptree, DB* db, BOOL duplicates,
} }
int r; int r;
toku_lock_tree* temp_tree =(toku_lock_tree*)user_malloc(sizeof(*temp_tree)); toku_lock_tree* tmp_tree = (toku_lock_tree*)user_malloc(sizeof(*tmp_tree));
if (0) { if (0) { died1: user_free(tmp_tree); return r; }
died1: if (!tmp_tree) return errno;
user_free(temp_tree); memset(tmp_tree, 0, sizeof(*toku_lock_tree));
return r; tmp_tree->db = db;
} tmp_tree->duplicates = duplicates;
if (!temp_tree) return errno; tmp_tree->panic = panic;
memset(temp_tree, 0, sizeof(*temp_tree)); tmp_tree->payload_capacity = payload_capacity;
temp_tree->db = db; tmp_tree->compare_fun = compare_fun;
temp_tree->duplicates = duplicates; tmp_tree->dup_compare = dup_compare;
temp_tree->panic = panic; tmp_tree->malloc = user_malloc;
temp_tree->payload_capacity = payload_capacity; tmp_tree->free = user_free;
temp_tree->compare_fun = compare_fun; tmp_tree->realloc = user_realloc;
temp_tree->dup_compare = dup_compare; r = toku_rt_create(&tmp_tree->mainread,
temp_tree->malloc = user_malloc;
temp_tree->free = user_free;
temp_tree->realloc = user_realloc;
r = toku_rt_create(&temp_tree->mainread,
toku_lt_point_cmp, __toku_lt_txn_cmp, TRUE, toku_lt_point_cmp, __toku_lt_txn_cmp, TRUE,
user_malloc, user_free, user_realloc); user_malloc, user_free, user_realloc);
if (0) { if (0) { died2: toku_rt_close(tmp_tree->mainread); goto died1; }
died2:
toku_rt_close(temp_tree->mainread);
goto died1;
}
if (r!=0) goto died1; if (r!=0) goto died1;
r = toku_rt_create(&temp_tree->borderwrite, r = toku_rt_create(&tmp_tree->borderwrite,
toku_lt_point_cmp, __toku_lt_txn_cmp, FALSE, toku_lt_point_cmp, __toku_lt_txn_cmp, FALSE,
user_malloc, user_free, user_realloc); user_malloc, user_free, user_realloc);
if (0) { if (0) { died3: toku_rt_close(tmp_tree->borderwrite); goto died2; }
died3:
toku_rt_close(temp_tree->borderwrite);
goto died2;
}
if (r!=0) goto died2; if (r!=0) goto died2;
tmp_tree->buflen = __toku_default_buflen;
temp_tree->buflen = __toku_default_buflen; tmp_tree->buf = (toku_range*)
temp_tree->buf = (toku_range*) user_malloc(tmp_tree->buflen * sizeof(toku_range));
user_malloc(temp_tree->buflen * sizeof(toku_range)); if (!tmp_tree->buf) { r = errno; goto died3; }
if (!temp_tree->buf) {
r = errno;
goto died3;
}
//TODO: Create list of selfreads //TODO: Create list of selfreads
//TODO: Create list of selfwrites //TODO: Create list of selfwrites
*ptree = temp_tree; *ptree = tmp_tree;
return 0; return 0;
} }
int toku_lt_close(toku_lock_tree* tree) { int toku_lt_close(toku_lock_tree* tree) {
if (!tree) return EINVAL; if (!tree) return EINVAL;
int r; int r;
int r2 = 0;
r = toku_rt_close(tree->mainread); r = toku_rt_close(tree->mainread);
assert(r==0); if (r!=0) r2 = r;
r = toku_rt_close(tree->borderwrite); r = toku_rt_close(tree->borderwrite);
assert(r==0); if (r!=0) r2 = r;
//TODO: Do this to ALLLLLLLL selfread and ALLLLLL selfwrite tables. //TODO: Do this to ALLLLLLLL selfread and ALLLLLL selfwrite tables.
/* Free all points referred to in a range tree (and close the tree). */ /* Free all points referred to in a range tree (and close the tree). */
__toku_lt_free_contents(tree,__toku_lt_ifexist_selfread (tree, (DB_TXN*)1)); r = __toku_lt_free_contents(tree,
__toku_lt_free_contents(tree,__toku_lt_ifexist_selfwrite(tree, (DB_TXN*)1)); __toku_lt_ifexist_selfread (tree, (DB_TXN*)1));
if (r!=0) r2 = r;
r= __toku_lt_free_contents( tree,
__toku_lt_ifexist_selfwrite(tree, (DB_TXN*)1));
if (r!=0) r2 = r;
//TODO: After freeing the tree, need to remove it from both lists!!! //TODO: After freeing the tree, need to remove it from both lists!!!
// One list probably IN the transaction, and one additional one here. // One list probably IN the transaction, and one additional one here.
tree->free(tree->buf); tree->free(tree->buf);
tree->free(tree); tree->free(tree);
return 0; return r2;
} }
int toku_lt_acquire_read_lock(toku_lock_tree* tree, DB_TXN* txn, int toku_lt_acquire_read_lock(toku_lock_tree* tree, DB_TXN* txn,
...@@ -938,7 +942,7 @@ int toku_lt_acquire_write_lock(toku_lock_tree* tree, DB_TXN* txn, ...@@ -938,7 +942,7 @@ int toku_lt_acquire_write_lock(toku_lock_tree* tree, DB_TXN* txn,
unsigned numfound; unsigned numfound;
r = toku_rt_find(borderwrite, &query, 1, &tree->buf, &tree->buflen, r = toku_rt_find(borderwrite, &query, 1, &tree->buf, &tree->buflen,
&numfound); &numfound);
if (r!=0) return __toku_lt_panic(tree, r); if (r!=0) return __toku_lt_panic(tree);
assert(numfound <= 1); assert(numfound <= 1);
/* No updated needed in borderwrite: we return right away. */ /* No updated needed in borderwrite: we return right away. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment