Commit 35a46f2e authored by Rich Prohaska's avatar Rich Prohaska Committed by Yoni Fogel

#3853 make the lock tree memory accounting more accurate refs[t:3853]

git-svn-id: file:///svn/toku/tokudb@36278 c7de825b-a66e-492c-adef-691d508d4ae1
parent d69063c8
...@@ -1262,8 +1262,6 @@ test_serialize_nonleaf(enum brtnode_verify_type bft) { ...@@ -1262,8 +1262,6 @@ test_serialize_nonleaf(enum brtnode_verify_type bft) {
int int
test_main (int argc __attribute__((__unused__)), const char *argv[] __attribute__((__unused__))) { test_main (int argc __attribute__((__unused__)), const char *argv[] __attribute__((__unused__))) {
toku_memory_check = 1;
test_serialize_leaf(read_none); test_serialize_leaf(read_none);
test_serialize_leaf(read_all); test_serialize_leaf(read_all);
test_serialize_leaf(read_compressed); test_serialize_leaf(read_compressed);
......
...@@ -14,7 +14,7 @@ static void test_dump_empty_db (void) { ...@@ -14,7 +14,7 @@ static void test_dump_empty_db (void) {
BRT t; BRT t;
CACHETABLE ct; CACHETABLE ct;
int r; int r;
toku_memory_check=1;
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
assert(r==0); assert(r==0);
unlink(fname); unlink(fname);
...@@ -1219,7 +1219,7 @@ static void test_new_brt_cursors(void) { ...@@ -1219,7 +1219,7 @@ static void test_new_brt_cursors(void) {
} }
static void brt_blackbox_test (void) { static void brt_blackbox_test (void) {
toku_memory_check = 1;
test_wrongendian_compare(0, 2); test_wrongendian_compare(0, 2);
test_wrongendian_compare(1, 2); test_wrongendian_compare(1, 2);
test_wrongendian_compare(1, 257); test_wrongendian_compare(1, 257);
...@@ -1236,8 +1236,6 @@ static void brt_blackbox_test (void) { ...@@ -1236,8 +1236,6 @@ static void brt_blackbox_test (void) {
if (verbose) printf("test_multiple_files\n"); if (verbose) printf("test_multiple_files\n");
test_multiple_files(); test_multiple_files();
toku_memory_check = 1;
test_brt_limits(); test_brt_limits();
test_brt_delete(); test_brt_delete();
......
...@@ -14,7 +14,6 @@ static void test0 (void) { ...@@ -14,7 +14,6 @@ static void test0 (void) {
CACHETABLE ct; CACHETABLE ct;
char fname[]= __FILE__ "0.brt"; char fname[]= __FILE__ "0.brt";
if (verbose) printf("%s:%d test0\n", __FILE__, __LINE__); if (verbose) printf("%s:%d test0\n", __FILE__, __LINE__);
toku_memory_check=1;
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
assert(r==0); assert(r==0);
......
...@@ -14,7 +14,6 @@ static void test1 (void) { ...@@ -14,7 +14,6 @@ static void test1 (void) {
CACHETABLE ct; CACHETABLE ct;
char fname[]= __FILE__ "1.brt"; char fname[]= __FILE__ "1.brt";
DBT k,v; DBT k,v;
toku_memory_check=1;
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
assert(r==0); assert(r==0);
......
...@@ -8,13 +8,12 @@ ...@@ -8,13 +8,12 @@
static TOKUTXN const null_txn = 0; static TOKUTXN const null_txn = 0;
static DB * const null_db = 0; static DB * const null_db = 0;
static void test2 (int memcheck, int limit) { static void test2 (int limit) {
BRT t; BRT t;
int r; int r;
int i; int i;
CACHETABLE ct; CACHETABLE ct;
char fname[]= __FILE__ "2.brt"; char fname[]= __FILE__ "2.brt";
toku_memory_check=memcheck;
if (verbose) printf("%s:%d checking\n", __FILE__, __LINE__); if (verbose) printf("%s:%d checking\n", __FILE__, __LINE__);
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0); r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0);
...@@ -47,13 +46,11 @@ static void test2 (int memcheck, int limit) { ...@@ -47,13 +46,11 @@ static void test2 (int memcheck, int limit) {
int int
test_main (int argc , const char *argv[]) { test_main (int argc , const char *argv[]) {
default_parse_args(argc, argv); default_parse_args(argc, argv);
// if (verbose) printf("test2 checking memory\n");
// test2(1);
if (verbose) printf("test2 faster\n"); if (verbose) printf("test2 faster\n");
test2(0, 2); test2(2);
test2(0, 27); test2(27);
test2(0, 212); test2(212);
test2(0, 4096); test2(4096);
if (verbose) printf("test1 ok\n"); if (verbose) printf("test1 ok\n");
return 0; return 0;
......
...@@ -11,13 +11,12 @@ static const char fname[]= __FILE__ ".brt"; ...@@ -11,13 +11,12 @@ static const char fname[]= __FILE__ ".brt";
static TOKUTXN const null_txn = 0; static TOKUTXN const null_txn = 0;
static DB * const null_db = 0; static DB * const null_db = 0;
static void test3 (int nodesize, int basementnodesize, int count, int memcheck) { static void test3 (int nodesize, int basementnodesize, int count) {
BRT t; BRT t;
int r; int r;
struct timeval t0,t1; struct timeval t0,t1;
int i; int i;
CACHETABLE ct; CACHETABLE ct;
toku_memory_check=memcheck;
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0); r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0);
gettimeofday(&t0, 0); gettimeofday(&t0, 0);
...@@ -45,26 +44,25 @@ static void test3 (int nodesize, int basementnodesize, int count, int memcheck) ...@@ -45,26 +44,25 @@ static void test3 (int nodesize, int basementnodesize, int count, int memcheck)
static void brt_blackbox_test (void) { static void brt_blackbox_test (void) {
if (verbose) printf("test3 slow\n"); if (verbose) printf("test3 slow\n");
toku_memory_check=0;
test3(2048, 512, 1<<15, 1); test3(2048, 512, 1<<15);
if (verbose) printf("test3 fast\n"); if (verbose) printf("test3 fast\n");
//if (verbose) toku_pma_show_stats(); //if (verbose) toku_pma_show_stats();
test3(1<<15, 1<<12, 1024, 1); test3(1<<15, 1<<12, 1024);
if (verbose) printf("test3 fast\n"); if (verbose) printf("test3 fast\n");
test3(1<<18, 1<<15, 1<<20, 0); test3(1<<18, 1<<15, 1<<20);
toku_memory_check = 1;
// test3(1<<19, 1<<16, 1<<20, 0); // test3(1<<19, 1<<16, 1<<20);
// test3(1<<20, 1<<17, 1<<20, 0); // test3(1<<20, 1<<17, 1<<20);
// test3(1<<20, 1<<17, 1<<21, 0); // test3(1<<20, 1<<17, 1<<21);
// test3(1<<20, 1<<17, 1<<22, 0); // test3(1<<20, 1<<17, 1<<22);
} }
......
...@@ -11,7 +11,7 @@ static const char fname[]= __FILE__ ".brt"; ...@@ -11,7 +11,7 @@ static const char fname[]= __FILE__ ".brt";
static TOKUTXN const null_txn = 0; static TOKUTXN const null_txn = 0;
static DB * const null_db = 0; static DB * const null_db = 0;
static void test4 (int nodesize, int count, int memcheck) { static void test4 (int nodesize, int count) {
BRT t; BRT t;
int r; int r;
struct timeval t0,t1; struct timeval t0,t1;
...@@ -19,7 +19,6 @@ static void test4 (int nodesize, int count, int memcheck) { ...@@ -19,7 +19,6 @@ static void test4 (int nodesize, int count, int memcheck) {
CACHETABLE ct; CACHETABLE ct;
gettimeofday(&t0, 0); gettimeofday(&t0, 0);
unlink(fname); unlink(fname);
toku_memory_check=memcheck;
r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0); r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0);
r = toku_open_brt(fname, 1, &t, nodesize, nodesize / 8, ct, null_txn, toku_builtin_compare_fun, null_db); assert(r==0); r = toku_open_brt(fname, 1, &t, nodesize, nodesize / 8, ct, null_txn, toku_builtin_compare_fun, null_db); assert(r==0);
...@@ -44,21 +43,21 @@ static void test4 (int nodesize, int count, int memcheck) { ...@@ -44,21 +43,21 @@ static void test4 (int nodesize, int count, int memcheck) {
} }
static void brt_blackbox_test (void) { static void brt_blackbox_test (void) {
test4(2048, 1<<14, 1); test4(2048, 1<<14);
if (0) { if (0) {
if (verbose) printf("test4 slow\n"); if (verbose) printf("test4 slow\n");
test4(2048, 1<<15, 1); test4(2048, 1<<15);
//if (verbose) toku_pma_show_stats(); //if (verbose) toku_pma_show_stats();
test4(1<<15, 1024, 1); test4(1<<15, 1024);
test4(1<<18, 1<<20, 0); test4(1<<18, 1<<20);
// Once upon a time srandom(8) caused this test to fail. // Once upon a time srandom(8) caused this test to fail.
srandom(8); test4(2048, 1<<15, 1); srandom(8); test4(2048, 1<<15);
} }
} }
......
...@@ -1069,7 +1069,6 @@ parse_args(int argc, const char *argv[]) { ...@@ -1069,7 +1069,6 @@ parse_args(int argc, const char *argv[]) {
int int
test_main (int argc, const char *argv[]) { test_main (int argc, const char *argv[]) {
toku_memory_check = 1;
parse_args(argc, argv); parse_args(argc, argv);
int r; int r;
......
...@@ -32,7 +32,6 @@ found(ITEMLEN UU(keylen), bytevec key, ITEMLEN UU(vallen), bytevec UU(val), void ...@@ -32,7 +32,6 @@ found(ITEMLEN UU(keylen), bytevec key, ITEMLEN UU(vallen), bytevec UU(val), void
int int
test_main (int argc __attribute__((__unused__)), const char *argv[] __attribute__((__unused__))) { test_main (int argc __attribute__((__unused__)), const char *argv[] __attribute__((__unused__))) {
toku_memory_check = 1;
CACHETABLE ct; CACHETABLE ct;
BRT t; BRT t;
......
...@@ -501,7 +501,6 @@ test_split_at_end(void) ...@@ -501,7 +501,6 @@ test_split_at_end(void)
int int
test_main (int argc __attribute__((__unused__)), const char *argv[] __attribute__((__unused__))) { test_main (int argc __attribute__((__unused__)), const char *argv[] __attribute__((__unused__))) {
toku_memory_check = 1;
test_split_on_boundary(); test_split_on_boundary();
test_split_with_everything_on_the_left(); test_split_with_everything_on_the_left();
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
*/ */
#include <toku_portability.h> #include <toku_portability.h>
#include "memory.h"
#include <idlth.h> #include <idlth.h>
#include <toku_assert.h> #include <toku_assert.h>
#include <errno.h> #include <errno.h>
...@@ -28,23 +29,17 @@ static inline void toku__invalidate_scan(toku_idlth* idlth) { ...@@ -28,23 +29,17 @@ static inline void toku__invalidate_scan(toku_idlth* idlth) {
idlth->iter_is_valid = FALSE; idlth->iter_is_valid = FALSE;
} }
int toku_idlth_create(toku_idlth** pidlth, int toku_idlth_create(toku_idlth** pidlth) {
void* (*user_malloc) (size_t),
void (*user_free) (void*),
void* (*user_realloc)(void*, size_t)) {
int r = ENOSYS; int r = ENOSYS;
assert(pidlth && user_malloc && user_free && user_realloc); assert(pidlth);
toku_idlth* tmp = NULL; toku_idlth* tmp = NULL;
tmp = (toku_idlth*)user_malloc(sizeof(*tmp)); tmp = (toku_idlth*) toku_malloc(sizeof(*tmp));
if (!tmp) { r = ENOMEM; goto cleanup; } if (!tmp) { r = ENOMEM; goto cleanup; }
memset(tmp, 0, sizeof(*tmp)); memset(tmp, 0, sizeof(*tmp));
tmp->malloc = user_malloc;
tmp->free = user_free;
tmp->realloc = user_realloc;
tmp->num_buckets = __toku_idlth_init_size; tmp->num_buckets = __toku_idlth_init_size;
tmp->buckets = (toku_idlth_elt*) tmp->buckets = (toku_idlth_elt*)
tmp->malloc(tmp->num_buckets * sizeof(*tmp->buckets)); toku_malloc(tmp->num_buckets * sizeof(*tmp->buckets));
if (!tmp->buckets) { r = ENOMEM; goto cleanup; } if (!tmp->buckets) { r = ENOMEM; goto cleanup; }
memset(tmp->buckets, 0, tmp->num_buckets * sizeof(*tmp->buckets)); memset(tmp->buckets, 0, tmp->num_buckets * sizeof(*tmp->buckets));
toku__invalidate_scan(tmp); toku__invalidate_scan(tmp);
...@@ -56,8 +51,8 @@ int toku_idlth_create(toku_idlth** pidlth, ...@@ -56,8 +51,8 @@ int toku_idlth_create(toku_idlth** pidlth,
cleanup: cleanup:
if (r != 0) { if (r != 0) {
if (tmp) { if (tmp) {
if (tmp->buckets) { user_free(tmp->buckets); } if (tmp->buckets) { toku_free(tmp->buckets); }
user_free(tmp); toku_free(tmp);
} }
} }
return r; return r;
...@@ -87,7 +82,7 @@ static inline toku_idlth_elt* toku__idlth_next(toku_idlth* idlth) { ...@@ -87,7 +82,7 @@ static inline toku_idlth_elt* toku__idlth_next(toku_idlth* idlth) {
assert(idlth->iter_is_valid); assert(idlth->iter_is_valid);
idlth->iter_curr = idlth->iter_curr->next_in_iteration; idlth->iter_curr = idlth->iter_curr->next_in_iteration;
idlth->iter_is_valid = (BOOL)(idlth->iter_curr != &idlth->iter_head); idlth->iter_is_valid = (idlth->iter_curr != &idlth->iter_head);
return idlth->iter_curr; return idlth->iter_curr;
} }
...@@ -120,7 +115,7 @@ void toku_idlth_delete(toku_idlth* idlth, DICTIONARY_ID dict_id) { ...@@ -120,7 +115,7 @@ void toku_idlth_delete(toku_idlth* idlth, DICTIONARY_ID dict_id) {
current->prev_in_iteration->next_in_iteration = current->next_in_iteration; current->prev_in_iteration->next_in_iteration = current->next_in_iteration;
current->next_in_iteration->prev_in_iteration = current->prev_in_iteration; current->next_in_iteration->prev_in_iteration = current->prev_in_iteration;
prev->next_in_bucket = current->next_in_bucket; prev->next_in_bucket = current->next_in_bucket;
idlth->free(current); toku_free(current);
idlth->num_keys--; idlth->num_keys--;
return; return;
} }
...@@ -134,7 +129,7 @@ int toku_idlth_insert(toku_idlth* idlth, DICTIONARY_ID dict_id) { ...@@ -134,7 +129,7 @@ int toku_idlth_insert(toku_idlth* idlth, DICTIONARY_ID dict_id) {
uint32_t index = toku__idlth_hash(idlth, dict_id); uint32_t index = toku__idlth_hash(idlth, dict_id);
/* Allocate a new one. */ /* Allocate a new one. */
toku_idlth_elt* element = (toku_idlth_elt*)idlth->malloc(sizeof(*element)); toku_idlth_elt* element = (toku_idlth_elt*) toku_malloc(sizeof(*element));
if (!element) { r = ENOMEM; goto cleanup; } if (!element) { r = ENOMEM; goto cleanup; }
memset(element, 0, sizeof(*element)); memset(element, 0, sizeof(*element));
element->value.dict_id = dict_id; element->value.dict_id = dict_id;
...@@ -153,7 +148,7 @@ cleanup: ...@@ -153,7 +148,7 @@ cleanup:
return r; return r;
} }
static inline void toku__idlth_clear(toku_idlth* idlth, BOOL clean) { static inline void toku__idlth_clear(toku_idlth* idlth, bool clean) {
assert(idlth); assert(idlth);
toku_idlth_elt* element; toku_idlth_elt* element;
...@@ -164,7 +159,7 @@ static inline void toku__idlth_clear(toku_idlth* idlth, BOOL clean) { ...@@ -164,7 +159,7 @@ static inline void toku__idlth_clear(toku_idlth* idlth, BOOL clean) {
while (next != head) { while (next != head) {
element = next; element = next;
next = toku__idlth_next(idlth); next = toku__idlth_next(idlth);
idlth->free(element); toku_free(element);
} }
/* If clean is true, then we want to restore it to 'just created' status. /* If clean is true, then we want to restore it to 'just created' status.
If we are closing the tree, we don't need to do that restoration. */ If we are closing the tree, we don't need to do that restoration. */
...@@ -184,16 +179,16 @@ void toku_idlth_close(toku_idlth* idlth) { ...@@ -184,16 +179,16 @@ void toku_idlth_close(toku_idlth* idlth) {
assert(idlth); assert(idlth);
toku__idlth_clear(idlth, FALSE); toku__idlth_clear(idlth, FALSE);
idlth->free(idlth->buckets); toku_free(idlth->buckets);
idlth->free(idlth); toku_free(idlth);
} }
BOOL toku_idlth_is_empty(toku_idlth* idlth) { bool toku_idlth_is_empty(toku_idlth* idlth) {
assert(idlth); assert(idlth);
/* Verify consistency. */ /* Verify consistency. */
assert((idlth->num_keys == 0) == assert((idlth->num_keys == 0) ==
(idlth->iter_head.next_in_iteration == &idlth->iter_head)); (idlth->iter_head.next_in_iteration == &idlth->iter_head));
assert((idlth->num_keys == 0) == assert((idlth->num_keys == 0) ==
(idlth->iter_head.prev_in_iteration == &idlth->iter_head)); (idlth->iter_head.prev_in_iteration == &idlth->iter_head));
return (BOOL)(idlth->num_keys == 0); return (idlth->num_keys == 0);
} }
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
*/ */
//Defines BOOL data type. //Defines bool data type.
#include <db.h> #include <db.h>
#include <brttypes.h> #include <brttypes.h>
#include <rangetree.h> #include <rangetree.h>
...@@ -46,19 +46,10 @@ struct __toku_idlth { ...@@ -46,19 +46,10 @@ struct __toku_idlth {
uint32_t num_keys; uint32_t num_keys;
toku_idlth_elt iter_head; toku_idlth_elt iter_head;
toku_idlth_elt* iter_curr; toku_idlth_elt* iter_curr;
BOOL iter_is_valid; bool iter_is_valid;
/** The user malloc function */
void* (*malloc) (size_t);
/** The user free function */
void (*free) (void*);
/** The user realloc function */
void* (*realloc)(void*, size_t);
}; };
int toku_idlth_create(toku_idlth** ptable, int toku_idlth_create(toku_idlth** ptable);
void* (*user_malloc) (size_t),
void (*user_free) (void*),
void* (*user_realloc)(void*, size_t));
toku_lt_map* toku_idlth_find (toku_idlth* table, DICTIONARY_ID dict_id); toku_lt_map* toku_idlth_find (toku_idlth* table, DICTIONARY_ID dict_id);
...@@ -74,7 +65,7 @@ int toku_idlth_insert (toku_idlth* table, DICTIONARY_ID dict_id) ...@@ -74,7 +65,7 @@ int toku_idlth_insert (toku_idlth* table, DICTIONARY_ID dict_id)
void toku_idlth_clear (toku_idlth* idlth); void toku_idlth_clear (toku_idlth* idlth);
BOOL toku_idlth_is_empty (toku_idlth* idlth); bool toku_idlth_is_empty (toku_idlth* idlth);
#if defined(__cplusplus) #if defined(__cplusplus)
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
*/ */
#include <toku_portability.h> #include <toku_portability.h>
#include "memory.h"
#include <locktree.h> #include <locktree.h>
#include <ydb-internal.h> #include <ydb-internal.h>
#include <brt-internal.h> #include <brt-internal.h>
...@@ -78,7 +79,8 @@ toku_ltm_unlock_mutex(toku_ltm *ltm) { ...@@ -78,7 +79,8 @@ toku_ltm_unlock_mutex(toku_ltm *ltm) {
int r = toku_pthread_mutex_unlock(toku_ltm_get_mutex(ltm)); assert_zero(r); int r = toku_pthread_mutex_unlock(toku_ltm_get_mutex(ltm)); assert_zero(r);
} }
char* toku_lt_strerror(TOKU_LT_ERROR r) { char*
toku_lt_strerror(TOKU_LT_ERROR r) {
if (r >= 0) if (r >= 0)
return strerror(r); return strerror(r);
if (r == TOKU_LT_INCONSISTENT) { if (r == TOKU_LT_INCONSISTENT) {
...@@ -87,7 +89,8 @@ char* toku_lt_strerror(TOKU_LT_ERROR r) { ...@@ -87,7 +89,8 @@ char* toku_lt_strerror(TOKU_LT_ERROR r) {
return "Unknown error in locking data structures.\n"; return "Unknown error in locking data structures.\n";
} }
/* Compare two payloads assuming that at least one of them is infinite */ /* Compare two payloads assuming that at least one of them is infinite */
static inline int infinite_compare(const DBT* a, const DBT* b) { static inline int
infinite_compare(const DBT* a, const DBT* b) {
if (a == b) if (a == b)
return 0; return 0;
if (a == toku_lt_infinity) if (a == toku_lt_infinity)
...@@ -100,8 +103,9 @@ static inline int infinite_compare(const DBT* a, const DBT* b) { ...@@ -100,8 +103,9 @@ static inline int infinite_compare(const DBT* a, const DBT* b) {
return 1; return 1;
} }
static inline BOOL lt_is_infinite(const DBT* p) { static inline bool
BOOL r; lt_is_infinite(const DBT* p) {
bool r;
if (p == toku_lt_infinity || p == toku_lt_neg_infinity) { if (p == toku_lt_infinity || p == toku_lt_neg_infinity) {
DBT* dbt = (DBT*)p; DBT* dbt = (DBT*)p;
assert(!dbt->data && !dbt->size); assert(!dbt->data && !dbt->size);
...@@ -113,34 +117,40 @@ static inline BOOL lt_is_infinite(const DBT* p) { ...@@ -113,34 +117,40 @@ static inline BOOL lt_is_infinite(const DBT* p) {
/* Verifies that NULL data and size are consistent. /* Verifies that NULL data and size are consistent.
i.e. The size is 0 if and only if the data is NULL. */ i.e. The size is 0 if and only if the data is NULL. */
static inline int lt_verify_null_key(const DBT* key) { static inline int
lt_verify_null_key(const DBT* key) {
if (key && key->size && !key->data) if (key && key->size && !key->data)
return EINVAL; return EINVAL;
return 0; return 0;
} }
static inline DBT* recreate_DBT(DBT* dbt, void* payload, uint32_t length) { static inline DBT*
recreate_DBT(DBT* dbt, void* payload, uint32_t length) {
memset(dbt, 0, sizeof(DBT)); memset(dbt, 0, sizeof(DBT));
dbt->data = payload; dbt->data = payload;
dbt->size = length; dbt->size = length;
return dbt; return dbt;
} }
static inline int lt_txn_cmp(const TXNID a, const TXNID b) { static inline int
lt_txn_cmp(const TXNID a, const TXNID b) {
return a < b ? -1 : (a != b); return a < b ? -1 : (a != b);
} }
static inline void toku_ltm_remove_lt(toku_ltm* mgr, toku_lock_tree* lt) { static inline void
toku_ltm_remove_lt(toku_ltm* mgr, toku_lock_tree* lt) {
assert(mgr && lt); assert(mgr && lt);
toku_lth_delete(mgr->lth, lt); toku_lth_delete(mgr->lth, lt);
} }
static inline int toku_ltm_add_lt(toku_ltm* mgr, toku_lock_tree* lt) { static inline int
toku_ltm_add_lt(toku_ltm* mgr, toku_lock_tree* lt) {
assert(mgr && lt); assert(mgr && lt);
return toku_lth_insert(mgr->lth, lt); return toku_lth_insert(mgr->lth, lt);
} }
int toku_lt_point_cmp(const toku_point* x, const toku_point* y) { int
toku_lt_point_cmp(const toku_point* x, const toku_point* y) {
DBT point_1; DBT point_1;
DBT point_2; DBT point_2;
...@@ -164,23 +174,21 @@ int toku_lt_point_cmp(const toku_point* x, const toku_point* y) { ...@@ -164,23 +174,21 @@ int toku_lt_point_cmp(const toku_point* x, const toku_point* y) {
} }
/* Lock tree manager functions begin here */ /* Lock tree manager functions begin here */
int toku_ltm_create(toku_ltm** pmgr, int
toku_ltm_create(toku_ltm** pmgr,
uint32_t max_locks, uint32_t max_locks,
uint64_t max_lock_memory, uint64_t max_lock_memory,
int (*panic)(DB*, int), int (*panic)(DB*, int),
toku_dbt_cmp (*get_compare_fun_from_db)(DB*), toku_dbt_cmp (*get_compare_fun_from_db)(DB*)) {
void* (*user_malloc) (size_t),
void (*user_free) (void*),
void* (*user_realloc)(void*, size_t)) {
int r = ENOSYS; int r = ENOSYS;
toku_ltm* tmp_mgr = NULL; toku_ltm* tmp_mgr = NULL;
if (!pmgr || !max_locks || !user_malloc || !user_free || !user_realloc) { if (!pmgr || !max_locks) {
r = EINVAL; goto cleanup; r = EINVAL; goto cleanup;
} }
assert(panic && get_compare_fun_from_db); assert(panic && get_compare_fun_from_db);
tmp_mgr = (toku_ltm*)user_malloc(sizeof(*tmp_mgr)); tmp_mgr = (toku_ltm*) toku_malloc(sizeof(*tmp_mgr));
if (!tmp_mgr) { if (!tmp_mgr) {
r = ENOMEM; goto cleanup; r = ENOMEM; goto cleanup;
} }
...@@ -193,19 +201,16 @@ int toku_ltm_create(toku_ltm** pmgr, ...@@ -193,19 +201,16 @@ int toku_ltm_create(toku_ltm** pmgr,
if (r != 0) if (r != 0)
goto cleanup; goto cleanup;
tmp_mgr->panic = panic; tmp_mgr->panic = panic;
tmp_mgr->malloc = user_malloc;
tmp_mgr->free = user_free;
tmp_mgr->realloc = user_realloc;
tmp_mgr->get_compare_fun_from_db = get_compare_fun_from_db; tmp_mgr->get_compare_fun_from_db = get_compare_fun_from_db;
r = toku_lth_create(&tmp_mgr->lth, user_malloc, user_free, user_realloc); r = toku_lth_create(&tmp_mgr->lth);
if (r != 0) if (r != 0)
goto cleanup; goto cleanup;
if (!tmp_mgr->lth) { if (!tmp_mgr->lth) {
r = ENOMEM; goto cleanup; r = ENOMEM; goto cleanup;
} }
r = toku_idlth_create(&tmp_mgr->idlth, user_malloc, user_free, user_realloc); r = toku_idlth_create(&tmp_mgr->idlth);
if (r != 0) if (r != 0)
goto cleanup; goto cleanup;
if (!tmp_mgr->idlth) { if (!tmp_mgr->idlth) {
...@@ -221,13 +226,14 @@ cleanup: ...@@ -221,13 +226,14 @@ cleanup:
toku_lth_close(tmp_mgr->lth); toku_lth_close(tmp_mgr->lth);
if (tmp_mgr->idlth) if (tmp_mgr->idlth)
toku_idlth_close(tmp_mgr->idlth); toku_idlth_close(tmp_mgr->idlth);
user_free(tmp_mgr); toku_free(tmp_mgr);
} }
} }
return r; return r;
} }
int toku_ltm_close(toku_ltm* mgr) { int
toku_ltm_close(toku_ltm* mgr) {
int r = ENOSYS; int r = ENOSYS;
int first_error = 0; int first_error = 0;
...@@ -245,14 +251,16 @@ int toku_ltm_close(toku_ltm* mgr) { ...@@ -245,14 +251,16 @@ int toku_ltm_close(toku_ltm* mgr) {
toku_lth_close(mgr->lth); toku_lth_close(mgr->lth);
toku_idlth_close(mgr->idlth); toku_idlth_close(mgr->idlth);
toku_ltm_destroy_mutex(mgr); toku_ltm_destroy_mutex(mgr);
mgr->free(mgr); assert(mgr->curr_locks == 0 && mgr->curr_lock_memory == 0);
toku_free(mgr);
r = first_error; r = first_error;
cleanup: cleanup:
return r; return r;
} }
void toku_ltm_get_status(toku_ltm* mgr, uint32_t * max_locks, uint32_t * curr_locks, void
toku_ltm_get_status(toku_ltm* mgr, uint32_t * max_locks, uint32_t * curr_locks,
uint64_t *max_lock_memory, uint64_t *curr_lock_memory, uint64_t *max_lock_memory, uint64_t *curr_lock_memory,
LTM_STATUS s) { LTM_STATUS s) {
*max_locks = mgr->max_locks; *max_locks = mgr->max_locks;
...@@ -262,14 +270,16 @@ void toku_ltm_get_status(toku_ltm* mgr, uint32_t * max_locks, uint32_t * curr_lo ...@@ -262,14 +270,16 @@ void toku_ltm_get_status(toku_ltm* mgr, uint32_t * max_locks, uint32_t * curr_lo
*s = mgr->status; *s = mgr->status;
} }
int toku_ltm_get_max_locks(toku_ltm* mgr, uint32_t* max_locks) { int
toku_ltm_get_max_locks(toku_ltm* mgr, uint32_t* max_locks) {
if (!mgr || !max_locks) if (!mgr || !max_locks)
return EINVAL; return EINVAL;
*max_locks = mgr->max_locks; *max_locks = mgr->max_locks;
return 0; return 0;
} }
int toku_ltm_set_max_locks(toku_ltm* mgr, uint32_t max_locks) { int
toku_ltm_set_max_locks(toku_ltm* mgr, uint32_t max_locks) {
if (!mgr || !max_locks) if (!mgr || !max_locks)
return EINVAL; return EINVAL;
if (max_locks < mgr->curr_locks) if (max_locks < mgr->curr_locks)
...@@ -278,14 +288,16 @@ int toku_ltm_set_max_locks(toku_ltm* mgr, uint32_t max_locks) { ...@@ -278,14 +288,16 @@ int toku_ltm_set_max_locks(toku_ltm* mgr, uint32_t max_locks) {
return 0; return 0;
} }
int toku_ltm_get_max_lock_memory(toku_ltm* mgr, uint64_t* max_lock_memory) { int
toku_ltm_get_max_lock_memory(toku_ltm* mgr, uint64_t* max_lock_memory) {
if (!mgr || !max_lock_memory) if (!mgr || !max_lock_memory)
return EINVAL; return EINVAL;
*max_lock_memory = mgr->max_lock_memory; *max_lock_memory = mgr->max_lock_memory;
return 0; return 0;
} }
int toku_ltm_set_max_lock_memory(toku_ltm* mgr, uint64_t max_lock_memory) { int
toku_ltm_set_max_lock_memory(toku_ltm* mgr, uint64_t max_lock_memory) {
if (!mgr || !max_lock_memory) if (!mgr || !max_lock_memory)
return EINVAL; return EINVAL;
if (max_lock_memory < mgr->curr_locks) if (max_lock_memory < mgr->curr_locks)
...@@ -294,56 +306,67 @@ int toku_ltm_set_max_lock_memory(toku_ltm* mgr, uint64_t max_lock_memory) { ...@@ -294,56 +306,67 @@ int toku_ltm_set_max_lock_memory(toku_ltm* mgr, uint64_t max_lock_memory) {
return 0; return 0;
} }
/* Functions to update the range count and compare it with the static inline void
maximum number of ranges */ ltm_incr_locks(toku_ltm* tree_mgr, uint32_t replace_locks) {
static inline BOOL ltm_lock_test_incr(toku_ltm* tree_mgr, uint32_t replace_locks) {
assert(tree_mgr);
assert(replace_locks <= tree_mgr->curr_locks); assert(replace_locks <= tree_mgr->curr_locks);
return (BOOL)(tree_mgr->curr_locks - replace_locks < tree_mgr->max_locks);
}
static inline void ltm_lock_incr(toku_ltm* tree_mgr, uint32_t replace_locks) {
assert(ltm_lock_test_incr(tree_mgr, replace_locks));
tree_mgr->curr_locks -= replace_locks; tree_mgr->curr_locks -= replace_locks;
tree_mgr->curr_locks += 1; tree_mgr->curr_locks += 1;
} }
static inline void ltm_lock_decr(toku_ltm* tree_mgr, uint32_t locks) { static inline void
ltm_decr_locks(toku_ltm* tree_mgr, uint32_t locks) {
assert(tree_mgr); assert(tree_mgr);
assert(tree_mgr->curr_locks >= locks); assert(tree_mgr->curr_locks >= locks);
tree_mgr->curr_locks -= locks; tree_mgr->curr_locks -= locks;
} }
static inline void ltm_note_free_memory(toku_ltm *mgr, size_t mem) { static int
assert(mgr->curr_lock_memory >= mem); ltm_out_of_locks(toku_ltm *mgr) {
mgr->curr_lock_memory -= mem; int r = 0;
if (mgr->curr_locks >= mgr->max_locks || mgr->curr_lock_memory >= mgr->max_lock_memory)
r = TOKUDB_OUT_OF_LOCKS;
return r;
} }
static inline int ltm_note_allocate_memory(toku_ltm *mgr, size_t mem) { static void
int r = TOKUDB_OUT_OF_LOCKS; ltm_incr_lock_memory(toku_ltm *mgr, size_t s) {
if (mgr->curr_lock_memory + mem <= mgr->max_lock_memory) { mgr->curr_lock_memory += s;
mgr->curr_lock_memory += mem; }
r = 0;
} void
return r; toku_ltm_incr_lock_memory(void *extra, size_t s) {
toku_ltm *mgr = (toku_ltm *) extra;
ltm_incr_lock_memory(mgr, s);
}
static void
ltm_decr_lock_memory(toku_ltm *mgr, size_t s) {
assert(mgr->curr_lock_memory >= s);
mgr->curr_lock_memory -= s;
}
void
toku_ltm_decr_lock_memory(void *extra, size_t s) {
toku_ltm *mgr = (toku_ltm *) extra;
ltm_decr_lock_memory(mgr, s);
} }
static inline void p_free(toku_lock_tree* tree, toku_point* point) { static inline void
p_free(toku_lock_tree* tree, toku_point* point) {
assert(point); assert(point);
size_t freeing = sizeof(*point);
if (!lt_is_infinite(point->key_payload)) { if (!lt_is_infinite(point->key_payload)) {
freeing += point->key_len; ltm_decr_lock_memory(tree->mgr, toku_malloc_usable_size(point->key_payload));
tree->free(point->key_payload); toku_free(point->key_payload);
} }
tree->free(point); ltm_decr_lock_memory(tree->mgr, toku_malloc_usable_size(point));
toku_free(point);
ltm_note_free_memory(tree->mgr, freeing);
} }
/* /*
Allocate and copy the payload. Allocate and copy the payload.
*/ */
static inline int payload_copy(toku_lock_tree* tree, static inline int
payload_copy(toku_lock_tree* tree,
void** payload_out, uint32_t* len_out, void** payload_out, uint32_t* len_out,
void* payload_in, uint32_t len_in) { void* payload_in, uint32_t len_in) {
int r = 0; int r = 0;
...@@ -352,53 +375,38 @@ static inline int payload_copy(toku_lock_tree* tree, ...@@ -352,53 +375,38 @@ static inline int payload_copy(toku_lock_tree* tree,
assert(!payload_in || lt_is_infinite(payload_in)); assert(!payload_in || lt_is_infinite(payload_in));
*payload_out = payload_in; *payload_out = payload_in;
*len_out = len_in; *len_out = len_in;
} } else {
else {
r = ltm_note_allocate_memory(tree->mgr, len_in);
if (r == 0) {
assert(payload_in); assert(payload_in);
*payload_out = tree->malloc((size_t)len_in); //2808 *payload_out = toku_xmalloc((size_t)len_in); //2808
ltm_incr_lock_memory(tree->mgr, toku_malloc_usable_size(*payload_out));
resource_assert(*payload_out); resource_assert(*payload_out);
*len_out = len_in; *len_out = len_in;
memcpy(*payload_out, payload_in, (size_t)len_in); memcpy(*payload_out, payload_in, (size_t)len_in);
} }
}
return r; return r;
} }
static inline int p_makecopy(toku_lock_tree* tree, toku_point** ppoint) { static inline int
p_makecopy(toku_lock_tree* tree, toku_point** ppoint) {
assert(ppoint); assert(ppoint);
int r;
toku_point* point = *ppoint; toku_point* point = *ppoint;
toku_point* temp_point = NULL; toku_point* temp_point = NULL;
int r; temp_point = (toku_point*)toku_xmalloc(sizeof(toku_point)); //2808
ltm_incr_lock_memory(tree->mgr, toku_malloc_usable_size(temp_point));
r = ltm_note_allocate_memory(tree->mgr, sizeof(toku_point));
if (r != 0)
goto done;
temp_point = (toku_point*)tree->malloc(sizeof(toku_point)); //2808
resource_assert(temp_point);
if (0) {
died1:
tree->free(temp_point);
ltm_note_free_memory(tree->mgr, sizeof(toku_point));
goto done;
}
*temp_point = *point; *temp_point = *point;
r = payload_copy(tree, r = payload_copy(tree,
&temp_point->key_payload, &temp_point->key_len, &temp_point->key_payload, &temp_point->key_len,
point->key_payload, point->key_len); point->key_payload, point->key_len);
if (r != 0) assert_zero(r);
goto died1;
*ppoint = temp_point; *ppoint = temp_point;
done:
return r; return r;
} }
/* Provides access to a selfread tree for a particular transaction. /* Provides access to a selfread tree for a particular transaction.
Returns NULL if it does not exist yet. */ Returns NULL if it does not exist yet. */
toku_range_tree* toku_lt_ifexist_selfread(toku_lock_tree* tree, TXNID txn) { toku_range_tree*
toku_lt_ifexist_selfread(toku_lock_tree* tree, TXNID txn) {
assert(tree); assert(tree);
rt_forest* forest = toku_rth_find(tree->rth, txn); rt_forest* forest = toku_rth_find(tree->rth, txn);
return forest ? forest->self_read : NULL; return forest ? forest->self_read : NULL;
...@@ -406,15 +414,17 @@ toku_range_tree* toku_lt_ifexist_selfread(toku_lock_tree* tree, TXNID txn) { ...@@ -406,15 +414,17 @@ toku_range_tree* toku_lt_ifexist_selfread(toku_lock_tree* tree, TXNID txn) {
/* Provides access to a selfwrite tree for a particular transaction. /* Provides access to a selfwrite tree for a particular transaction.
Returns NULL if it does not exist yet. */ Returns NULL if it does not exist yet. */
toku_range_tree* toku_lt_ifexist_selfwrite(toku_lock_tree* tree, TXNID txn) { toku_range_tree*
toku_lt_ifexist_selfwrite(toku_lock_tree* tree, TXNID txn) {
assert(tree); assert(tree);
rt_forest* forest = toku_rth_find(tree->rth, txn); rt_forest* forest = toku_rth_find(tree->rth, txn);
return forest ? forest->self_write : NULL; return forest ? forest->self_write : NULL;
} }
static inline int lt_add_locked_txn(toku_lock_tree* tree, TXNID txn) { static inline int
lt_add_locked_txn(toku_lock_tree* tree, TXNID txn) {
int r = ENOSYS; int r = ENOSYS;
BOOL half_done = FALSE; bool half_done = FALSE;
/* Neither selfread nor selfwrite exist. */ /* Neither selfread nor selfwrite exist. */
r = toku_rth_insert(tree->rth, txn); r = toku_rth_insert(tree->rth, txn);
...@@ -433,8 +443,8 @@ cleanup: ...@@ -433,8 +443,8 @@ cleanup:
/* Provides access to a selfread tree for a particular transaction. /* Provides access to a selfread tree for a particular transaction.
Creates it if it does not exist. */ Creates it if it does not exist. */
static inline int lt_selfread(toku_lock_tree* tree, TXNID txn, static inline int
toku_range_tree** pselfread) { lt_selfread(toku_lock_tree* tree, TXNID txn, toku_range_tree** pselfread) {
int r = ENOSYS; int r = ENOSYS;
assert(tree && pselfread); assert(tree && pselfread);
...@@ -448,10 +458,8 @@ static inline int lt_selfread(toku_lock_tree* tree, TXNID txn, ...@@ -448,10 +458,8 @@ static inline int lt_selfread(toku_lock_tree* tree, TXNID txn,
} }
assert(forest); assert(forest);
if (!forest->self_read) { if (!forest->self_read) {
r = toku_rt_create(&forest->self_read, r = toku_rt_create(&forest->self_read, toku_lt_point_cmp, lt_txn_cmp, FALSE,
toku_lt_point_cmp, lt_txn_cmp, toku_ltm_incr_lock_memory, toku_ltm_decr_lock_memory, tree->mgr);
FALSE,
tree->malloc, tree->free, tree->realloc);
if (r != 0) if (r != 0)
goto cleanup; goto cleanup;
assert(forest->self_read); assert(forest->self_read);
...@@ -464,8 +472,8 @@ cleanup: ...@@ -464,8 +472,8 @@ cleanup:
/* Provides access to a selfwrite tree for a particular transaction. /* Provides access to a selfwrite tree for a particular transaction.
Creates it if it does not exist. */ Creates it if it does not exist. */
static inline int lt_selfwrite(toku_lock_tree* tree, TXNID txn, static inline int
toku_range_tree** pselfwrite) { lt_selfwrite(toku_lock_tree* tree, TXNID txn, toku_range_tree** pselfwrite) {
int r = ENOSYS; int r = ENOSYS;
assert(tree && pselfwrite); assert(tree && pselfwrite);
...@@ -479,10 +487,8 @@ static inline int lt_selfwrite(toku_lock_tree* tree, TXNID txn, ...@@ -479,10 +487,8 @@ static inline int lt_selfwrite(toku_lock_tree* tree, TXNID txn,
} }
assert(forest); assert(forest);
if (!forest->self_write) { if (!forest->self_write) {
r = toku_rt_create(&forest->self_write, r = toku_rt_create(&forest->self_write, toku_lt_point_cmp, lt_txn_cmp, FALSE,
toku_lt_point_cmp, lt_txn_cmp, toku_ltm_incr_lock_memory, toku_ltm_decr_lock_memory, tree->mgr);
FALSE,
tree->malloc, tree->free, tree->realloc);
if (r != 0) if (r != 0)
goto cleanup; goto cleanup;
assert(forest->self_write); assert(forest->self_write);
...@@ -493,9 +499,10 @@ cleanup: ...@@ -493,9 +499,10 @@ cleanup:
return r; return r;
} }
static inline BOOL interval_dominated(toku_interval* query, toku_interval* by) { static inline bool
interval_dominated(toku_interval* query, toku_interval* by) {
assert(query && by); assert(query && by);
return (BOOL)(toku_lt_point_cmp(query->left, by->left) >= 0 && return (bool)(toku_lt_point_cmp(query->left, by->left) >= 0 &&
toku_lt_point_cmp(query->right, by->right) <= 0); toku_lt_point_cmp(query->right, by->right) <= 0);
} }
...@@ -504,15 +511,15 @@ static inline BOOL interval_dominated(toku_interval* query, toku_interval* by) { ...@@ -504,15 +511,15 @@ static inline BOOL interval_dominated(toku_interval* query, toku_interval* by) {
Uses the standard definition of dominated from the design document. Uses the standard definition of dominated from the design document.
Determines whether 'query' is dominated by 'rt'. Determines whether 'query' is dominated by 'rt'.
*/ */
static inline int lt_rt_dominates(toku_lock_tree* tree, toku_interval* query, static inline int
toku_range_tree* rt, BOOL* dominated) { lt_rt_dominates(toku_lock_tree* tree, toku_interval* query, toku_range_tree* rt, bool* dominated) {
assert(tree && query && dominated); assert(tree && query && dominated);
if (!rt) { if (!rt) {
*dominated = FALSE; *dominated = FALSE;
return 0; return 0;
} }
BOOL allow_overlaps; bool allow_overlaps;
const uint32_t query_size = 1; const uint32_t query_size = 1;
toku_range buffer[query_size]; toku_range buffer[query_size];
uint32_t buflen = query_size; uint32_t buflen = query_size;
...@@ -550,7 +557,8 @@ typedef enum {TOKU_NO_CONFLICT, TOKU_MAYBE_CONFLICT, TOKU_YES_CONFLICT} toku_con ...@@ -550,7 +557,8 @@ typedef enum {TOKU_NO_CONFLICT, TOKU_MAYBE_CONFLICT, TOKU_YES_CONFLICT} toku_con
If exactly one range overlaps and its data != self, there might be a If exactly one range overlaps and its data != self, there might be a
conflict. We need to check the 'peer'write table to verify. conflict. We need to check the 'peer'write table to verify.
*/ */
static inline int lt_borderwrite_conflict(toku_lock_tree* tree, TXNID self, static inline int
lt_borderwrite_conflict(toku_lock_tree* tree, TXNID self,
toku_interval* query, toku_interval* query,
toku_conflict* conflict, TXNID* peer) { toku_conflict* conflict, TXNID* peer) {
assert(tree && query && conflict && peer); assert(tree && query && conflict && peer);
...@@ -586,7 +594,8 @@ static inline int lt_borderwrite_conflict(toku_lock_tree* tree, TXNID self, ...@@ -586,7 +594,8 @@ static inline int lt_borderwrite_conflict(toku_lock_tree* tree, TXNID self,
Uses the standard definition of 'query' meets 'tree' at 'data' from the Uses the standard definition of 'query' meets 'tree' at 'data' from the
design document. design document.
*/ */
static inline int lt_meets(toku_lock_tree* tree, toku_interval* query, toku_range_tree* rt, BOOL* met) { static inline int
lt_meets(toku_lock_tree* tree, toku_interval* query, toku_range_tree* rt, bool* met) {
assert(tree && query && rt && met); assert(tree && query && rt && met);
const uint32_t query_size = 1; const uint32_t query_size = 1;
toku_range buffer[query_size]; toku_range buffer[query_size];
...@@ -594,7 +603,7 @@ static inline int lt_meets(toku_lock_tree* tree, toku_interval* query, toku_rang ...@@ -594,7 +603,7 @@ static inline int lt_meets(toku_lock_tree* tree, toku_interval* query, toku_rang
toku_range* buf = &buffer[0]; toku_range* buf = &buffer[0];
uint32_t numfound; uint32_t numfound;
int r; int r;
BOOL allow_overlaps; bool allow_overlaps;
/* Sanity check. (Function only supports non-overlap range trees.) */ /* Sanity check. (Function only supports non-overlap range trees.) */
r = toku_rt_get_allow_overlaps(rt, &allow_overlaps); r = toku_rt_get_allow_overlaps(rt, &allow_overlaps);
...@@ -606,7 +615,7 @@ static inline int lt_meets(toku_lock_tree* tree, toku_interval* query, toku_rang ...@@ -606,7 +615,7 @@ static inline int lt_meets(toku_lock_tree* tree, toku_interval* query, toku_rang
if (r != 0) if (r != 0)
return r; return r;
assert(numfound <= query_size); assert(numfound <= query_size);
*met = (BOOL)(numfound != 0); *met = (bool)(numfound != 0);
return 0; return 0;
} }
...@@ -617,9 +626,10 @@ static inline int lt_meets(toku_lock_tree* tree, toku_interval* query, toku_rang ...@@ -617,9 +626,10 @@ static inline int lt_meets(toku_lock_tree* tree, toku_interval* query, toku_rang
Uses the standard definition of 'query' meets 'tree' at 'data' from the Uses the standard definition of 'query' meets 'tree' at 'data' from the
design document. design document.
*/ */
static inline int lt_meets_peer(toku_lock_tree* tree, toku_interval* query, static inline int
toku_range_tree* rt, BOOL is_homogenous, lt_meets_peer(toku_lock_tree* tree, toku_interval* query,
TXNID self, BOOL* met) { toku_range_tree* rt, bool is_homogenous,
TXNID self, bool* met) {
assert(tree && query && rt && met); assert(tree && query && rt && met);
assert(query->left == query->right || is_homogenous); assert(query->left == query->right || is_homogenous);
...@@ -634,15 +644,16 @@ static inline int lt_meets_peer(toku_lock_tree* tree, toku_interval* query, ...@@ -634,15 +644,16 @@ static inline int lt_meets_peer(toku_lock_tree* tree, toku_interval* query,
if (r != 0) if (r != 0)
return r; return r;
assert(numfound <= query_size); assert(numfound <= query_size);
*met = (BOOL) (numfound == 2 || (numfound == 1 && lt_txn_cmp(buf[0].data, self))); *met = (bool) (numfound == 2 || (numfound == 1 && lt_txn_cmp(buf[0].data, self)));
return 0; return 0;
} }
/* Checks for if a write range conflicts with reads. /* Checks for if a write range conflicts with reads.
Supports ranges. */ Supports ranges. */
static inline int lt_write_range_conflicts_reads(toku_lock_tree* tree, TXNID txn, toku_interval* query) { static inline int
lt_write_range_conflicts_reads(toku_lock_tree* tree, TXNID txn, toku_interval* query) {
int r = 0; int r = 0;
BOOL met = FALSE; bool met = FALSE;
toku_rth_start_scan(tree->rth); toku_rth_start_scan(tree->rth);
rt_forest* forest; rt_forest* forest;
...@@ -663,9 +674,10 @@ cleanup: ...@@ -663,9 +674,10 @@ cleanup:
#if !TOKU_LT_USE_BORDERWRITE #if !TOKU_LT_USE_BORDERWRITE
static inline int lt_write_range_conflicts_writes(toku_lock_tree* tree, TXNID txn, toku_interval* query) { static inline int
lt_write_range_conflicts_writes(toku_lock_tree* tree, TXNID txn, toku_interval* query) {
int r = 0; int r = 0;
BOOL met = FALSE; bool met = FALSE;
toku_rth_start_scan(tree->rth); toku_rth_start_scan(tree->rth);
rt_forest* forest; rt_forest* forest;
...@@ -690,7 +702,8 @@ cleanup: ...@@ -690,7 +702,8 @@ cleanup:
Utility function to implement: (from design document) Utility function to implement: (from design document)
if K meets E at v'!=t and K meets W_v' then return failure. if K meets E at v'!=t and K meets W_v' then return failure.
*/ */
static inline int lt_check_borderwrite_conflict(toku_lock_tree* tree, TXNID txn, toku_interval* query) { static inline int
lt_check_borderwrite_conflict(toku_lock_tree* tree, TXNID txn, toku_interval* query) {
#if TOKU_LT_USE_BORDERWRITE #if TOKU_LT_USE_BORDERWRITE
assert(tree && query); assert(tree && query);
toku_conflict conflict; toku_conflict conflict;
...@@ -706,7 +719,7 @@ static inline int lt_check_borderwrite_conflict(toku_lock_tree* tree, TXNID txn, ...@@ -706,7 +719,7 @@ static inline int lt_check_borderwrite_conflict(toku_lock_tree* tree, TXNID txn,
if (!peer_selfwrite) if (!peer_selfwrite)
return lt_panic(tree, TOKU_LT_INCONSISTENT); return lt_panic(tree, TOKU_LT_INCONSISTENT);
BOOL met; bool met;
r = lt_meets(tree, query, peer_selfwrite, &met); r = lt_meets(tree, query, peer_selfwrite, &met);
if (r != 0) if (r != 0)
return r; return r;
...@@ -722,7 +735,8 @@ static inline int lt_check_borderwrite_conflict(toku_lock_tree* tree, TXNID txn, ...@@ -722,7 +735,8 @@ static inline int lt_check_borderwrite_conflict(toku_lock_tree* tree, TXNID txn,
#endif #endif
} }
static inline void payload_from_dbt(void** payload, uint32_t* len, const DBT* dbt) { static inline void
payload_from_dbt(void** payload, uint32_t* len, const DBT* dbt) {
assert(payload && len && dbt); assert(payload && len && dbt);
if (lt_is_infinite(dbt)) *payload = (void*)dbt; if (lt_is_infinite(dbt)) *payload = (void*)dbt;
else if (!dbt->size) { else if (!dbt->size) {
...@@ -735,15 +749,16 @@ static inline void payload_from_dbt(void** payload, uint32_t* len, const DBT* db ...@@ -735,15 +749,16 @@ static inline void payload_from_dbt(void** payload, uint32_t* len, const DBT* db
} }
} }
static inline void init_point(toku_point* point, toku_lock_tree* tree, const DBT* key) { static inline void
init_point(toku_point* point, toku_lock_tree* tree, const DBT* key) {
assert(point && tree && key); assert(point && tree && key);
memset(point, 0, sizeof(toku_point)); memset(point, 0, sizeof(toku_point));
point->lt = tree; point->lt = tree;
payload_from_dbt(&point->key_payload, &point->key_len, key); payload_from_dbt(&point->key_payload, &point->key_len, key);
} }
static inline void init_query(toku_interval* query, toku_point* left, toku_point* right) { static inline void
init_query(toku_interval* query, toku_point* left, toku_point* right) {
query->left = left; query->left = left;
query->right = right; query->right = right;
} }
...@@ -761,9 +776,8 @@ static inline void init_query(toku_interval* query, toku_point* left, toku_point ...@@ -761,9 +776,8 @@ static inline void init_query(toku_interval* query, toku_point* left, toku_point
we made copies from the DB at consolidation time we made copies from the DB at consolidation time
*/ */
static inline void init_insert(toku_range* to_insert, static inline void
toku_point* left, toku_point* right, init_insert(toku_range* to_insert, toku_point* left, toku_point* right, TXNID txn) {
TXNID txn) {
to_insert->ends.left = left; to_insert->ends.left = left;
to_insert->ends.right = right; to_insert->ends.right = right;
to_insert->data = txn; to_insert->data = txn;
...@@ -771,14 +785,16 @@ static inline void init_insert(toku_range* to_insert, ...@@ -771,14 +785,16 @@ static inline void init_insert(toku_range* to_insert,
/* Returns whether the point already exists /* Returns whether the point already exists
as an endpoint of the given range. */ as an endpoint of the given range. */
static inline BOOL lt_p_independent(toku_point* point, toku_interval* range) { static inline bool
lt_p_independent(toku_point* point, toku_interval* range) {
assert(point && range); assert(point && range);
return (BOOL)(point != range->left && point != range->right); return (bool)(point != range->left && point != range->right);
} }
static inline int lt_determine_extreme(toku_lock_tree* tree, static inline int
lt_determine_extreme(toku_lock_tree* tree,
toku_range* to_insert, toku_range* to_insert,
BOOL* alloc_left, BOOL* alloc_right, bool* alloc_left, BOOL* alloc_right,
uint32_t numfound, uint32_t numfound,
uint32_t start_at) { uint32_t start_at) {
assert(to_insert && tree && alloc_left && alloc_right); assert(to_insert && tree && alloc_left && alloc_right);
...@@ -811,28 +827,25 @@ static inline int lt_determine_extreme(toku_lock_tree* tree, ...@@ -811,28 +827,25 @@ static inline int lt_determine_extreme(toku_lock_tree* tree,
} }
/* Find extreme given a starting point. */ /* Find extreme given a starting point. */
static inline int lt_extend_extreme(toku_lock_tree* tree,toku_range* to_insert, static inline int
BOOL* alloc_left, BOOL* alloc_right, lt_extend_extreme(toku_lock_tree* tree,toku_range* to_insert, bool* alloc_left, BOOL* alloc_right, uint32_t numfound) {
uint32_t numfound) { return lt_determine_extreme(tree, to_insert, alloc_left, alloc_right, numfound, 0);
return lt_determine_extreme(tree, to_insert, alloc_left, alloc_right,
numfound, 0);
} }
/* Has no starting point. */ /* Has no starting point. */
static inline int lt_find_extreme(toku_lock_tree* tree, static inline int
toku_range* to_insert, lt_find_extreme(toku_lock_tree* tree, toku_range* to_insert, uint32_t numfound) {
uint32_t numfound) {
assert(numfound > 0); assert(numfound > 0);
*to_insert = tree->buf[0]; *to_insert = tree->buf[0];
BOOL ignore_left = TRUE; bool ignore_left = TRUE;
BOOL ignore_right = TRUE; bool ignore_right = TRUE;
return lt_determine_extreme(tree, to_insert, &ignore_left, &ignore_right, numfound, 1); return lt_determine_extreme(tree, to_insert, &ignore_left, &ignore_right, numfound, 1);
} }
static inline int lt_alloc_extreme(toku_lock_tree* tree, toku_range* to_insert, static inline int
BOOL alloc_left, BOOL* alloc_right) { lt_alloc_extreme(toku_lock_tree* tree, toku_range* to_insert, bool alloc_left, BOOL* alloc_right) {
assert(to_insert && alloc_right); assert(to_insert && alloc_right);
BOOL copy_left = FALSE; bool copy_left = FALSE;
int r; int r;
/* The pointer comparison may speed up the evaluation in some cases, /* The pointer comparison may speed up the evaluation in some cases,
...@@ -866,9 +879,8 @@ static inline int lt_alloc_extreme(toku_lock_tree* tree, toku_range* to_insert, ...@@ -866,9 +879,8 @@ static inline int lt_alloc_extreme(toku_lock_tree* tree, toku_range* to_insert,
return 0; return 0;
} }
static inline int lt_delete_overlapping_ranges(toku_lock_tree* tree, static inline int
toku_range_tree* rt, lt_delete_overlapping_ranges(toku_lock_tree* tree, toku_range_tree* rt, uint32_t numfound) {
uint32_t numfound) {
assert(tree && rt); assert(tree && rt);
int r; int r;
uint32_t i; uint32_t i;
...@@ -881,7 +893,8 @@ static inline int lt_delete_overlapping_ranges(toku_lock_tree* tree, ...@@ -881,7 +893,8 @@ static inline int lt_delete_overlapping_ranges(toku_lock_tree* tree,
return 0; return 0;
} }
static inline int lt_free_points(toku_lock_tree* tree, toku_interval* to_insert, uint32_t numfound) { static inline int
lt_free_points(toku_lock_tree* tree, toku_interval* to_insert, uint32_t numfound) {
assert(tree && to_insert); assert(tree && to_insert);
assert(numfound <= tree->buflen); assert(numfound <= tree->buflen);
...@@ -908,13 +921,13 @@ static inline int lt_borderwrite_insert(toku_lock_tree* tree, toku_interval* que ...@@ -908,13 +921,13 @@ static inline int lt_borderwrite_insert(toku_lock_tree* tree, toku_interval* que
If found_only is TRUE, we're only consolidating existing ranges in the interval If found_only is TRUE, we're only consolidating existing ranges in the interval
specified inside of to_insert. specified inside of to_insert.
*/ */
static inline int consolidate_range_tree(toku_lock_tree* tree, BOOL found_only, toku_range* to_insert, toku_range_tree *rt, static inline int
BOOL do_borderwrite_insert) { consolidate_range_tree(toku_lock_tree* tree, bool found_only, toku_range* to_insert, toku_range_tree *rt, bool do_borderwrite_insert) {
assert(tree && to_insert); assert(tree && to_insert);
int r; int r;
BOOL alloc_left = TRUE; bool alloc_left = TRUE;
BOOL alloc_right = TRUE; bool alloc_right = TRUE;
toku_interval* query = &to_insert->ends; toku_interval* query = &to_insert->ends;
/* Find all overlapping ranges in the range tree */ /* Find all overlapping ranges in the range tree */
...@@ -938,8 +951,6 @@ static inline int consolidate_range_tree(toku_lock_tree* tree, BOOL found_only, ...@@ -938,8 +951,6 @@ static inline int consolidate_range_tree(toku_lock_tree* tree, BOOL found_only,
r = lt_extend_extreme(tree, to_insert, &alloc_left, &alloc_right, numfound); r = lt_extend_extreme(tree, to_insert, &alloc_left, &alloc_right, numfound);
if (r != 0) if (r != 0)
return r; return r;
if (!ltm_lock_test_incr(tree->mgr, numfound))
return TOKUDB_OUT_OF_LOCKS;
} }
/* Allocate the consolidated range */ /* Allocate the consolidated range */
r = lt_alloc_extreme(tree, to_insert, alloc_left, &alloc_right); r = lt_alloc_extreme(tree, to_insert, alloc_left, &alloc_right);
...@@ -950,6 +961,7 @@ static inline int consolidate_range_tree(toku_lock_tree* tree, BOOL found_only, ...@@ -950,6 +961,7 @@ static inline int consolidate_range_tree(toku_lock_tree* tree, BOOL found_only,
} }
if (r != 0) if (r != 0)
return r; return r;
/* From this point on we have to panic if we cannot finish. */ /* From this point on we have to panic if we cannot finish. */
/* Delete overlapping ranges from range tree ... */ /* Delete overlapping ranges from range tree ... */
r = lt_delete_overlapping_ranges(tree, rt, numfound); r = lt_delete_overlapping_ranges(tree, rt, numfound);
...@@ -980,11 +992,12 @@ static inline int consolidate_range_tree(toku_lock_tree* tree, BOOL found_only, ...@@ -980,11 +992,12 @@ static inline int consolidate_range_tree(toku_lock_tree* tree, BOOL found_only,
goto died1; goto died1;
} }
ltm_lock_incr(tree->mgr, numfound); ltm_incr_locks(tree->mgr, numfound);
return 0; return 0;
} }
static inline int consolidate_reads(toku_lock_tree* tree, BOOL found_only, toku_range* to_insert, TXNID txn) { static inline int
consolidate_reads(toku_lock_tree* tree, bool found_only, toku_range* to_insert, TXNID txn) {
assert(tree && to_insert); assert(tree && to_insert);
toku_range_tree* selfread; toku_range_tree* selfread;
int r = lt_selfread(tree, txn, &selfread); int r = lt_selfread(tree, txn, &selfread);
...@@ -994,7 +1007,8 @@ static inline int consolidate_reads(toku_lock_tree* tree, BOOL found_only, toku_ ...@@ -994,7 +1007,8 @@ static inline int consolidate_reads(toku_lock_tree* tree, BOOL found_only, toku_
return consolidate_range_tree(tree, found_only, to_insert, selfread, FALSE); return consolidate_range_tree(tree, found_only, to_insert, selfread, FALSE);
} }
static inline int consolidate_writes(toku_lock_tree* tree, toku_range* to_insert, TXNID txn) { static inline int
consolidate_writes(toku_lock_tree* tree, toku_range* to_insert, TXNID txn) {
assert(tree && to_insert); assert(tree && to_insert);
toku_range_tree* selfwrite; toku_range_tree* selfwrite;
int r = lt_selfwrite(tree, txn, &selfwrite); int r = lt_selfwrite(tree, txn, &selfwrite);
...@@ -1004,8 +1018,8 @@ static inline int consolidate_writes(toku_lock_tree* tree, toku_range* to_insert ...@@ -1004,8 +1018,8 @@ static inline int consolidate_writes(toku_lock_tree* tree, toku_range* to_insert
return consolidate_range_tree(tree, FALSE, to_insert, selfwrite, TRUE); return consolidate_range_tree(tree, FALSE, to_insert, selfwrite, TRUE);
} }
static inline void lt_init_full_query(toku_lock_tree* tree, toku_interval* query, static inline void
toku_point* left, toku_point* right) { lt_init_full_query(toku_lock_tree* tree, toku_interval* query, toku_point* left, toku_point* right) {
init_point(left, tree, (DBT*)toku_lt_neg_infinity); init_point(left, tree, (DBT*)toku_lt_neg_infinity);
init_point(right, tree, (DBT*)toku_lt_infinity); init_point(right, tree, (DBT*)toku_lt_infinity);
init_query(query, left, right); init_query(query, left, right);
...@@ -1017,7 +1031,8 @@ typedef struct { ...@@ -1017,7 +1031,8 @@ typedef struct {
toku_range* store_value; toku_range* store_value;
} free_contents_info; } free_contents_info;
static int free_contents_helper(toku_range* value, void* extra) { static int
free_contents_helper(toku_range* value, void* extra) {
free_contents_info* info = extra; free_contents_info* info = extra;
int r = ENOSYS; int r = ENOSYS;
...@@ -1033,7 +1048,8 @@ static int free_contents_helper(toku_range* value, void* extra) { ...@@ -1033,7 +1048,8 @@ static int free_contents_helper(toku_range* value, void* extra) {
lt_free_points should be replaced (or supplanted) with a lt_free_points should be replaced (or supplanted) with a
lt_free_point (singular) lt_free_point (singular)
*/ */
static inline int lt_free_contents(toku_lock_tree* tree, toku_range_tree* rt, BOOL doclose) { static inline int
lt_free_contents(toku_lock_tree* tree, toku_range_tree* rt) {
assert(tree); assert(tree);
if (!rt) if (!rt)
return 0; return 0;
...@@ -1051,44 +1067,42 @@ static inline int lt_free_contents(toku_lock_tree* tree, toku_range_tree* rt, BO ...@@ -1051,44 +1067,42 @@ static inline int lt_free_contents(toku_lock_tree* tree, toku_range_tree* rt, BO
if ((r = toku_rt_iterate(rt, free_contents_helper, &info))) if ((r = toku_rt_iterate(rt, free_contents_helper, &info)))
return r; return r;
if (doclose)
r = toku_rt_close(rt); r = toku_rt_close(rt);
else {
r = 0;
toku_rt_clear(rt);
}
assert_zero(r); assert_zero(r);
return r; return r;
} }
static inline BOOL r_backwards(toku_interval* range) { static inline bool
r_backwards(toku_interval* range) {
assert(range && range->left && range->right); assert(range && range->left && range->right);
toku_point* left = (toku_point*)range->left; toku_point* left = (toku_point*)range->left;
toku_point* right = (toku_point*)range->right; toku_point* right = (toku_point*)range->right;
/* Optimization: if all the pointers are equal, clearly left == right. */ /* Optimization: if all the pointers are equal, clearly left == right. */
return (BOOL) ((left->key_payload != right->key_payload) && return (bool) ((left->key_payload != right->key_payload) &&
(toku_lt_point_cmp(left, right) > 0)); (toku_lt_point_cmp(left, right) > 0));
} }
static inline int lt_unlock_deferred_txns(toku_lock_tree* tree); static inline int lt_unlock_deferred_txns(toku_lock_tree* tree);
static inline void lt_set_comparison_functions(toku_lock_tree* tree, static inline void
DB* db) { lt_set_comparison_functions(toku_lock_tree* tree, DB* db) {
assert(!tree->db && !tree->compare_fun); assert(!tree->db && !tree->compare_fun);
tree->db = db; tree->db = db;
tree->compare_fun = tree->get_compare_fun_from_db(tree->db); tree->compare_fun = tree->get_compare_fun_from_db(tree->db);
assert(tree->compare_fun); assert(tree->compare_fun);
} }
static inline void lt_clear_comparison_functions(toku_lock_tree* tree) { static inline void
lt_clear_comparison_functions(toku_lock_tree* tree) {
assert(tree); assert(tree);
tree->db = NULL; tree->db = NULL;
tree->compare_fun = NULL; tree->compare_fun = NULL;
} }
/* Preprocess step for acquire functions. */ /* Preprocess step for acquire functions. */
static inline int lt_preprocess(toku_lock_tree* tree, DB* db, static inline int
lt_preprocess(toku_lock_tree* tree, DB* db,
__attribute__((unused)) TXNID txn, __attribute__((unused)) TXNID txn,
const DBT* key_left, const DBT* key_left,
const DBT* key_right, const DBT* key_right,
...@@ -1130,13 +1144,15 @@ cleanup: ...@@ -1130,13 +1144,15 @@ cleanup:
} }
/* Postprocess step for acquire functions. */ /* Postprocess step for acquire functions. */
static inline void lt_postprocess(toku_lock_tree* tree) { static inline void
lt_postprocess(toku_lock_tree* tree) {
lt_clear_comparison_functions(tree); lt_clear_comparison_functions(tree);
} }
static inline int lt_get_border_in_selfwrite(toku_lock_tree* tree, static inline int
lt_get_border_in_selfwrite(toku_lock_tree* tree,
toku_range* pred, toku_range* succ, toku_range* pred, toku_range* succ,
BOOL* found_p, BOOL* found_s, bool* found_p, BOOL* found_s,
toku_range* to_insert) { toku_range* to_insert) {
assert(tree && pred && succ && found_p && found_s); assert(tree && pred && succ && found_p && found_s);
int r; int r;
...@@ -1152,9 +1168,10 @@ static inline int lt_get_border_in_selfwrite(toku_lock_tree* tree, ...@@ -1152,9 +1168,10 @@ static inline int lt_get_border_in_selfwrite(toku_lock_tree* tree,
return 0; return 0;
} }
static inline int lt_get_border_in_borderwrite(toku_lock_tree* tree, static inline int
lt_get_border_in_borderwrite(toku_lock_tree* tree,
toku_range* pred, toku_range* succ, toku_range* pred, toku_range* succ,
BOOL* found_p, BOOL* found_s, bool* found_p, BOOL* found_s,
toku_range* to_insert) { toku_range* to_insert) {
assert(tree && pred && succ && found_p && found_s); assert(tree && pred && succ && found_p && found_s);
int r; int r;
...@@ -1170,9 +1187,10 @@ static inline int lt_get_border_in_borderwrite(toku_lock_tree* tree, ...@@ -1170,9 +1187,10 @@ static inline int lt_get_border_in_borderwrite(toku_lock_tree* tree,
return 0; return 0;
} }
static inline int lt_expand_border(toku_lock_tree* tree, toku_range* to_insert, static inline int
lt_expand_border(toku_lock_tree* tree, toku_range* to_insert,
toku_range* pred, toku_range* succ, toku_range* pred, toku_range* succ,
BOOL found_p, BOOL found_s) { bool found_p, BOOL found_s) {
assert(tree && to_insert && pred && succ); assert(tree && to_insert && pred && succ);
int r; int r;
if (found_p && !lt_txn_cmp(pred->data, to_insert->data)) { if (found_p && !lt_txn_cmp(pred->data, to_insert->data)) {
...@@ -1190,9 +1208,10 @@ static inline int lt_expand_border(toku_lock_tree* tree, toku_range* to_insert, ...@@ -1190,9 +1208,10 @@ static inline int lt_expand_border(toku_lock_tree* tree, toku_range* to_insert,
return 0; return 0;
} }
static inline int lt_split_border(toku_lock_tree* tree, toku_range* to_insert, static inline int
lt_split_border(toku_lock_tree* tree, toku_range* to_insert,
toku_range* pred, toku_range* succ, toku_range* pred, toku_range* succ,
BOOL found_p, BOOL found_s) { bool found_p, BOOL found_s) {
assert(tree && to_insert && pred && succ); assert(tree && to_insert && pred && succ);
int r; int r;
assert(lt_txn_cmp(tree->bw_buf[0].data, to_insert->data)); assert(lt_txn_cmp(tree->bw_buf[0].data, to_insert->data));
...@@ -1220,9 +1239,8 @@ static inline int lt_split_border(toku_lock_tree* tree, toku_range* to_insert, ...@@ -1220,9 +1239,8 @@ static inline int lt_split_border(toku_lock_tree* tree, toku_range* to_insert,
/* /*
NO MEMORY GETS FREED!!!!!!!!!!, it all is tied to selfwrites. NO MEMORY GETS FREED!!!!!!!!!!, it all is tied to selfwrites.
*/ */
static inline int lt_borderwrite_insert(toku_lock_tree* tree, static inline int
toku_interval* query, lt_borderwrite_insert(toku_lock_tree* tree, toku_interval* query, toku_range* to_insert) {
toku_range* to_insert) {
assert(tree && query && to_insert); assert(tree && query && to_insert);
int r; int r;
toku_range_tree* borderwrite = tree->borderwrite; toku_range_tree* borderwrite = tree->borderwrite;
...@@ -1240,8 +1258,8 @@ static inline int lt_borderwrite_insert(toku_lock_tree* tree, ...@@ -1240,8 +1258,8 @@ static inline int lt_borderwrite_insert(toku_lock_tree* tree,
// Find the adjacent ranges in the borderwrite tree and expand them if they are owned by me // Find the adjacent ranges in the borderwrite tree and expand them if they are owned by me
// Find the predecessor and successor of the range to be inserted // Find the predecessor and successor of the range to be inserted
toku_range pred; BOOL found_p = FALSE; toku_range pred; bool found_p = FALSE;
toku_range succ; BOOL found_s = FALSE; toku_range succ; bool found_s = FALSE;
r = lt_get_border_in_borderwrite(tree, &pred, &succ, &found_p, &found_s, to_insert); r = lt_get_border_in_borderwrite(tree, &pred, &succ, &found_p, &found_s, to_insert);
if (r != 0) if (r != 0)
return lt_panic(tree, r); return lt_panic(tree, r);
...@@ -1276,8 +1294,8 @@ static inline int lt_borderwrite_insert(toku_lock_tree* tree, ...@@ -1276,8 +1294,8 @@ static inline int lt_borderwrite_insert(toku_lock_tree* tree,
// Split the borderwrite range to remove the overlap with the range being inserted. // Split the borderwrite range to remove the overlap with the range being inserted.
// Find predecessor and successor of the range to be inserted // Find predecessor and successor of the range to be inserted
toku_range pred; BOOL found_p = FALSE; toku_range pred; bool found_p = FALSE;
toku_range succ; BOOL found_s = FALSE; toku_range succ; bool found_s = FALSE;
r = lt_get_border_in_selfwrite(tree, &pred, &succ, &found_p, &found_s, to_insert); r = lt_get_border_in_selfwrite(tree, &pred, &succ, &found_p, &found_s, to_insert);
if (r != 0) if (r != 0)
return lt_panic(tree, r); return lt_panic(tree, r);
...@@ -1294,52 +1312,46 @@ static inline int lt_borderwrite_insert(toku_lock_tree* tree, ...@@ -1294,52 +1312,46 @@ static inline int lt_borderwrite_insert(toku_lock_tree* tree,
} }
/* TODO: Investigate better way of passing comparison functions. */ /* TODO: Investigate better way of passing comparison functions. */
int toku_lt_create(toku_lock_tree** ptree, int
toku_lt_create(toku_lock_tree** ptree,
int (*panic)(DB*, int), int (*panic)(DB*, int),
toku_ltm* mgr, toku_ltm* mgr,
toku_dbt_cmp (*get_compare_fun_from_db)(DB*), toku_dbt_cmp (*get_compare_fun_from_db)(DB*)) {
void* (*user_malloc) (size_t),
void (*user_free) (void*),
void* (*user_realloc)(void*, size_t)) {
int r = ENOSYS; int r = ENOSYS;
toku_lock_tree* tmp_tree = NULL; toku_lock_tree* tmp_tree = NULL;
if (!ptree || !mgr || if (!ptree || !mgr ||
!get_compare_fun_from_db || !panic || !get_compare_fun_from_db || !panic) {
!user_malloc || !user_free || !user_realloc) {
r = EINVAL; goto cleanup; r = EINVAL; goto cleanup;
} }
tmp_tree = (toku_lock_tree*)user_malloc(sizeof(*tmp_tree)); tmp_tree = (toku_lock_tree*)toku_malloc(sizeof(*tmp_tree));
if (!tmp_tree) { r = ENOMEM; goto cleanup; } if (!tmp_tree) { r = ENOMEM; goto cleanup; }
memset(tmp_tree, 0, sizeof(toku_lock_tree)); memset(tmp_tree, 0, sizeof(toku_lock_tree));
tmp_tree->panic = panic; tmp_tree->panic = panic;
tmp_tree->mgr = mgr; tmp_tree->mgr = mgr;
tmp_tree->malloc = user_malloc;
tmp_tree->free = user_free;
tmp_tree->realloc = user_realloc;
tmp_tree->get_compare_fun_from_db = get_compare_fun_from_db; tmp_tree->get_compare_fun_from_db = get_compare_fun_from_db;
tmp_tree->lock_escalation_allowed = TRUE; tmp_tree->lock_escalation_allowed = TRUE;
r = toku_rt_create(&tmp_tree->borderwrite, r = toku_rt_create(&tmp_tree->borderwrite, toku_lt_point_cmp, lt_txn_cmp, FALSE,
toku_lt_point_cmp, lt_txn_cmp, FALSE, toku_ltm_incr_lock_memory, toku_ltm_decr_lock_memory, mgr);
user_malloc, user_free, user_realloc);
if (r != 0) if (r != 0)
goto cleanup; goto cleanup;
r = toku_rth_create(&tmp_tree->rth, user_malloc, user_free, user_realloc);
r = toku_rth_create(&tmp_tree->rth);
if (r != 0) if (r != 0)
goto cleanup; goto cleanup;
r = toku_rth_create(&tmp_tree->txns_to_unlock, user_malloc, user_free, user_realloc); r = toku_rth_create(&tmp_tree->txns_to_unlock);
if (r != 0) if (r != 0)
goto cleanup; goto cleanup;
r = toku_rth_create(&tmp_tree->txns_still_locked, user_malloc, user_free, user_realloc); r = toku_rth_create(&tmp_tree->txns_still_locked);
if (r != 0) if (r != 0)
goto cleanup; goto cleanup;
tmp_tree->buflen = __toku_default_buflen; tmp_tree->buflen = __toku_default_buflen;
tmp_tree->buf = (toku_range*) tmp_tree->buf = (toku_range*)
user_malloc(tmp_tree->buflen * sizeof(toku_range)); toku_malloc(tmp_tree->buflen * sizeof(toku_range));
if (!tmp_tree->buf) { r = ENOMEM; goto cleanup; } if (!tmp_tree->buf) { r = ENOMEM; goto cleanup; }
tmp_tree->bw_buflen = __toku_default_buflen; tmp_tree->bw_buflen = __toku_default_buflen;
tmp_tree->bw_buf = (toku_range*) tmp_tree->bw_buf = (toku_range*)
user_malloc(tmp_tree->bw_buflen * sizeof(toku_range)); toku_malloc(tmp_tree->bw_buflen * sizeof(toku_range));
if (!tmp_tree->bw_buf) { r = ENOMEM; goto cleanup; } if (!tmp_tree->bw_buf) { r = ENOMEM; goto cleanup; }
r = toku_omt_create(&tmp_tree->dbs); r = toku_omt_create(&tmp_tree->dbs);
if (r != 0) if (r != 0)
...@@ -1352,7 +1364,6 @@ int toku_lt_create(toku_lock_tree** ptree, ...@@ -1352,7 +1364,6 @@ int toku_lt_create(toku_lock_tree** ptree,
cleanup: cleanup:
if (r != 0) { if (r != 0) {
if (tmp_tree) { if (tmp_tree) {
assert(user_free);
if (tmp_tree->borderwrite) if (tmp_tree->borderwrite)
toku_rt_close(tmp_tree->borderwrite); toku_rt_close(tmp_tree->borderwrite);
if (tmp_tree->rth) if (tmp_tree->rth)
...@@ -1360,18 +1371,19 @@ cleanup: ...@@ -1360,18 +1371,19 @@ cleanup:
if (tmp_tree->txns_to_unlock) if (tmp_tree->txns_to_unlock)
toku_rth_close(tmp_tree->txns_to_unlock); toku_rth_close(tmp_tree->txns_to_unlock);
if (tmp_tree->buf) if (tmp_tree->buf)
user_free(tmp_tree->buf); toku_free(tmp_tree->buf);
if (tmp_tree->bw_buf) if (tmp_tree->bw_buf)
user_free(tmp_tree->bw_buf); toku_free(tmp_tree->bw_buf);
if (tmp_tree->dbs) if (tmp_tree->dbs)
toku_omt_destroy(&tmp_tree->dbs); toku_omt_destroy(&tmp_tree->dbs);
user_free(tmp_tree); toku_free(tmp_tree);
} }
} }
return r; return r;
} }
void toku_ltm_invalidate_lt(toku_ltm* mgr, DICTIONARY_ID dict_id) { void
toku_ltm_invalidate_lt(toku_ltm* mgr, DICTIONARY_ID dict_id) {
assert(mgr && dict_id.dictid != DICTIONARY_ID_NONE.dictid); assert(mgr && dict_id.dictid != DICTIONARY_ID_NONE.dictid);
toku_lt_map* map = NULL; toku_lt_map* map = NULL;
map = toku_idlth_find(mgr->idlth, dict_id); map = toku_idlth_find(mgr->idlth, dict_id);
...@@ -1381,7 +1393,8 @@ void toku_ltm_invalidate_lt(toku_ltm* mgr, DICTIONARY_ID dict_id) { ...@@ -1381,7 +1393,8 @@ void toku_ltm_invalidate_lt(toku_ltm* mgr, DICTIONARY_ID dict_id) {
} }
static inline void toku_lt_set_dict_id(toku_lock_tree* lt, DICTIONARY_ID dict_id) { static inline void
toku_lt_set_dict_id(toku_lock_tree* lt, DICTIONARY_ID dict_id) {
assert(lt && dict_id.dictid != DICTIONARY_ID_NONE.dictid); assert(lt && dict_id.dictid != DICTIONARY_ID_NONE.dictid);
lt->dict_id = dict_id; lt->dict_id = dict_id;
} }
...@@ -1389,16 +1402,17 @@ static inline void toku_lt_set_dict_id(toku_lock_tree* lt, DICTIONARY_ID dict_id ...@@ -1389,16 +1402,17 @@ static inline void toku_lt_set_dict_id(toku_lock_tree* lt, DICTIONARY_ID dict_id
static void lt_add_db(toku_lock_tree* tree, DB *db); static void lt_add_db(toku_lock_tree* tree, DB *db);
static void lt_remove_db(toku_lock_tree* tree, DB *db); static void lt_remove_db(toku_lock_tree* tree, DB *db);
int toku_ltm_get_lt(toku_ltm* mgr, toku_lock_tree** ptree, int
toku_ltm_get_lt(toku_ltm* mgr, toku_lock_tree** ptree,
DICTIONARY_ID dict_id, DB *db) { DICTIONARY_ID dict_id, DB *db) {
/* first look in hash table to see if lock tree exists for that db, /* first look in hash table to see if lock tree exists for that db,
if so return it */ if so return it */
int r = ENOSYS; int r = ENOSYS;
toku_lt_map* map = NULL; toku_lt_map* map = NULL;
toku_lock_tree* tree = NULL; toku_lock_tree* tree = NULL;
BOOL added_to_ltm = FALSE; bool added_to_ltm = FALSE;
BOOL added_to_idlth = FALSE; bool added_to_idlth = FALSE;
BOOL added_extant_db = FALSE; bool added_extant_db = FALSE;
map = toku_idlth_find(mgr->idlth, dict_id); map = toku_idlth_find(mgr->idlth, dict_id);
if (map != NULL) { if (map != NULL) {
...@@ -1412,9 +1426,7 @@ int toku_ltm_get_lt(toku_ltm* mgr, toku_lock_tree** ptree, ...@@ -1412,9 +1426,7 @@ int toku_ltm_get_lt(toku_ltm* mgr, toku_lock_tree** ptree,
goto cleanup; goto cleanup;
} }
/* Must create new lock tree for this dict_id*/ /* Must create new lock tree for this dict_id*/
r = toku_lt_create(&tree, mgr->panic, mgr, r = toku_lt_create(&tree, mgr->panic, mgr, mgr->get_compare_fun_from_db);
mgr->get_compare_fun_from_db,
mgr->malloc, mgr->free, mgr->realloc);
if (r != 0) if (r != 0)
goto cleanup; goto cleanup;
toku_lt_set_dict_id(tree, dict_id); toku_lt_set_dict_id(tree, dict_id);
...@@ -1455,7 +1467,8 @@ cleanup: ...@@ -1455,7 +1467,8 @@ cleanup:
return r; return r;
} }
int toku_lt_close(toku_lock_tree* tree) { int
toku_lt_close(toku_lock_tree* tree) {
int r = ENOSYS; int r = ENOSYS;
int first_error = 0; int first_error = 0;
if (!tree) { if (!tree) {
...@@ -1470,10 +1483,10 @@ int toku_lt_close(toku_lock_tree* tree) { ...@@ -1470,10 +1483,10 @@ int toku_lt_close(toku_lock_tree* tree) {
rt_forest* forest; rt_forest* forest;
while ((forest = toku_rth_next(tree->rth)) != NULL) { while ((forest = toku_rth_next(tree->rth)) != NULL) {
r = lt_free_contents(tree, forest->self_read, TRUE); r = lt_free_contents(tree, forest->self_read);
if (!first_error && r != 0) if (!first_error && r != 0)
first_error = r; first_error = r;
r = lt_free_contents(tree, forest->self_write, TRUE); r = lt_free_contents(tree, forest->self_write);
if (!first_error && r != 0) if (!first_error && r != 0)
first_error = r; first_error = r;
} }
...@@ -1482,37 +1495,30 @@ int toku_lt_close(toku_lock_tree* tree) { ...@@ -1482,37 +1495,30 @@ int toku_lt_close(toku_lock_tree* tree) {
toku_rth_close(tree->txns_still_locked); toku_rth_close(tree->txns_still_locked);
toku_omt_destroy(&tree->dbs); toku_omt_destroy(&tree->dbs);
tree->free(tree->buf); toku_free(tree->buf);
tree->free(tree->bw_buf); toku_free(tree->bw_buf);
tree->free(tree); toku_free(tree);
r = first_error; r = first_error;
cleanup: cleanup:
return r; return r;
} }
// toku_lt_acquire_read_lock() used only by test programs // toku_lt_acquire_read_lock() used only by test programs
int toku_lt_acquire_read_lock(toku_lock_tree* tree, int
DB* db, TXNID txn, toku_lt_acquire_read_lock(toku_lock_tree* tree, DB* db, TXNID txn, const DBT* key) {
const DBT* key) {
return toku_lt_acquire_range_read_lock(tree, db, txn, key, key); return toku_lt_acquire_range_read_lock(tree, db, txn, key, key);
} }
static int lt_try_acquire_range_read_lock(toku_lock_tree* tree, static int
DB* db, TXNID txn, lt_try_acquire_range_read_lock(toku_lock_tree* tree, DB* db, TXNID txn, const DBT* key_left, const DBT* key_right) {
const DBT* key_left,
const DBT* key_right) {
int r; int r;
toku_point left; toku_point left;
toku_point right; toku_point right;
toku_interval query; toku_interval query;
BOOL dominated; bool dominated;
r = lt_preprocess(tree, db, txn, r = lt_preprocess(tree, db, txn, key_left, key_right, &left, &right, &query);
key_left,
key_right,
&left, &right,
&query);
if (r != 0) if (r != 0)
goto cleanup; goto cleanup;
...@@ -1545,10 +1551,16 @@ static int lt_try_acquire_range_read_lock(toku_lock_tree* tree, ...@@ -1545,10 +1551,16 @@ static int lt_try_acquire_range_read_lock(toku_lock_tree* tree,
r = lt_check_borderwrite_conflict(tree, txn, &query); r = lt_check_borderwrite_conflict(tree, txn, &query);
if (r != 0) if (r != 0)
goto cleanup; goto cleanup;
/* Now need to merge, copy the memory and insert. */
// Check lock resource contraints
r = ltm_out_of_locks(tree->mgr);
if (r != 0)
goto cleanup;
// Now need to merge, copy the memory and insert
toku_range to_insert; toku_range to_insert;
init_insert(&to_insert, &left, &right, txn); init_insert(&to_insert, &left, &right, txn);
/* Consolidate the new range and all the overlapping ranges */ // Consolidate the new range and all the overlapping ranges
r = consolidate_reads(tree, FALSE, &to_insert, txn); r = consolidate_reads(tree, FALSE, &to_insert, txn);
if (r != 0) if (r != 0)
goto cleanup; goto cleanup;
...@@ -1564,9 +1576,8 @@ cleanup: ...@@ -1564,9 +1576,8 @@ cleanup:
Tests whether a range from BorderWrite is trivially escalatable. Tests whether a range from BorderWrite is trivially escalatable.
i.e. No read locks from other transactions overlap the range. i.e. No read locks from other transactions overlap the range.
*/ */
static inline int border_escalation_trivial(toku_lock_tree* tree, static inline int
toku_range* border_range, border_escalation_trivial(toku_lock_tree* tree, toku_range* border_range, bool* trivial) {
BOOL* trivial) {
assert(tree && border_range && trivial); assert(tree && border_range && trivial);
int r = ENOSYS; int r = ENOSYS;
...@@ -1585,9 +1596,8 @@ cleanup: ...@@ -1585,9 +1596,8 @@ cleanup:
return r; return r;
} }
/* */ static inline int
static inline int escalate_writes_from_border_range(toku_lock_tree* tree, escalate_writes_from_border_range(toku_lock_tree* tree, toku_range* border_range) {
toku_range* border_range) {
int r = ENOSYS; int r = ENOSYS;
if (!tree || !border_range) { if (!tree || !border_range) {
r = EINVAL; goto cleanup; r = EINVAL; goto cleanup;
...@@ -1635,16 +1645,15 @@ static inline int escalate_writes_from_border_range(toku_lock_tree* tree, ...@@ -1635,16 +1645,15 @@ static inline int escalate_writes_from_border_range(toku_lock_tree* tree,
if (r != 0) { if (r != 0) {
r = lt_panic(tree, r); goto cleanup; r = lt_panic(tree, r); goto cleanup;
} }
ltm_lock_incr(tree->mgr, numfound); ltm_incr_locks(tree->mgr, numfound);
r = 0; r = 0;
cleanup: cleanup:
return r; return r;
} }
static int lt_escalate_read_locks_in_interval(toku_lock_tree* tree, static int
toku_interval* query, lt_escalate_read_locks_in_interval(toku_lock_tree* tree, toku_interval* query, TXNID txn) {
TXNID txn) {
int r = ENOSYS; int r = ENOSYS;
toku_range to_insert; toku_range to_insert;
...@@ -1660,7 +1669,8 @@ typedef struct { ...@@ -1660,7 +1669,8 @@ typedef struct {
TXNID txn; TXNID txn;
} escalate_info; } escalate_info;
static int escalate_read_locks_helper(toku_range* border_range, void* extra) { static int
escalate_read_locks_helper(toku_range* border_range, void* extra) {
escalate_info* info = extra; escalate_info* info = extra;
int r = ENOSYS; int r = ENOSYS;
...@@ -1679,7 +1689,8 @@ cleanup: ...@@ -1679,7 +1689,8 @@ cleanup:
} }
//TODO: Whenever comparing TXNIDs use the comparison function INSTEAD of just '!= or ==' //TODO: Whenever comparing TXNIDs use the comparison function INSTEAD of just '!= or =='
static int lt_escalate_read_locks(toku_lock_tree* tree, TXNID txn) { static int
lt_escalate_read_locks(toku_lock_tree* tree, TXNID txn) {
int r = ENOSYS; int r = ENOSYS;
assert(tree); assert(tree);
assert(tree->lock_escalation_allowed); assert(tree->lock_escalation_allowed);
...@@ -1705,10 +1716,11 @@ cleanup: ...@@ -1705,10 +1716,11 @@ cleanup:
return r; return r;
} }
static int escalate_write_locks_helper(toku_range* border_range, void* extra) { static int
escalate_write_locks_helper(toku_range* border_range, void* extra) {
toku_lock_tree* tree = extra; toku_lock_tree* tree = extra;
int r = ENOSYS; int r = ENOSYS;
BOOL trivial; bool trivial;
if ((r = border_escalation_trivial(tree, border_range, &trivial))) if ((r = border_escalation_trivial(tree, border_range, &trivial)))
goto cleanup; goto cleanup;
if (!trivial) { if (!trivial) {
...@@ -1733,7 +1745,8 @@ cleanup: ...@@ -1733,7 +1745,8 @@ cleanup:
* Replaces all writes that overlap with range * Replaces all writes that overlap with range
* Deletes all reads dominated by range * Deletes all reads dominated by range
*/ */
static int lt_escalate_write_locks(toku_lock_tree* tree) { static int
lt_escalate_write_locks(toku_lock_tree* tree) {
int r = ENOSYS; int r = ENOSYS;
assert(tree); assert(tree);
assert(tree->borderwrite); assert(tree->borderwrite);
...@@ -1746,7 +1759,8 @@ cleanup: ...@@ -1746,7 +1759,8 @@ cleanup:
} }
// run escalation algorithm on a given locktree // run escalation algorithm on a given locktree
static int lt_do_escalation(toku_lock_tree* lt) { static int
lt_do_escalation(toku_lock_tree* lt) {
assert(lt); assert(lt);
int r = ENOSYS; int r = ENOSYS;
DB* db; // extract db from lt DB* db; // extract db from lt
...@@ -1782,7 +1796,8 @@ cleanup: ...@@ -1782,7 +1796,8 @@ cleanup:
} }
// run escalation algorithm on all locktrees // run escalation algorithm on all locktrees
static int ltm_do_escalation(toku_ltm* mgr) { static int
ltm_do_escalation(toku_ltm* mgr) {
assert(mgr); assert(mgr);
int r = ENOSYS; int r = ENOSYS;
toku_lock_tree* lt = NULL; toku_lock_tree* lt = NULL;
...@@ -1799,9 +1814,8 @@ cleanup: ...@@ -1799,9 +1814,8 @@ cleanup:
return r; return r;
} }
int toku_lt_acquire_range_read_lock(toku_lock_tree* tree, DB* db, TXNID txn, int
const DBT* key_left, toku_lt_acquire_range_read_lock(toku_lock_tree* tree, DB* db, TXNID txn, const DBT* key_left, const DBT* key_right) {
const DBT* key_right) {
int r = ENOSYS; int r = ENOSYS;
r = lt_try_acquire_range_read_lock(tree, db, txn, r = lt_try_acquire_range_read_lock(tree, db, txn,
...@@ -1834,24 +1848,19 @@ int toku_lt_acquire_range_read_lock(toku_lock_tree* tree, DB* db, TXNID txn, ...@@ -1834,24 +1848,19 @@ int toku_lt_acquire_range_read_lock(toku_lock_tree* tree, DB* db, TXNID txn,
return r; return r;
} }
static int lt_try_acquire_range_write_lock(toku_lock_tree* tree, static int
DB* db, TXNID txn, lt_try_acquire_range_write_lock(toku_lock_tree* tree, DB* db, TXNID txn, const DBT* key_left, const DBT* key_right) {
const DBT* key_left,
const DBT* key_right) {
int r; int r;
toku_point left; toku_point left;
toku_point right; toku_point right;
toku_interval query; toku_interval query;
r = lt_preprocess(tree, db, txn, r = lt_preprocess(tree, db, txn, key_left, key_right, &left, &right, &query);
key_left, key_right,
&left, &right,
&query);
if (r != 0) if (r != 0)
goto cleanup; goto cleanup;
// if query is dominated by selfwrite('txn') then return success // if query is dominated by selfwrite('txn') then return success
BOOL dominated; bool dominated;
r = lt_rt_dominates(tree, &query, toku_lt_ifexist_selfwrite(tree, txn), &dominated); r = lt_rt_dominates(tree, &query, toku_lt_ifexist_selfwrite(tree, txn), &dominated);
if (r || dominated) if (r || dominated)
goto cleanup; goto cleanup;
...@@ -1868,18 +1877,19 @@ static int lt_try_acquire_range_write_lock(toku_lock_tree* tree, ...@@ -1868,18 +1877,19 @@ static int lt_try_acquire_range_write_lock(toku_lock_tree* tree,
// Need to copy the memory and insert. No merging required in selfwrite. // Need to copy the memory and insert. No merging required in selfwrite.
// This is a point, and if merging was possible it would have been dominated by selfwrite. // This is a point, and if merging was possible it would have been dominated by selfwrite.
r = ltm_out_of_locks(tree->mgr);
if (r != 0)
goto cleanup;
// Insert into selfwrite // Insert into selfwrite
toku_range to_insert; toku_range to_insert;
init_insert(&to_insert, &left, &right, txn); init_insert(&to_insert, &left, &right, txn);
if (!ltm_lock_test_incr(tree->mgr, 0)) {
r = TOKUDB_OUT_OF_LOCKS; bool dummy = TRUE;
goto cleanup;
}
BOOL dummy = TRUE;
r = lt_alloc_extreme(tree, &to_insert, TRUE, &dummy); r = lt_alloc_extreme(tree, &to_insert, TRUE, &dummy);
if (r != 0) if (r != 0)
goto cleanup; goto cleanup;
BOOL free_left = FALSE; bool free_left = FALSE;
toku_range_tree* selfwrite; toku_range_tree* selfwrite;
r = lt_selfwrite(tree, txn, &selfwrite); r = lt_selfwrite(tree, txn, &selfwrite);
if (r != 0) { if (r != 0) {
...@@ -1898,7 +1908,7 @@ static int lt_try_acquire_range_write_lock(toku_lock_tree* tree, ...@@ -1898,7 +1908,7 @@ static int lt_try_acquire_range_write_lock(toku_lock_tree* tree,
r = lt_panic(tree, r); r = lt_panic(tree, r);
goto cleanup_left; goto cleanup_left;
} }
ltm_lock_incr(tree->mgr, 0); ltm_incr_locks(tree->mgr, 0);
r = 0; r = 0;
cleanup_left: cleanup_left:
...@@ -1906,6 +1916,11 @@ static int lt_try_acquire_range_write_lock(toku_lock_tree* tree, ...@@ -1906,6 +1916,11 @@ static int lt_try_acquire_range_write_lock(toku_lock_tree* tree,
if (free_left) if (free_left)
p_free(tree, to_insert.ends.left); p_free(tree, to_insert.ends.left);
} else { } else {
// Check lock resource contraints
r = ltm_out_of_locks(tree->mgr);
if (r != 0)
goto cleanup;
// insert and consolidate into the local write set // insert and consolidate into the local write set
toku_range to_insert; toku_range to_insert;
init_insert(&to_insert, &left, &right, txn); init_insert(&to_insert, &left, &right, txn);
...@@ -1919,9 +1934,8 @@ cleanup: ...@@ -1919,9 +1934,8 @@ cleanup:
return r; return r;
} }
int toku_lt_acquire_range_write_lock(toku_lock_tree* tree, DB* db, TXNID txn, int
const DBT* key_left, toku_lt_acquire_range_write_lock(toku_lock_tree* tree, DB* db, TXNID txn, const DBT* key_left, const DBT* key_right) {
const DBT* key_right) {
int r = ENOSYS; int r = ENOSYS;
r = lt_try_acquire_range_write_lock(tree, db, txn, key_left, key_right); r = lt_try_acquire_range_write_lock(tree, db, txn, key_left, key_right);
...@@ -1952,11 +1966,13 @@ int toku_lt_acquire_range_write_lock(toku_lock_tree* tree, DB* db, TXNID txn, ...@@ -1952,11 +1966,13 @@ int toku_lt_acquire_range_write_lock(toku_lock_tree* tree, DB* db, TXNID txn,
return r; return r;
} }
int toku_lt_acquire_write_lock(toku_lock_tree* tree, DB* db, TXNID txn, const DBT* key) { int
toku_lt_acquire_write_lock(toku_lock_tree* tree, DB* db, TXNID txn, const DBT* key) {
return toku_lt_acquire_range_write_lock(tree, db, txn, key, key); return toku_lt_acquire_range_write_lock(tree, db, txn, key, key);
} }
static inline int sweep_border(toku_lock_tree* tree, toku_range* range) { static inline int
sweep_border(toku_lock_tree* tree, toku_range* range) {
assert(tree && range); assert(tree && range);
toku_range_tree* borderwrite = tree->borderwrite; toku_range_tree* borderwrite = tree->borderwrite;
assert(borderwrite); assert(borderwrite);
...@@ -1989,8 +2005,8 @@ static inline int sweep_border(toku_lock_tree* tree, toku_range* range) { ...@@ -1989,8 +2005,8 @@ static inline int sweep_border(toku_lock_tree* tree, toku_range* range) {
/* Find pred(s.ends.left), and succ(s.ends.right) */ /* Find pred(s.ends.left), and succ(s.ends.right) */
toku_range pred; toku_range pred;
toku_range succ; toku_range succ;
BOOL found_p = FALSE; bool found_p = FALSE;
BOOL found_s = FALSE; bool found_s = FALSE;
r = lt_get_border_in_borderwrite(tree, &pred, &succ, &found_p, &found_s, &buf[0]); r = lt_get_border_in_borderwrite(tree, &pred, &succ, &found_p, &found_s, &buf[0]);
if (r != 0) if (r != 0)
...@@ -2030,7 +2046,8 @@ static inline int sweep_border(toku_lock_tree* tree, toku_range* range) { ...@@ -2030,7 +2046,8 @@ static inline int sweep_border(toku_lock_tree* tree, toku_range* range) {
If both found and pred.data=succ.data, merge pred and succ (expand?) If both found and pred.data=succ.data, merge pred and succ (expand?)
free_points free_points
*/ */
static inline int lt_border_delete(toku_lock_tree* tree, toku_range_tree* rt) { static inline int
lt_border_delete(toku_lock_tree* tree, toku_range_tree* rt) {
int r; int r;
assert(tree); assert(tree);
if (!rt) if (!rt)
...@@ -2058,7 +2075,8 @@ static inline int lt_border_delete(toku_lock_tree* tree, toku_range_tree* rt) { ...@@ -2058,7 +2075,8 @@ static inline int lt_border_delete(toku_lock_tree* tree, toku_range_tree* rt) {
return 0; return 0;
} }
static inline int lt_defer_unlocking_txn(toku_lock_tree* tree, TXNID txnid) { static inline int
lt_defer_unlocking_txn(toku_lock_tree* tree, TXNID txnid) {
int r = ENOSYS; int r = ENOSYS;
rt_forest* forest = toku_rth_find(tree->txns_to_unlock, txnid); rt_forest* forest = toku_rth_find(tree->txns_to_unlock, txnid);
...@@ -2075,7 +2093,8 @@ cleanup: ...@@ -2075,7 +2093,8 @@ cleanup:
return r; return r;
} }
static inline int lt_unlock_txn(toku_lock_tree* tree, TXNID txn) { static inline int
lt_unlock_txn(toku_lock_tree* tree, TXNID txn) {
if (!tree) if (!tree)
return EINVAL; return EINVAL;
int r; int r;
...@@ -2085,24 +2104,20 @@ static inline int lt_unlock_txn(toku_lock_tree* tree, TXNID txn) { ...@@ -2085,24 +2104,20 @@ static inline int lt_unlock_txn(toku_lock_tree* tree, TXNID txn) {
uint32_t ranges = 0; uint32_t ranges = 0;
if (selfread) { if (selfread) {
uint32_t size; uint32_t size = toku_rt_get_size(selfread);
r = toku_rt_get_size(selfread, &size);
assert_zero(r);
ranges += size; ranges += size;
r = lt_free_contents(tree, selfread, TRUE); r = lt_free_contents(tree, selfread);
if (r != 0) if (r != 0)
return lt_panic(tree, r); return lt_panic(tree, r);
} }
if (selfwrite) { if (selfwrite) {
uint32_t size; uint32_t size = toku_rt_get_size(selfwrite);
r = toku_rt_get_size(selfwrite, &size);
assert_zero(r);
ranges += size; ranges += size;
r = lt_border_delete(tree, selfwrite); r = lt_border_delete(tree, selfwrite);
if (r != 0) if (r != 0)
return lt_panic(tree, r); return lt_panic(tree, r);
r = lt_free_contents(tree, selfwrite, TRUE); r = lt_free_contents(tree, selfwrite);
if (r != 0) if (r != 0)
return lt_panic(tree, r); return lt_panic(tree, r);
} }
...@@ -2110,12 +2125,13 @@ static inline int lt_unlock_txn(toku_lock_tree* tree, TXNID txn) { ...@@ -2110,12 +2125,13 @@ static inline int lt_unlock_txn(toku_lock_tree* tree, TXNID txn) {
if (selfread || selfwrite) if (selfread || selfwrite)
toku_rth_delete(tree->rth, txn); toku_rth_delete(tree->rth, txn);
ltm_lock_decr(tree->mgr, ranges); ltm_decr_locks(tree->mgr, ranges);
return 0; return 0;
} }
static inline int lt_unlock_deferred_txns(toku_lock_tree* tree) { static inline int
lt_unlock_deferred_txns(toku_lock_tree* tree) {
int r = ENOSYS; int r = ENOSYS;
toku_rth_start_scan(tree->txns_to_unlock); toku_rth_start_scan(tree->txns_to_unlock);
rt_forest* forest = NULL; rt_forest* forest = NULL;
...@@ -2131,8 +2147,10 @@ cleanup: ...@@ -2131,8 +2147,10 @@ cleanup:
return r; return r;
} }
static inline void lt_clear(toku_lock_tree* tree) { static inline void
lt_clear(toku_lock_tree* tree) {
int r; int r;
assert(tree); assert(tree);
toku_rt_clear(tree->borderwrite); toku_rt_clear(tree->borderwrite);
...@@ -2140,19 +2158,14 @@ static inline void lt_clear(toku_lock_tree* tree) { ...@@ -2140,19 +2158,14 @@ static inline void lt_clear(toku_lock_tree* tree) {
rt_forest* forest; rt_forest* forest;
uint32_t ranges = 0; uint32_t ranges = 0;
while ((forest = toku_rth_next(tree->rth)) != NULL) { while ((forest = toku_rth_next(tree->rth)) != NULL) {
uint32_t size;
if (forest->self_read) { if (forest->self_read) {
r = toku_rt_get_size(forest->self_read, &size); ranges += toku_rt_get_size(forest->self_read);
assert_zero(r); r = lt_free_contents(tree, forest->self_read);
ranges += size;
r = lt_free_contents(tree, forest->self_read, TRUE);
assert_zero(r); assert_zero(r);
} }
if (forest->self_write) { if (forest->self_write) {
r = toku_rt_get_size(forest->self_write, &size); ranges += toku_rt_get_size(forest->self_write);
assert_zero(r); r = lt_free_contents(tree, forest->self_write);
ranges += size;
r = lt_free_contents(tree, forest->self_write, TRUE);
assert_zero(r); assert_zero(r);
} }
...@@ -2160,10 +2173,11 @@ static inline void lt_clear(toku_lock_tree* tree) { ...@@ -2160,10 +2173,11 @@ static inline void lt_clear(toku_lock_tree* tree) {
toku_rth_clear(tree->rth); toku_rth_clear(tree->rth);
toku_rth_clear(tree->txns_to_unlock); toku_rth_clear(tree->txns_to_unlock);
/* tree->txns_still_locked is already empty, so we do not clear it. */ /* tree->txns_still_locked is already empty, so we do not clear it. */
ltm_lock_decr(tree->mgr, ranges); ltm_decr_locks(tree->mgr, ranges);
} }
int toku_lt_unlock(toku_lock_tree* tree, TXNID txn) { int
toku_lt_unlock(toku_lock_tree* tree, TXNID txn) {
int r = ENOSYS; int r = ENOSYS;
if (!tree) { if (!tree) {
r = EINVAL; goto cleanup; r = EINVAL; goto cleanup;
...@@ -2183,13 +2197,15 @@ cleanup: ...@@ -2183,13 +2197,15 @@ cleanup:
return r; return r;
} }
void toku_lt_add_ref(toku_lock_tree* tree) { void
toku_lt_add_ref(toku_lock_tree* tree) {
assert(tree); assert(tree);
assert(tree->ref_count > 0); assert(tree->ref_count > 0);
tree->ref_count++; tree->ref_count++;
} }
static void toku_ltm_stop_managing_lt(toku_ltm* mgr, toku_lock_tree* tree) { static void
toku_ltm_stop_managing_lt(toku_ltm* mgr, toku_lock_tree* tree) {
toku_ltm_remove_lt(mgr, tree); toku_ltm_remove_lt(mgr, tree);
toku_lt_map* map = toku_idlth_find(mgr->idlth, tree->dict_id); toku_lt_map* map = toku_idlth_find(mgr->idlth, tree->dict_id);
if (map && map->tree == tree) { if (map && map->tree == tree) {
...@@ -2197,7 +2213,8 @@ static void toku_ltm_stop_managing_lt(toku_ltm* mgr, toku_lock_tree* tree) { ...@@ -2197,7 +2213,8 @@ static void toku_ltm_stop_managing_lt(toku_ltm* mgr, toku_lock_tree* tree) {
} }
} }
int toku_lt_remove_ref(toku_lock_tree* tree) { int
toku_lt_remove_ref(toku_lock_tree* tree) {
int r = ENOSYS; int r = ENOSYS;
assert(tree); assert(tree);
assert(tree->ref_count > 0); assert(tree->ref_count > 0);
...@@ -2217,7 +2234,8 @@ cleanup: ...@@ -2217,7 +2234,8 @@ cleanup:
} }
//Heaviside function to find a DB by DB (used to find the index) (just sort by pointer addr) //Heaviside function to find a DB by DB (used to find the index) (just sort by pointer addr)
static int find_db (OMTVALUE v, void *dbv) { static int
find_db (OMTVALUE v, void *dbv) {
DB *db = v; DB *db = v;
DB *dbfind = dbv; DB *dbfind = dbv;
if (db < dbfind) if (db < dbfind)
...@@ -2227,7 +2245,8 @@ static int find_db (OMTVALUE v, void *dbv) { ...@@ -2227,7 +2245,8 @@ static int find_db (OMTVALUE v, void *dbv) {
return 0; return 0;
} }
static void lt_add_db(toku_lock_tree* tree, DB *db) { static void
lt_add_db(toku_lock_tree* tree, DB *db) {
if (db != NULL) { if (db != NULL) {
int r; int r;
OMTVALUE get_dbv = NULL; OMTVALUE get_dbv = NULL;
...@@ -2239,7 +2258,8 @@ static void lt_add_db(toku_lock_tree* tree, DB *db) { ...@@ -2239,7 +2258,8 @@ static void lt_add_db(toku_lock_tree* tree, DB *db) {
} }
} }
static void lt_remove_db(toku_lock_tree* tree, DB *db) { static void
lt_remove_db(toku_lock_tree* tree, DB *db) {
if (db != NULL) { if (db != NULL) {
int r; int r;
OMTVALUE get_dbv = NULL; OMTVALUE get_dbv = NULL;
...@@ -2252,7 +2272,8 @@ static void lt_remove_db(toku_lock_tree* tree, DB *db) { ...@@ -2252,7 +2272,8 @@ static void lt_remove_db(toku_lock_tree* tree, DB *db) {
} }
} }
void toku_lt_remove_db_ref(toku_lock_tree* tree, DB *db) { void
toku_lt_remove_db_ref(toku_lock_tree* tree, DB *db) {
int r; int r;
lt_remove_db(tree, db); lt_remove_db(tree, db);
r = toku_lt_remove_ref(tree); r = toku_lt_remove_ref(tree);
...@@ -2683,7 +2704,7 @@ toku_lt_get_lock_request_conflicts(toku_lock_tree *tree, toku_lock_request *lock ...@@ -2683,7 +2704,7 @@ toku_lt_get_lock_request_conflicts(toku_lock_tree *tree, toku_lock_request *lock
} }
if (ranges) if (ranges)
tree->free(ranges); toku_free(ranges);
lt_clear_comparison_functions(tree); lt_clear_comparison_functions(tree);
return r; return r;
......
...@@ -97,7 +97,7 @@ struct __toku_lock_tree { ...@@ -97,7 +97,7 @@ struct __toku_lock_tree {
toku_range* bw_buf; toku_range* bw_buf;
uint32_t bw_buflen; uint32_t bw_buflen;
/** Whether lock escalation is allowed. */ /** Whether lock escalation is allowed. */
BOOL lock_escalation_allowed; bool lock_escalation_allowed;
/** Lock tree manager */ /** Lock tree manager */
toku_ltm* mgr; toku_ltm* mgr;
/** Function to retrieve the key compare function from the database. */ /** Function to retrieve the key compare function from the database. */
...@@ -106,12 +106,6 @@ struct __toku_lock_tree { ...@@ -106,12 +106,6 @@ struct __toku_lock_tree {
int (*compare_fun)(DB*,const DBT*,const DBT*); int (*compare_fun)(DB*,const DBT*,const DBT*);
/** The panic function */ /** The panic function */
int (*panic)(DB*, int); int (*panic)(DB*, int);
/** The user malloc function */
void* (*malloc) (size_t);
/** The user free function */
void (*free) (void*);
/** The user realloc function */
void* (*realloc)(void*, size_t);
/** The number of references held by DB instances and transactions to this lock tree*/ /** The number of references held by DB instances and transactions to this lock tree*/
uint32_t ref_count; uint32_t ref_count;
/** DICTIONARY_ID associated with the lock tree */ /** DICTIONARY_ID associated with the lock tree */
...@@ -158,12 +152,6 @@ struct __toku_ltm { ...@@ -158,12 +152,6 @@ struct __toku_ltm {
toku_dbt_cmp (*get_compare_fun_from_db)(DB*); toku_dbt_cmp (*get_compare_fun_from_db)(DB*);
/** The panic function */ /** The panic function */
int (*panic)(DB*, int); int (*panic)(DB*, int);
/** The user malloc function */
void* (*malloc) (size_t);
/** The user free function */
void (*free) (void*);
/** The user realloc function */
void* (*realloc)(void*, size_t);
toku_pthread_mutex_t lock; toku_pthread_mutex_t lock;
toku_pthread_mutex_t *use_lock; toku_pthread_mutex_t *use_lock;
...@@ -205,9 +193,6 @@ typedef struct __toku_point toku_point; ...@@ -205,9 +193,6 @@ typedef struct __toku_point toku_point;
\param panic The function to cause the db to panic. \param panic The function to cause the db to panic.
i.e., godzilla_rampage() i.e., godzilla_rampage()
\param payload_capacity The maximum amount of memory to use for dbt payloads. \param payload_capacity The maximum amount of memory to use for dbt payloads.
\param user_malloc A user provided malloc(3) function.
\param user_free A user provided free(3) function.
\param user_realloc A user provided realloc(3) function.
\return \return
- 0 Success - 0 Success
...@@ -225,10 +210,7 @@ typedef struct __toku_point toku_point; ...@@ -225,10 +210,7 @@ typedef struct __toku_point toku_point;
int toku_lt_create(toku_lock_tree** ptree, int toku_lt_create(toku_lock_tree** ptree,
int (*panic)(DB*, int), int (*panic)(DB*, int),
toku_ltm* mgr, toku_ltm* mgr,
toku_dbt_cmp (*get_compare_fun_from_db)(DB*), toku_dbt_cmp (*get_compare_fun_from_db)(DB*));
void* (*user_malloc) (size_t),
void (*user_free) (void*),
void* (*user_realloc)(void*, size_t));
/** /**
Gets a lock tree for a given DB with id dict_id Gets a lock tree for a given DB with id dict_id
...@@ -410,9 +392,6 @@ int toku_lt_unlock(toku_lock_tree* tree, TXNID txn); ...@@ -410,9 +392,6 @@ int toku_lt_unlock(toku_lock_tree* tree, TXNID txn);
\param pmgr A buffer for the new lock tree manager. \param pmgr A buffer for the new lock tree manager.
\param max_locks The maximum number of locks. \param max_locks The maximum number of locks.
\param user_malloc A user provided malloc(3) function.
\param user_free A user provided free(3) function.
\param user_realloc A user provided realloc(3) function.
\return \return
- 0 on success. - 0 on success.
...@@ -423,10 +402,7 @@ int toku_ltm_create(toku_ltm** pmgr, ...@@ -423,10 +402,7 @@ int toku_ltm_create(toku_ltm** pmgr,
uint32_t max_locks, uint32_t max_locks,
uint64_t max_lock_memory, uint64_t max_lock_memory,
int (*panic)(DB*, int), int (*panic)(DB*, int),
toku_dbt_cmp (*get_compare_fun_from_db)(DB*), toku_dbt_cmp (*get_compare_fun_from_db)(DB*));
void* (*user_malloc) (size_t),
void (*user_free) (void*),
void* (*user_realloc)(void*, size_t));
/** /**
Closes and frees a lock tree manager.. Closes and frees a lock tree manager..
...@@ -464,6 +440,9 @@ void toku_ltm_get_status(toku_ltm* mgr, uint32_t * max_locks, uint32_t * curr_lo ...@@ -464,6 +440,9 @@ void toku_ltm_get_status(toku_ltm* mgr, uint32_t * max_locks, uint32_t * curr_lo
int toku_ltm_get_max_locks(toku_ltm* mgr, uint32_t* max_locks); int toku_ltm_get_max_locks(toku_ltm* mgr, uint32_t* max_locks);
void toku_ltm_incr_lock_memory(void *extra, size_t s);
void toku_ltm_decr_lock_memory(void *extra, size_t s);
void toku_lt_add_ref(toku_lock_tree* tree); void toku_lt_add_ref(toku_lock_tree* tree);
int toku_lt_remove_ref(toku_lock_tree* tree); int toku_lt_remove_ref(toku_lock_tree* tree);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
*/ */
#include <toku_portability.h> #include <toku_portability.h>
#include "memory.h"
#include "lth.h" #include "lth.h"
#include <toku_assert.h> #include <toku_assert.h>
#include <errno.h> #include <errno.h>
...@@ -27,23 +28,17 @@ static inline void toku__invalidate_scan(toku_lth* lth) { ...@@ -27,23 +28,17 @@ static inline void toku__invalidate_scan(toku_lth* lth) {
lth->iter_is_valid = FALSE; lth->iter_is_valid = FALSE;
} }
int toku_lth_create(toku_lth** plth, int toku_lth_create(toku_lth** plth) {
void* (*user_malloc) (size_t),
void (*user_free) (void*),
void* (*user_realloc)(void*, size_t)) {
int r = ENOSYS; int r = ENOSYS;
assert(plth && user_malloc && user_free && user_realloc); assert(plth);
toku_lth* tmp = NULL; toku_lth* tmp = NULL;
tmp = (toku_lth*)user_malloc(sizeof(*tmp)); tmp = (toku_lth*) toku_malloc(sizeof(*tmp));
if (!tmp) { r = ENOMEM; goto cleanup; } if (!tmp) { r = ENOMEM; goto cleanup; }
memset(tmp, 0, sizeof(*tmp)); memset(tmp, 0, sizeof(*tmp));
tmp->malloc = user_malloc;
tmp->free = user_free;
tmp->realloc = user_realloc;
tmp->num_buckets = __toku_lth_init_size; tmp->num_buckets = __toku_lth_init_size;
tmp->buckets = (toku_lth_elt*) tmp->buckets = (toku_lth_elt*)
tmp->malloc(tmp->num_buckets * sizeof(*tmp->buckets)); toku_malloc(tmp->num_buckets * sizeof(*tmp->buckets));
if (!tmp->buckets) { r = ENOMEM; goto cleanup; } if (!tmp->buckets) { r = ENOMEM; goto cleanup; }
memset(tmp->buckets, 0, tmp->num_buckets * sizeof(*tmp->buckets)); memset(tmp->buckets, 0, tmp->num_buckets * sizeof(*tmp->buckets));
toku__invalidate_scan(tmp); toku__invalidate_scan(tmp);
...@@ -55,8 +50,8 @@ int toku_lth_create(toku_lth** plth, ...@@ -55,8 +50,8 @@ int toku_lth_create(toku_lth** plth,
cleanup: cleanup:
if (r != 0) { if (r != 0) {
if (tmp) { if (tmp) {
if (tmp->buckets) { user_free(tmp->buckets); } if (tmp->buckets) { toku_free(tmp->buckets); }
user_free(tmp); toku_free(tmp);
} }
} }
return r; return r;
...@@ -86,7 +81,7 @@ static inline toku_lth_elt* toku__lth_next(toku_lth* lth) { ...@@ -86,7 +81,7 @@ static inline toku_lth_elt* toku__lth_next(toku_lth* lth) {
assert(lth->iter_is_valid); assert(lth->iter_is_valid);
lth->iter_curr = lth->iter_curr->next_in_iteration; lth->iter_curr = lth->iter_curr->next_in_iteration;
lth->iter_is_valid = (BOOL)(lth->iter_curr != &lth->iter_head); lth->iter_is_valid = (bool)(lth->iter_curr != &lth->iter_head);
return lth->iter_curr; return lth->iter_curr;
} }
...@@ -119,7 +114,7 @@ void toku_lth_delete(toku_lth* lth, toku_lock_tree* key) { ...@@ -119,7 +114,7 @@ void toku_lth_delete(toku_lth* lth, toku_lock_tree* key) {
current->prev_in_iteration->next_in_iteration = current->next_in_iteration; current->prev_in_iteration->next_in_iteration = current->next_in_iteration;
current->next_in_iteration->prev_in_iteration = current->prev_in_iteration; current->next_in_iteration->prev_in_iteration = current->prev_in_iteration;
prev->next_in_bucket = current->next_in_bucket; prev->next_in_bucket = current->next_in_bucket;
lth->free(current); toku_free(current);
lth->num_keys--; lth->num_keys--;
return; return;
} }
...@@ -133,7 +128,7 @@ int toku_lth_insert(toku_lth* lth, toku_lock_tree* key) { ...@@ -133,7 +128,7 @@ int toku_lth_insert(toku_lth* lth, toku_lock_tree* key) {
uint32_t index = toku__lth_hash(lth, key); uint32_t index = toku__lth_hash(lth, key);
/* Allocate a new one. */ /* Allocate a new one. */
toku_lth_elt* element = (toku_lth_elt*)lth->malloc(sizeof(*element)); toku_lth_elt* element = (toku_lth_elt*) toku_malloc(sizeof(*element));
if (!element) { r = ENOMEM; goto cleanup; } if (!element) { r = ENOMEM; goto cleanup; }
memset(element, 0, sizeof(*element)); memset(element, 0, sizeof(*element));
element->value.hash_key = key; element->value.hash_key = key;
...@@ -162,9 +157,9 @@ void toku_lth_close(toku_lth* lth) { ...@@ -162,9 +157,9 @@ void toku_lth_close(toku_lth* lth) {
while (next != head) { while (next != head) {
element = next; element = next;
next = toku__lth_next(lth); next = toku__lth_next(lth);
lth->free(element); toku_free(element);
} }
lth->free(lth->buckets); toku_free(lth->buckets);
lth->free(lth); toku_free(lth);
} }
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
*/ */
//Defines BOOL data type. //Defines bool data type.
#include <db.h> #include <db.h>
#include <brttypes.h> #include <brttypes.h>
#include <locktree.h> #include <locktree.h>
...@@ -51,20 +51,11 @@ struct __toku_lth { ...@@ -51,20 +51,11 @@ struct __toku_lth {
uint32_t num_keys; uint32_t num_keys;
toku_lth_elt iter_head; toku_lth_elt iter_head;
toku_lth_elt* iter_curr; toku_lth_elt* iter_curr;
BOOL iter_is_valid; bool iter_is_valid;
/** The user malloc function */
void* (*malloc) (size_t);
/** The user free function */
void (*free) (void*);
/** The user realloc function */
void* (*realloc)(void*, size_t);
}; };
int toku_lth_create(toku_lth** ptable, int toku_lth_create(toku_lth** ptable);
void* (*user_malloc) (size_t),
void (*user_free) (void*),
void* (*user_realloc)(void*, size_t));
toku_lock_tree* toku_lth_find (toku_lth* table, toku_lock_tree* key); toku_lock_tree* toku_lth_find (toku_lth* table, toku_lock_tree* key);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
*/ */
#include <toku_portability.h> #include <toku_portability.h>
#include "memory.h"
#include "rth.h" #include "rth.h"
#include <toku_assert.h> #include <toku_assert.h>
#include <errno.h> #include <errno.h>
...@@ -27,23 +28,17 @@ static inline void toku__invalidate_scan(toku_rth* rth) { ...@@ -27,23 +28,17 @@ static inline void toku__invalidate_scan(toku_rth* rth) {
rth->iter_is_valid = FALSE; rth->iter_is_valid = FALSE;
} }
int toku_rth_create(toku_rth** prth, int toku_rth_create(toku_rth** prth) {
void* (*user_malloc) (size_t),
void (*user_free) (void*),
void* (*user_realloc)(void*, size_t)) {
int r = ENOSYS; int r = ENOSYS;
assert(prth && user_malloc && user_free && user_realloc); assert(prth);
toku_rth* tmp = NULL; toku_rth* tmp = NULL;
tmp = (toku_rth*)user_malloc(sizeof(*tmp)); tmp = (toku_rth*) toku_malloc(sizeof(*tmp));
if (!tmp) { r = ENOMEM; goto cleanup; } if (!tmp) { r = ENOMEM; goto cleanup; }
memset(tmp, 0, sizeof(*tmp)); memset(tmp, 0, sizeof(*tmp));
tmp->malloc = user_malloc;
tmp->free = user_free;
tmp->realloc = user_realloc;
tmp->num_buckets = __toku_rth_init_size; tmp->num_buckets = __toku_rth_init_size;
tmp->buckets = (toku_rth_elt*) tmp->buckets = (toku_rth_elt*)
tmp->malloc(tmp->num_buckets * sizeof(*tmp->buckets)); toku_malloc(tmp->num_buckets * sizeof(*tmp->buckets));
if (!tmp->buckets) { r = ENOMEM; goto cleanup; } if (!tmp->buckets) { r = ENOMEM; goto cleanup; }
memset(tmp->buckets, 0, tmp->num_buckets * sizeof(*tmp->buckets)); memset(tmp->buckets, 0, tmp->num_buckets * sizeof(*tmp->buckets));
toku__invalidate_scan(tmp); toku__invalidate_scan(tmp);
...@@ -55,8 +50,8 @@ int toku_rth_create(toku_rth** prth, ...@@ -55,8 +50,8 @@ int toku_rth_create(toku_rth** prth,
cleanup: cleanup:
if (r != 0) { if (r != 0) {
if (tmp) { if (tmp) {
if (tmp->buckets) { user_free(tmp->buckets); } if (tmp->buckets) { toku_free(tmp->buckets); }
user_free(tmp); toku_free(tmp);
} }
} }
return r; return r;
...@@ -86,7 +81,7 @@ static inline toku_rth_elt* toku__rth_next(toku_rth* rth) { ...@@ -86,7 +81,7 @@ static inline toku_rth_elt* toku__rth_next(toku_rth* rth) {
assert(rth->iter_is_valid); assert(rth->iter_is_valid);
rth->iter_curr = rth->iter_curr->next_in_iteration; rth->iter_curr = rth->iter_curr->next_in_iteration;
rth->iter_is_valid = (BOOL)(rth->iter_curr != &rth->iter_head); rth->iter_is_valid = (rth->iter_curr != &rth->iter_head);
return rth->iter_curr; return rth->iter_curr;
} }
...@@ -119,7 +114,7 @@ void toku_rth_delete(toku_rth* rth, TXNID key) { ...@@ -119,7 +114,7 @@ void toku_rth_delete(toku_rth* rth, TXNID key) {
current->prev_in_iteration->next_in_iteration = current->next_in_iteration; current->prev_in_iteration->next_in_iteration = current->next_in_iteration;
current->next_in_iteration->prev_in_iteration = current->prev_in_iteration; current->next_in_iteration->prev_in_iteration = current->prev_in_iteration;
prev->next_in_bucket = current->next_in_bucket; prev->next_in_bucket = current->next_in_bucket;
rth->free(current); toku_free(current);
rth->num_keys--; rth->num_keys--;
return; return;
} }
...@@ -133,7 +128,7 @@ int toku_rth_insert(toku_rth* rth, TXNID key) { ...@@ -133,7 +128,7 @@ int toku_rth_insert(toku_rth* rth, TXNID key) {
uint32_t index = toku__rth_hash(rth, key); uint32_t index = toku__rth_hash(rth, key);
/* Allocate a new one. */ /* Allocate a new one. */
toku_rth_elt* element = (toku_rth_elt*)rth->malloc(sizeof(*element)); toku_rth_elt* element = (toku_rth_elt*) toku_malloc(sizeof(*element));
if (!element) { r = ENOMEM; goto cleanup; } if (!element) { r = ENOMEM; goto cleanup; }
memset(element, 0, sizeof(*element)); memset(element, 0, sizeof(*element));
element->value.hash_key = key; element->value.hash_key = key;
...@@ -151,7 +146,7 @@ cleanup: ...@@ -151,7 +146,7 @@ cleanup:
return r; return r;
} }
static inline void toku__rth_clear(toku_rth* rth, BOOL clean) { static inline void toku__rth_clear(toku_rth* rth, bool clean) {
assert(rth); assert(rth);
toku_rth_elt* element; toku_rth_elt* element;
...@@ -162,7 +157,7 @@ static inline void toku__rth_clear(toku_rth* rth, BOOL clean) { ...@@ -162,7 +157,7 @@ static inline void toku__rth_clear(toku_rth* rth, BOOL clean) {
while (next != head) { while (next != head) {
element = next; element = next;
next = toku__rth_next(rth); next = toku__rth_next(rth);
rth->free(element); toku_free(element);
} }
/* If clean is true, then we want to restore it to 'just created' status. /* If clean is true, then we want to restore it to 'just created' status.
If we are closing the tree, we don't need to do that restoration. */ If we are closing the tree, we don't need to do that restoration. */
...@@ -182,16 +177,16 @@ void toku_rth_close(toku_rth* rth) { ...@@ -182,16 +177,16 @@ void toku_rth_close(toku_rth* rth) {
assert(rth); assert(rth);
toku__rth_clear(rth, FALSE); toku__rth_clear(rth, FALSE);
rth->free(rth->buckets); toku_free(rth->buckets);
rth->free(rth); toku_free(rth);
} }
BOOL toku_rth_is_empty(toku_rth* rth) { bool toku_rth_is_empty(toku_rth* rth) {
assert(rth); assert(rth);
/* Verify consistency. */ /* Verify consistency. */
assert((rth->num_keys == 0) == assert((rth->num_keys == 0) ==
(rth->iter_head.next_in_iteration == &rth->iter_head)); (rth->iter_head.next_in_iteration == &rth->iter_head));
assert((rth->num_keys == 0) == assert((rth->num_keys == 0) ==
(rth->iter_head.prev_in_iteration == &rth->iter_head)); (rth->iter_head.prev_in_iteration == &rth->iter_head));
return (BOOL)(rth->num_keys == 0); return (rth->num_keys == 0);
} }
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
*/ */
//Defines BOOL data type.
#include <db.h> #include <db.h>
#include <brttypes.h> #include <brttypes.h>
#include <rangetree.h> #include <rangetree.h>
...@@ -42,19 +41,10 @@ struct __toku_rth { ...@@ -42,19 +41,10 @@ struct __toku_rth {
uint32_t num_keys; uint32_t num_keys;
toku_rth_elt iter_head; toku_rth_elt iter_head;
toku_rth_elt* iter_curr; toku_rth_elt* iter_curr;
BOOL iter_is_valid; bool iter_is_valid;
/** The user malloc function */
void* (*malloc) (size_t);
/** The user free function */
void (*free) (void*);
/** The user realloc function */
void* (*realloc)(void*, size_t);
}; };
int toku_rth_create(toku_rth** ptable, int toku_rth_create(toku_rth** ptable);
void* (*user_malloc) (size_t),
void (*user_free) (void*),
void* (*user_realloc)(void*, size_t));
rt_forest* toku_rth_find (toku_rth* table, TXNID key); rt_forest* toku_rth_find (toku_rth* table, TXNID key);
...@@ -70,7 +60,7 @@ int toku_rth_insert (toku_rth* table, TXNID key); ...@@ -70,7 +60,7 @@ int toku_rth_insert (toku_rth* table, TXNID key);
void toku_rth_clear (toku_rth* rth); void toku_rth_clear (toku_rth* rth);
BOOL toku_rth_is_empty (toku_rth* rth); bool toku_rth_is_empty (toku_rth* rth);
#if defined(__cplusplus) #if defined(__cplusplus)
} }
......
...@@ -75,3 +75,37 @@ clean: ...@@ -75,3 +75,37 @@ clean:
rm -f $(ALL_TESTS) rm -f $(ALL_TESTS)
rm -rf dir.*.lin dir.*.tlog dir.*.log rm -rf dir.*.lin dir.*.tlog dir.*.log
check_footprint.linrun: check_footprint_point.linrun check_footprint_range.linrun
true
check_footprint_point.linrun: test_footprint_point_write.lin
$(VGRIND) ./$< -v --nrows 1 && \
$(VGRIND) ./$< -v --nrows 2 && \
$(VGRIND) ./$< -v --nrows 10 --max_locks 1000 && \
$(VGRIND) ./$< -v --nrows 100 --max_locks 1000 && \
$(VGRIND) ./$< -v --nrows 1000 --max_locks 1000
check_footprint_range.linrun: test_footprint_range_write.lin
$(VGRIND) ./$< -v --nrows 1 && \
$(VGRIND) ./$< -v --nrows 2 && \
$(VGRIND) ./$< -v --nrows 10 --max_locks 1000 && \
$(VGRIND) ./$< -v --nrows 100 --max_locks 1000 && \
$(VGRIND) ./$< -v --nrows 1000 --max_locks 1000
check_footprint.tlogrun: check_footprint_point.tlogrun check_footprint_range.tlogrun
true
check_footprint_point.tlogrun: test_footprint_point_write.tlog
$(VGRIND) ./$< -v --nrows 1 && \
$(VGRIND) ./$< -v --nrows 2 && \
$(VGRIND) ./$< -v --nrows 10 --max_locks 1000 && \
$(VGRIND) ./$< -v --nrows 100 --max_locks 1000 && \
$(VGRIND) ./$< -v --nrows 1000 --max_locks 1000
check_footprint_range.tlogrun: test_footprint_range_write.tlog
$(VGRIND) ./$< -v --nrows 1 && \
$(VGRIND) ./$< -v --nrows 2 && \
$(VGRIND) ./$< -v --nrows 10 --max_locks 1000 && \
$(VGRIND) ./$< -v --nrows 100 --max_locks 1000 && \
$(VGRIND) ./$< -v --nrows 1000 --max_locks 1000
...@@ -38,11 +38,11 @@ int main(int argc, const char *argv[]) { ...@@ -38,11 +38,11 @@ int main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
DB *db_a = (DB *) 2; DB *db_a = (DB *) 2;
......
...@@ -17,7 +17,7 @@ int verbose=0; ...@@ -17,7 +17,7 @@ int verbose=0;
#include <key.h> #include <key.h>
BOOL want_panic = FALSE; bool want_panic = false;
static inline int intcmp(DB *db __attribute__((__unused__)), const DBT* a, const DBT* b) { static inline int intcmp(DB *db __attribute__((__unused__)), const DBT* a, const DBT* b) {
int x = *(int*)a->data; int x = *(int*)a->data;
...@@ -39,11 +39,11 @@ static inline toku_dbt_cmp get_compare_fun_from_db(__attribute__((unused)) DB* d ...@@ -39,11 +39,11 @@ static inline toku_dbt_cmp get_compare_fun_from_db(__attribute__((unused)) DB* d
return compare_fun; return compare_fun;
} }
BOOL panicked = FALSE; bool panicked = false;
static inline int dbpanic(DB* db, int r) { static inline int dbpanic(DB* db, int r) {
if (verbose) printf("AHH!!!! %d is rampaging! Run away %p!!!\n", r, db); if (verbose) printf("AHH!!!! %d is rampaging! Run away %p!!!\n", r, db);
panicked = TRUE; panicked = true;
assert(want_panic); assert(want_panic);
return EINVAL; return EINVAL;
} }
...@@ -107,13 +107,3 @@ static inline void init_point(toku_point* point, toku_lock_tree* tree) { ...@@ -107,13 +107,3 @@ static inline void init_point(toku_point* point, toku_lock_tree* tree) {
point->lt = tree; point->lt = tree;
} }
int mallocced = 0;
int failon = -1;
static inline void* fail_malloc(size_t size) {
if (++mallocced == failon) {
errno = ENOMEM;
return NULL;
}
return toku_malloc(size);
}
...@@ -8,14 +8,12 @@ int main(void) { ...@@ -8,14 +8,12 @@ int main(void) {
uint64_t max_lock_memory = max_locks*64; uint64_t max_lock_memory = max_locks*64;
r = toku_ltm_create(&mgr, max_locks, max_lock_memory, dbpanic, r = toku_ltm_create(&mgr, max_locks, max_lock_memory, dbpanic,
get_compare_fun_from_db, get_compare_fun_from_db);
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
{ {
r = toku_lt_create(&lt, dbpanic, mgr, r = toku_lt_create(&lt, dbpanic, mgr,
get_compare_fun_from_db, get_compare_fun_from_db);
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(lt); assert(lt);
r = toku_lt_close(lt); r = toku_lt_close(lt);
......
...@@ -22,9 +22,8 @@ static void do_range_test(int (*acquire)(toku_lock_tree*, DB*, TXNID, ...@@ -22,9 +22,8 @@ static void do_range_test(int (*acquire)(toku_lock_tree*, DB*, TXNID,
DBT* key_l = &_key_l; DBT* key_l = &_key_l;
DBT* key_r = &_key_r; DBT* key_r = &_key_r;
{ {
r = toku_lt_create(&lt, dbpanic, ltm, r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(lt); assert(lt);
...@@ -65,9 +64,7 @@ static void do_point_test(int (*acquire)(toku_lock_tree*, DB*, TXNID, ...@@ -65,9 +64,7 @@ static void do_point_test(int (*acquire)(toku_lock_tree*, DB*, TXNID,
/* Point read tests. */ /* Point read tests. */
key = &_key; key = &_key;
{ {
r = toku_lt_create(&lt, dbpanic, ltm, r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(lt); assert(lt);
...@@ -94,41 +91,18 @@ int main(int argc, const char *argv[]) { ...@@ -94,41 +91,18 @@ int main(int argc, const char *argv[]) {
int r; int r;
toku_lock_tree* lt = NULL; toku_lock_tree* lt = NULL;
r = toku_ltm_create(NULL, max_locks, max_lock_memory, dbpanic, r = toku_ltm_create(NULL, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR2(r, EINVAL);
assert(ltm == NULL);
r = toku_ltm_create(&ltm, 0, max_lock_memory, dbpanic,
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR2(r, EINVAL); CKERR2(r, EINVAL);
assert(ltm == NULL); assert(ltm == NULL);
r = toku_ltm_create(&ltm, max_locks, 0, dbpanic, r = toku_ltm_create(&ltm, 0, max_lock_memory, dbpanic, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR2(r, EINVAL); CKERR2(r, EINVAL);
assert(ltm == NULL); assert(ltm == NULL);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, r = toku_ltm_create(&ltm, max_locks, 0, dbpanic, get_compare_fun_from_db);
get_compare_fun_from_db,
NULL, toku_free, toku_realloc);
CKERR2(r, EINVAL);
assert(ltm == NULL);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic,
get_compare_fun_from_db,
toku_malloc, NULL, toku_realloc);
CKERR2(r, EINVAL);
assert(ltm == NULL);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic,
get_compare_fun_from_db,
toku_malloc, toku_free, NULL);
CKERR2(r, EINVAL); CKERR2(r, EINVAL);
assert(ltm == NULL); assert(ltm == NULL);
/* Actually create it. */ /* Actually create it. */
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(ltm); assert(ltm);
...@@ -170,37 +144,16 @@ int main(int argc, const char *argv[]) { ...@@ -170,37 +144,16 @@ int main(int argc, const char *argv[]) {
/* create tests. */ /* create tests. */
{ {
r = toku_lt_create(NULL, dbpanic, ltm, r = toku_lt_create(NULL, dbpanic, ltm, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR2(r, EINVAL);
r = toku_lt_create(&lt, NULL, ltm,
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR2(r, EINVAL); CKERR2(r, EINVAL);
r = toku_lt_create(&lt, dbpanic, NULL, r = toku_lt_create(&lt, NULL, ltm, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR2(r, EINVAL); CKERR2(r, EINVAL);
r = toku_lt_create(&lt, dbpanic, ltm, r = toku_lt_create(&lt, dbpanic, NULL, get_compare_fun_from_db);
NULL,
toku_malloc, toku_free, toku_realloc);
CKERR2(r, EINVAL); CKERR2(r, EINVAL);
r = toku_lt_create(&lt, dbpanic, ltm, r = toku_lt_create(&lt, dbpanic, ltm, NULL);
get_compare_fun_from_db,
NULL, toku_free, toku_realloc);
CKERR2(r, EINVAL);
r = toku_lt_create(&lt, dbpanic, ltm,
get_compare_fun_from_db,
toku_malloc, NULL, toku_realloc);
CKERR2(r, EINVAL);
r = toku_lt_create(&lt, dbpanic, ltm,
get_compare_fun_from_db,
toku_malloc, toku_free, NULL);
CKERR2(r, EINVAL); CKERR2(r, EINVAL);
} }
......
...@@ -10,7 +10,7 @@ TXNID txn = (TXNID)1; ...@@ -10,7 +10,7 @@ TXNID txn = (TXNID)1;
enum { MAX_LT_LOCKS = 1000 }; enum { MAX_LT_LOCKS = 1000 };
uint32_t max_locks = MAX_LT_LOCKS; uint32_t max_locks = MAX_LT_LOCKS;
uint64_t max_lock_memory = MAX_LT_LOCKS*64; uint64_t max_lock_memory = MAX_LT_LOCKS*64;
BOOL duplicates = FALSE; bool duplicates = false;
int nums[100]; int nums[100];
DBT _keys_left[2]; DBT _keys_left[2];
...@@ -42,25 +42,20 @@ static void init_query(void) { ...@@ -42,25 +42,20 @@ static void init_query(void) {
static void setup_tree(void) { static void setup_tree(void) {
assert(!lt && !ltm); assert(!lt && !ltm);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(ltm); assert(ltm);
r = toku_lt_create(&lt, dbpanic, ltm, r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(lt); assert(lt);
init_query(); init_query();
} }
static void close_tree(void) { static void close_tree(void) {
r = toku_lt_unlock(lt, txn); CKERR(r);
assert(lt && ltm); assert(lt && ltm);
r = toku_lt_close(lt); r = toku_lt_close(lt); CKERR(r);
CKERR(r); r = toku_ltm_close(ltm); CKERR(r);
r = toku_ltm_close(ltm);
CKERR(r);
lt = NULL; lt = NULL;
ltm = NULL; ltm = NULL;
} }
...@@ -139,7 +134,7 @@ temporarily_fake_comparison_functions(); ...@@ -139,7 +134,7 @@ temporarily_fake_comparison_functions();
toku_lt_point_cmp(buf[i].ends.right, &right) == 0 && toku_lt_point_cmp(buf[i].ends.right, &right) == 0 &&
buf[i].data == find_txn) { goto cleanup; } buf[i].data == find_txn) { goto cleanup; }
} }
assert(FALSE); //Crash since we didn't find it. assert(false); //Crash since we didn't find it.
cleanup: cleanup:
stop_fake_comparison_functions(); stop_fake_comparison_functions();
} }
...@@ -159,13 +154,11 @@ static void insert_1(int key_l, int key_r, ...@@ -159,13 +154,11 @@ static void insert_1(int key_l, int key_r,
setup_tree(); setup_tree();
r = toku_lt_acquire_range_read_lock(lt, db, txn, key_left, key_right); r = toku_lt_acquire_range_read_lock(lt, db, txn, key_left, key_right); CKERR(r);
CKERR(r);
close_tree(); close_tree();
setup_tree(); setup_tree();
r = toku_lt_acquire_read_lock(lt, db, txn, key_left); r = toku_lt_acquire_read_lock(lt, db, txn, key_left); CKERR(r);
CKERR(r);
close_tree(); close_tree();
} }
......
...@@ -8,27 +8,11 @@ int main(int argc, const char *argv[]) { ...@@ -8,27 +8,11 @@ int main(int argc, const char *argv[]) {
int r; int r;
parse_args(argc, argv); parse_args(argc, argv);
/* ********************************************************************** */
rth = NULL;
for (failon = 1; failon <= 2; failon++) {
mallocced = 0;
r = toku_rth_create(&rth, fail_malloc, toku_free, toku_realloc);
CKERR2(r, ENOMEM);
assert(rth==NULL);
}
r = toku_rth_create(&rth, toku_malloc, toku_free, toku_realloc);
CKERR(r);
assert(rth);
toku_rth_close(rth);
rth = NULL;
/* ********************************************************************** */
size_t i; size_t i;
size_t iterations = 512 << 2; size_t iterations = 512 << 2;
r = toku_rth_create(&rth, toku_malloc, toku_free, toku_realloc); r = toku_rth_create(&rth);
CKERR(r); CKERR(r);
assert(rth); assert(rth);
for (i = 1; i < iterations; i++) { for (i = 1; i < iterations; i++) {
...@@ -50,7 +34,7 @@ int main(int argc, const char *argv[]) { ...@@ -50,7 +34,7 @@ int main(int argc, const char *argv[]) {
/* ********************************************************************** */ /* ********************************************************************** */
r = toku_rth_create(&rth, toku_malloc, toku_free, toku_realloc); r = toku_rth_create(&rth);
CKERR(r); CKERR(r);
assert(rth); assert(rth);
for (i = 1; i < iterations; i++) { for (i = 1; i < iterations; i++) {
...@@ -65,7 +49,7 @@ int main(int argc, const char *argv[]) { ...@@ -65,7 +49,7 @@ int main(int argc, const char *argv[]) {
/* ********************************************************************** */ /* ********************************************************************** */
r = toku_rth_create(&rth, toku_malloc, toku_free, toku_realloc); r = toku_rth_create(&rth);
CKERR(r); CKERR(r);
assert(rth); assert(rth);
for (i = iterations - 1; i >= 1; i--) { for (i = iterations - 1; i >= 1; i--) {
...@@ -75,19 +59,9 @@ int main(int argc, const char *argv[]) { ...@@ -75,19 +59,9 @@ int main(int argc, const char *argv[]) {
toku_rth_close(rth); toku_rth_close(rth);
rth = NULL; rth = NULL;
failon = 3;
mallocced = 0;
r = toku_rth_create(&rth, fail_malloc, toku_free, toku_realloc);
CKERR(r);
assert(rth);
r = toku_rth_insert(rth, (TXNID)1);
CKERR2(r, ENOMEM);
toku_rth_close(rth);
rth = NULL;
/* ********************************************************************** */ /* ********************************************************************** */
r = toku_rth_create(&rth, toku_malloc, toku_free, toku_realloc); r = toku_rth_create(&rth);
CKERR(r); CKERR(r);
assert(rth); assert(rth);
for (i = iterations - 1; i >= 1; i--) { for (i = iterations - 1; i >= 1; i--) {
......
...@@ -36,14 +36,10 @@ static void init_query(void) { ...@@ -36,14 +36,10 @@ static void init_query(void) {
static void setup_tree(void) { static void setup_tree(void) {
assert(!lt && !ltm); assert(!lt && !ltm);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(ltm); assert(ltm);
r = toku_lt_create(&lt, dbpanic, ltm, r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(lt); assert(lt);
init_query(); init_query();
...@@ -71,7 +67,7 @@ static DBT* set_to_infty(DBT *dbt, int value) { ...@@ -71,7 +67,7 @@ static DBT* set_to_infty(DBT *dbt, int value) {
static void lt_insert(int r_expect, char txn, int key_l, static void lt_insert(int r_expect, char txn, int key_l,
int key_r, BOOL read_flag) { int key_r, bool read_flag) {
DBT _key_left; DBT _key_left;
DBT _key_right; DBT _key_right;
DBT* key_left = &_key_left; DBT* key_left = &_key_left;
...@@ -96,11 +92,11 @@ static void lt_insert(int r_expect, char txn, int key_l, ...@@ -96,11 +92,11 @@ static void lt_insert(int r_expect, char txn, int key_l,
} }
static void lt_insert_read(int r_expect, char txn, int key_l, int key_r) { static void lt_insert_read(int r_expect, char txn, int key_l, int key_r) {
lt_insert(r_expect, txn, key_l, key_r, TRUE); lt_insert(r_expect, txn, key_l, key_r, true);
} }
static void lt_insert_write(int r_expect, char txn, int key_l) { static void lt_insert_write(int r_expect, char txn, int key_l) {
lt_insert(r_expect, txn, key_l, 0, FALSE); lt_insert(r_expect, txn, key_l, 0, false);
} }
...@@ -120,37 +116,45 @@ static void runtest(void) { ...@@ -120,37 +116,45 @@ static void runtest(void) {
toku_lt_verify(lt, NULL); toku_lt_verify(lt, NULL);
lt_insert_write(0, 'b', 10); lt_insert_write(0, 'b', 10);
toku_lt_verify(lt, NULL); toku_lt_verify(lt, NULL);
lt_unlock('a');
lt_unlock('b');
close_tree(); close_tree();
/* ********************* */ /* ********************* */
setup_tree(); setup_tree();
lt_insert_write(0, 'a', 1); lt_insert_write(0, 'a', 1);
lt_unlock('a');
close_tree(); close_tree();
/* ********************* */ /* ********************* */
setup_tree(); setup_tree();
lt_insert_write(0, 'a', 2); lt_insert_write(0, 'a', 2);
lt_insert_write(0, 'a', 1); lt_insert_write(0, 'a', 1);
lt_unlock('a');
close_tree(); close_tree();
/* ********************* */ /* ********************* */
setup_tree(); setup_tree();
lt_insert_write(0, 'a', 1); lt_insert_write(0, 'a', 1);
lt_insert_write(0, 'a', 2); lt_insert_write(0, 'a', 2);
lt_insert_write(0, 'a', 1); lt_insert_write(0, 'a', 1);
lt_unlock('a');
close_tree(); close_tree();
/* ********************* */ /* ********************* */
setup_tree(); setup_tree();
lt_insert_write(0, 'a', 1); lt_insert_write(0, 'a', 1);
lt_insert_read (0, 'a', 1, 1); lt_insert_read (0, 'a', 1, 1);
lt_unlock('a');
close_tree(); close_tree();
/* ********************* */ /* ********************* */
setup_tree(); setup_tree();
lt_insert_write(0, 'a', 1); lt_insert_write(0, 'a', 1);
lt_insert_read (DB_LOCK_NOTGRANTED, 'b', 1, 1); lt_insert_read (DB_LOCK_NOTGRANTED, 'b', 1, 1);
lt_unlock('a');
close_tree(); close_tree();
/* ********************* */ /* ********************* */
setup_tree(); setup_tree();
lt_insert_read (0, 'b', 1, 1); lt_insert_read (0, 'b', 1, 1);
lt_insert_write(DB_LOCK_NOTGRANTED, 'a', 1); lt_insert_write(DB_LOCK_NOTGRANTED, 'a', 1);
lt_unlock('b');
close_tree(); close_tree();
/* ********************* */ /* ********************* */
setup_tree(); setup_tree();
...@@ -160,6 +164,7 @@ static void runtest(void) { ...@@ -160,6 +164,7 @@ static void runtest(void) {
lt_insert_write(0, 'a', 4); lt_insert_write(0, 'a', 4);
lt_insert_write(0, 'a', 5); lt_insert_write(0, 'a', 5);
lt_insert_read (DB_LOCK_NOTGRANTED, 'b', 2, 4); lt_insert_read (DB_LOCK_NOTGRANTED, 'b', 2, 4);
lt_unlock('a');
close_tree(); close_tree();
/* ********************* */ /* ********************* */
setup_tree(); setup_tree();
...@@ -169,6 +174,7 @@ static void runtest(void) { ...@@ -169,6 +174,7 @@ static void runtest(void) {
lt_insert_write(0, 'a', 4); lt_insert_write(0, 'a', 4);
lt_insert_write(0, 'a', 5); lt_insert_write(0, 'a', 5);
lt_insert_write (DB_LOCK_NOTGRANTED, 'b', 2); lt_insert_write (DB_LOCK_NOTGRANTED, 'b', 2);
lt_unlock('a');
close_tree(); close_tree();
/* ********************* */ /* ********************* */
setup_tree(); setup_tree();
...@@ -177,6 +183,8 @@ static void runtest(void) { ...@@ -177,6 +183,8 @@ static void runtest(void) {
lt_insert_write(0, 'a', 4); lt_insert_write(0, 'a', 4);
lt_insert_write(0, 'a', 5); lt_insert_write(0, 'a', 5);
lt_insert_read (0, 'b', 3, 3); lt_insert_read (0, 'b', 3, 3);
lt_unlock('a');
lt_unlock('b');
close_tree(); close_tree();
/* ********************* */ /* ********************* */
setup_tree(); setup_tree();
...@@ -185,6 +193,8 @@ static void runtest(void) { ...@@ -185,6 +193,8 @@ static void runtest(void) {
lt_insert_write(0, 'a', 4); lt_insert_write(0, 'a', 4);
lt_insert_write(0, 'a', 5); lt_insert_write(0, 'a', 5);
lt_insert_read (0, 'b', 3, 3); lt_insert_read (0, 'b', 3, 3);
lt_unlock('a');
lt_unlock('b');
close_tree(); close_tree();
/* ********************* */ /* ********************* */
setup_tree(); setup_tree();
...@@ -198,6 +208,8 @@ static void runtest(void) { ...@@ -198,6 +208,8 @@ static void runtest(void) {
lt_insert_write(0, 'a', 8); lt_insert_write(0, 'a', 8);
lt_insert_write(0, 'a', 9); lt_insert_write(0, 'a', 9);
lt_insert_read (DB_LOCK_NOTGRANTED, 'a', 3, 7); lt_insert_read (DB_LOCK_NOTGRANTED, 'a', 3, 7);
lt_unlock('a');
lt_unlock('b');
close_tree(); close_tree();
/* ********************* */ /* ********************* */
setup_tree(); setup_tree();
...@@ -211,6 +223,7 @@ static void runtest(void) { ...@@ -211,6 +223,7 @@ static void runtest(void) {
lt_insert_write(0, 'b', 8); lt_insert_write(0, 'b', 8);
lt_insert_write(0, 'b', 9); lt_insert_write(0, 'b', 9);
lt_insert_read (DB_LOCK_NOTGRANTED, 'a', 3, 7); lt_insert_read (DB_LOCK_NOTGRANTED, 'a', 3, 7);
lt_unlock('b');
close_tree(); close_tree();
/* ********************* */ /* ********************* */
setup_tree(); setup_tree();
...@@ -219,6 +232,7 @@ static void runtest(void) { ...@@ -219,6 +232,7 @@ static void runtest(void) {
lt_insert_write(0, 'a', 3); lt_insert_write(0, 'a', 3);
lt_insert_write(0, 'a', 4); lt_insert_write(0, 'a', 4);
lt_insert_read (0, 'a', 3, 7); lt_insert_read (0, 'a', 3, 7);
lt_unlock('a');
close_tree(); close_tree();
/* ********************* */ /* ********************* */
setup_tree(); setup_tree();
...@@ -227,6 +241,7 @@ static void runtest(void) { ...@@ -227,6 +241,7 @@ static void runtest(void) {
lt_insert_write(0, 'b', 3); lt_insert_write(0, 'b', 3);
lt_insert_write(0, 'b', 4); lt_insert_write(0, 'b', 4);
lt_insert_read (DB_LOCK_NOTGRANTED, 'a', 3, 7); lt_insert_read (DB_LOCK_NOTGRANTED, 'a', 3, 7);
lt_unlock('b');
close_tree(); close_tree();
/* ********************* */ /* ********************* */
setup_tree(); setup_tree();
...@@ -235,6 +250,7 @@ static void runtest(void) { ...@@ -235,6 +250,7 @@ static void runtest(void) {
lt_insert_write(0, 'a', 4); lt_insert_write(0, 'a', 4);
lt_insert_write(0, 'a', 5); lt_insert_write(0, 'a', 5);
lt_insert_write(0, 'a', 3); lt_insert_write(0, 'a', 3);
lt_unlock('a');
close_tree(); close_tree();
/* ********************* */ /* ********************* */
setup_tree(); setup_tree();
...@@ -243,6 +259,8 @@ static void runtest(void) { ...@@ -243,6 +259,8 @@ static void runtest(void) {
lt_insert_write(0, 'b', 4); lt_insert_write(0, 'b', 4);
lt_insert_write(0, 'b', 5); lt_insert_write(0, 'b', 5);
lt_insert_write(0, 'a', 3); lt_insert_write(0, 'a', 3);
lt_unlock('a');
lt_unlock('b');
close_tree(); close_tree();
/* ********************* */ /* ********************* */
setup_tree(); setup_tree();
...@@ -256,6 +274,7 @@ static void runtest(void) { ...@@ -256,6 +274,7 @@ static void runtest(void) {
lt_insert_read (DB_LOCK_NOTGRANTED, 'a', 3, 3); lt_insert_read (DB_LOCK_NOTGRANTED, 'a', 3, 3);
lt_unlock('b'); lt_unlock('b');
lt_insert_read (0, 'a', 3, 3); lt_insert_read (0, 'a', 3, 3);
lt_unlock('a');
close_tree(); close_tree();
/* ********************* */ /* ********************* */
setup_tree(); setup_tree();
...@@ -263,6 +282,7 @@ static void runtest(void) { ...@@ -263,6 +282,7 @@ static void runtest(void) {
lt_insert_write(0, 'a', 3); lt_insert_write(0, 'a', 3);
lt_insert_write(0, 'b', 2); lt_insert_write(0, 'b', 2);
lt_unlock('b'); lt_unlock('b');
lt_unlock('a');
close_tree(); close_tree();
/* ********************* */ /* ********************* */
} }
......
...@@ -8,15 +8,8 @@ int main(int argc, const char *argv[]) { ...@@ -8,15 +8,8 @@ int main(int argc, const char *argv[]) {
int r; int r;
parse_args(argc, argv); parse_args(argc, argv);
lth = NULL; lth = NULL;
for (failon = 1; failon <= 2; failon++) { r = toku_lth_create(&lth);
mallocced = 0;
r = toku_lth_create(&lth, fail_malloc, toku_free, toku_realloc);
CKERR2(r, ENOMEM);
assert(lth==NULL);
}
r = toku_lth_create(&lth, toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(lth); assert(lth);
toku_lth_close(lth); toku_lth_close(lth);
...@@ -25,7 +18,7 @@ int main(int argc, const char *argv[]) { ...@@ -25,7 +18,7 @@ int main(int argc, const char *argv[]) {
size_t i; size_t i;
size_t iterations = 512 << 2; size_t iterations = 512 << 2;
r = toku_lth_create(&lth, toku_malloc, toku_free, toku_realloc); r = toku_lth_create(&lth);
CKERR(r); CKERR(r);
assert(lth); assert(lth);
for (i = 1; i < iterations; i++) { for (i = 1; i < iterations; i++) {
...@@ -54,7 +47,7 @@ int main(int argc, const char *argv[]) { ...@@ -54,7 +47,7 @@ int main(int argc, const char *argv[]) {
toku_lth_close(lth); toku_lth_close(lth);
lth = NULL; lth = NULL;
r = toku_lth_create(&lth, toku_malloc, toku_free, toku_realloc); r = toku_lth_create(&lth);
CKERR(r); CKERR(r);
assert(lth); assert(lth);
for (i = 1; i < iterations; i++) { for (i = 1; i < iterations; i++) {
...@@ -68,7 +61,7 @@ int main(int argc, const char *argv[]) { ...@@ -68,7 +61,7 @@ int main(int argc, const char *argv[]) {
lth = NULL; lth = NULL;
r = toku_lth_create(&lth, toku_malloc, toku_free, toku_realloc); r = toku_lth_create(&lth);
CKERR(r); CKERR(r);
assert(lth); assert(lth);
for (i = iterations - 1; i >= 1; i--) { for (i = iterations - 1; i >= 1; i--) {
...@@ -78,14 +71,5 @@ int main(int argc, const char *argv[]) { ...@@ -78,14 +71,5 @@ int main(int argc, const char *argv[]) {
toku_lth_close(lth); toku_lth_close(lth);
lth = NULL; lth = NULL;
failon = 3;
mallocced = 0;
r = toku_lth_create(&lth, fail_malloc, toku_free, toku_realloc);
CKERR(r);
assert(lth);
r = toku_lth_insert(lth, (toku_lock_tree*)1);
CKERR2(r, ENOMEM);
toku_lth_close(lth);
lth = NULL;
return 0; return 0;
} }
...@@ -8,8 +8,8 @@ toku_ltm* ltm = NULL; ...@@ -8,8 +8,8 @@ toku_ltm* ltm = NULL;
DB* db = (DB*)1; DB* db = (DB*)1;
enum { MAX_LT_LOCKS = 10 }; enum { MAX_LT_LOCKS = 10 };
uint32_t max_locks = MAX_LT_LOCKS; uint32_t max_locks = MAX_LT_LOCKS;
uint64_t max_lock_memory = MAX_LT_LOCKS*64; uint64_t max_lock_memory = MAX_LT_LOCKS*256;
BOOL duplicates = FALSE; bool duplicates = false;
int nums[10000]; int nums[10000];
DBT _keys_left[2]; DBT _keys_left[2];
...@@ -37,9 +37,7 @@ static void init_query(void) { ...@@ -37,9 +37,7 @@ static void init_query(void) {
static void setup_tree(void) { static void setup_tree(void) {
assert(!lt && !ltm); assert(!lt && !ltm);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(ltm); assert(ltm);
//ask ltm for lock tree //ask ltm for lock tree
...@@ -67,12 +65,12 @@ static DBT* set_to_infty(DBT *dbt, int value) { ...@@ -67,12 +65,12 @@ static DBT* set_to_infty(DBT *dbt, int value) {
if (value == infinite) return (DBT*)toku_lt_infinity; if (value == infinite) return (DBT*)toku_lt_infinity;
if (value == neg_infinite) return (DBT*)toku_lt_neg_infinity; if (value == neg_infinite) return (DBT*)toku_lt_neg_infinity;
if (value == null) return dbt_init(dbt, NULL, 0); if (value == null) return dbt_init(dbt, NULL, 0);
assert(value >= 0); assert(0 <= value && (unsigned) value < sizeof nums / sizeof nums[0]);
return dbt_init(dbt, &nums[value], sizeof(nums[0])); return dbt_init(dbt, &nums[value], sizeof(nums[0]));
} }
static void lt_insert(int r_expect, char txn, int key_l, int key_r, BOOL read_flag) { static void lt_insert(int r_expect, char txn, int key_l, int key_r, bool read_flag) {
DBT _key_left; DBT _key_left;
DBT _key_right; DBT _key_right;
DBT* key_left = &_key_left; DBT* key_left = &_key_left;
...@@ -88,26 +86,29 @@ static void lt_insert(int r_expect, char txn, int key_l, int key_r, BOOL read_fl ...@@ -88,26 +86,29 @@ static void lt_insert(int r_expect, char txn, int key_l, int key_r, BOOL read_fl
TXNID local_txn = (TXNID) (size_t) txn; TXNID local_txn = (TXNID) (size_t) txn;
if (read_flag) if (read_flag)
r = toku_lt_acquire_range_read_lock(lt, db, local_txn, r = toku_lt_acquire_range_read_lock(lt, db, local_txn, key_left, key_right);
key_left,
key_right);
else else
r = toku_lt_acquire_write_lock(lt, db, local_txn, key_left); r = toku_lt_acquire_write_lock(lt, db, local_txn, key_left);
CKERR2(r, r_expect); CKERR2(r, r_expect);
} }
static int lt_insert_write_no_check(char txn, int key_p) {
DBT key;
TXNID local_txn = (TXNID) (size_t) txn;
r = toku_lt_acquire_write_lock(lt, db, local_txn, dbt_init(&key, &nums[key_p], sizeof(nums[0])));
return r;
}
static void lt_insert_read(int r_expect, char txn, int key_l, int key_r) { static void lt_insert_read(int r_expect, char txn, int key_l, int key_r) {
lt_insert(r_expect, txn, key_l, key_r, TRUE); lt_insert(r_expect, txn, key_l, key_r, true);
} }
static void lt_insert_write(int r_expect, char txn, int key_l) { static void lt_insert_write(int r_expect, char txn, int key_l) {
lt_insert(r_expect, txn, key_l, 0, FALSE); lt_insert(r_expect, txn, key_l, 0, false);
} }
static void lt_unlock(char ctxn) { static void lt_unlock(char ctxn) {
int retval; int retval = toku_lt_unlock(lt, (TXNID) (size_t) ctxn); CKERR(retval);
retval = toku_lt_unlock(lt, (TXNID) (size_t) ctxn);
CKERR(retval);
} }
static void run_escalation_test(void) { static void run_escalation_test(void) {
...@@ -120,6 +121,7 @@ static void run_escalation_test(void) { ...@@ -120,6 +121,7 @@ static void run_escalation_test(void) {
lt_insert_write(0, 'a', i); lt_insert_write(0, 'a', i);
assert(lt->lock_escalation_allowed); assert(lt->lock_escalation_allowed);
} }
lt_unlock('a');
close_tree(); close_tree();
/* ******************** */ /* ******************** */
/* interleaving transactions, /* interleaving transactions,
...@@ -128,17 +130,19 @@ static void run_escalation_test(void) { ...@@ -128,17 +130,19 @@ static void run_escalation_test(void) {
make sure lock escalation fails, and that we run out of locks */ make sure lock escalation fails, and that we run out of locks */
setup_tree(); setup_tree();
// this should grab ten locks successfully // this should grab ten locks successfully
for (i = 1; i < 10; i+=2) { for (i = 1; i < 20; i++) {
lt_insert_write(0, 'a', i); r = lt_insert_write_no_check(i&1 ? 'a' : 'b', i);
lt_insert_write(0, 'b', i+1); if (r != 0)
break;
} }
lt_insert_write(TOKUDB_OUT_OF_LOCKS, 'a', 100); lt_insert_write(TOKUDB_OUT_OF_LOCKS, 'a', 100);
lt_insert_write(TOKUDB_OUT_OF_LOCKS, 'b', 100); lt_insert_write(TOKUDB_OUT_OF_LOCKS, 'b', 100);
lt_insert_write(TOKUDB_OUT_OF_LOCKS, 'c', 100); lt_insert_write(TOKUDB_OUT_OF_LOCKS, 'c', 100);
lt_unlock('a'); lt_unlock('b');
close_tree(); close_tree();
/* ******************** */ /* ******************** */
/* /*
test that escalation allowed flag goes from FALSE->TRUE->FALSE test that escalation allowed flag goes from false->true->FALSE
TXN A grabs 1 3 5 7 9 TXN A grabs 1 3 5 7 9
TXN B grabs 2 4 6 8 10 TXN B grabs 2 4 6 8 10
try to grab another lock, fail, lock escalation should be disabled try to grab another lock, fail, lock escalation should be disabled
...@@ -150,9 +154,10 @@ static void run_escalation_test(void) { ...@@ -150,9 +154,10 @@ static void run_escalation_test(void) {
setup_tree(); setup_tree();
assert(lt->lock_escalation_allowed); assert(lt->lock_escalation_allowed);
// this should grab ten locks successfully // this should grab ten locks successfully
for (i = 1; i < 10; i+=2) { for (i = 1; i < 20; i++) {
lt_insert_write(0, 'a', i); r = lt_insert_write_no_check(i&1 ? 'a' : 'b', i);
lt_insert_write(0, 'b', i+1); if (r != 0)
break;
} }
assert(lt->lock_escalation_allowed); assert(lt->lock_escalation_allowed);
lt_insert_write(TOKUDB_OUT_OF_LOCKS, 'a', 100); lt_insert_write(TOKUDB_OUT_OF_LOCKS, 'a', 100);
...@@ -167,6 +172,7 @@ static void run_escalation_test(void) { ...@@ -167,6 +172,7 @@ static void run_escalation_test(void) {
lt_insert_write(0, 'c', i); lt_insert_write(0, 'c', i);
assert(lt->lock_escalation_allowed); assert(lt->lock_escalation_allowed);
} }
lt_unlock('a'); lt_unlock('c');
close_tree(); close_tree();
/* ******************** */ /* ******************** */
/* /*
...@@ -196,6 +202,7 @@ static void run_escalation_test(void) { ...@@ -196,6 +202,7 @@ static void run_escalation_test(void) {
lt_insert_write(0, 'c', i); lt_insert_write(0, 'c', i);
assert(lt->lock_escalation_allowed); assert(lt->lock_escalation_allowed);
} }
lt_unlock('a'); lt_unlock('c');
close_tree(); close_tree();
/* ******************** */ /* ******************** */
#if 0 //Only use when messy transactions are enabled. #if 0 //Only use when messy transactions are enabled.
...@@ -234,6 +241,7 @@ static void run_escalation_test(void) { ...@@ -234,6 +241,7 @@ static void run_escalation_test(void) {
lt_insert_write(0, 'a', i); lt_insert_write(0, 'a', i);
} }
lt_insert_read(0, 'a', 10, 10); lt_insert_read(0, 'a', 10, 10);
lt_unlock('a');
close_tree(); close_tree();
/* ******************** */ /* ******************** */
/* escalate on read lock of different transaction. */ /* escalate on read lock of different transaction. */
...@@ -242,6 +250,7 @@ static void run_escalation_test(void) { ...@@ -242,6 +250,7 @@ static void run_escalation_test(void) {
lt_insert_write(0, 'a', i); lt_insert_write(0, 'a', i);
} }
lt_insert_read(0, 'b', 10, 10); lt_insert_read(0, 'b', 10, 10);
lt_unlock('a'); lt_unlock('b');
close_tree(); close_tree();
/* ******************** */ /* ******************** */
/* txn A grabs write lock 0,9 /* txn A grabs write lock 0,9
...@@ -257,6 +266,7 @@ static void run_escalation_test(void) { ...@@ -257,6 +266,7 @@ static void run_escalation_test(void) {
lt_insert_write(0, 'b', i); lt_insert_write(0, 'b', i);
assert(lt->lock_escalation_allowed); assert(lt->lock_escalation_allowed);
} }
lt_unlock('a'); lt_unlock('b');
close_tree(); close_tree();
/* ******************** */ /* ******************** */
/* [1-A-5] [10-B-15] [20-A-25] BORDER WRITE /* [1-A-5] [10-B-15] [20-A-25] BORDER WRITE
...@@ -280,6 +290,7 @@ static void run_escalation_test(void) { ...@@ -280,6 +290,7 @@ static void run_escalation_test(void) {
lt_insert_write(DB_LOCK_NOTGRANTED, 'b', 24); lt_insert_write(DB_LOCK_NOTGRANTED, 'b', 24);
lt_insert_write(0, 'a', 14); lt_insert_write(0, 'a', 14);
lt_insert_write(0, 'b', 4); lt_insert_write(0, 'b', 4);
lt_unlock('a'); lt_unlock('b');
close_tree(); close_tree();
/* ******************** */ /* ******************** */
/* Test read lock escalation, no writes. */ /* Test read lock escalation, no writes. */
...@@ -288,6 +299,7 @@ static void run_escalation_test(void) { ...@@ -288,6 +299,7 @@ static void run_escalation_test(void) {
for (i = 0; i < 1000; i ++) { for (i = 0; i < 1000; i ++) {
lt_insert_read (0, 'b', i, i); lt_insert_read (0, 'b', i, i);
} }
lt_unlock('b');
close_tree(); close_tree();
/* ******************** */ /* ******************** */
/* Test read lock escalation, writes of same kind. */ /* Test read lock escalation, writes of same kind. */
...@@ -298,6 +310,7 @@ static void run_escalation_test(void) { ...@@ -298,6 +310,7 @@ static void run_escalation_test(void) {
for (i = 0; i < 1000; i ++) { for (i = 0; i < 1000; i ++) {
lt_insert_read (0, 'b', i, i); lt_insert_read (0, 'b', i, i);
} }
lt_unlock('b');
close_tree(); close_tree();
/* ******************** */ /* ******************** */
/* Test read lock escalation, writes of other kind. */ /* Test read lock escalation, writes of other kind. */
...@@ -312,6 +325,7 @@ static void run_escalation_test(void) { ...@@ -312,6 +325,7 @@ static void run_escalation_test(void) {
if (i % 5 == 0) { continue; } if (i % 5 == 0) { continue; }
lt_insert_read (0, 'a', i, i); lt_insert_read (0, 'a', i, i);
} }
lt_unlock('a'); lt_unlock('b'); lt_unlock('c');
close_tree(); close_tree();
/* ******************** */ /* ******************** */
/* /*
...@@ -320,7 +334,7 @@ static void run_escalation_test(void) { ...@@ -320,7 +334,7 @@ static void run_escalation_test(void) {
txn C attempts to grab lock, escalation, and lock grab, should fail txn C attempts to grab lock, escalation, and lock grab, should fail
lock lock
*/ */
/* #if 0
setup_tree(); setup_tree();
assert(lt->lock_escalation_allowed); assert(lt->lock_escalation_allowed);
// this should grab ten locks successfully // this should grab ten locks successfully
...@@ -346,7 +360,7 @@ static void run_escalation_test(void) { ...@@ -346,7 +360,7 @@ static void run_escalation_test(void) {
assert(lt->lock_escalation_allowed); assert(lt->lock_escalation_allowed);
} }
close_tree(); close_tree();
*/ #endif
/* ******************** */ /* ******************** */
} }
......
...@@ -17,9 +17,7 @@ int nums[10000]; ...@@ -17,9 +17,7 @@ int nums[10000];
static void setup_ltm(void) { static void setup_ltm(void) {
assert(!ltm); assert(!ltm);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(ltm); assert(ltm);
} }
......
...@@ -20,9 +20,7 @@ int nums[10000]; ...@@ -20,9 +20,7 @@ int nums[10000];
static void setup_ltm(void) { static void setup_ltm(void) {
assert(!ltm); assert(!ltm);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(ltm); assert(ltm);
} }
......
...@@ -36,14 +36,10 @@ static void init_query(void) { ...@@ -36,14 +36,10 @@ static void init_query(void) {
static void setup_tree(void) { static void setup_tree(void) {
assert(!lt && !ltm); assert(!lt && !ltm);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(ltm); assert(ltm);
r = toku_lt_create(&lt, dbpanic, ltm, r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(lt); assert(lt);
init_query(); init_query();
...@@ -90,6 +86,10 @@ static void lt_insert_write_range(int r_expect, char txn, int key_l, int key_r) ...@@ -90,6 +86,10 @@ static void lt_insert_write_range(int r_expect, char txn, int key_l, int key_r)
lt_verify(); lt_verify();
} }
static void lt_unlock(TXNID txnid) {
r= toku_lt_unlock(lt, txnid); CKERR(r);
}
static void runtest(void) { static void runtest(void) {
setup_tree(); setup_tree();
lt_insert_write_range(0, 'a', 5, 15); lt_insert_write_range(0, 'a', 5, 15);
...@@ -98,6 +98,7 @@ static void runtest(void) { ...@@ -98,6 +98,7 @@ static void runtest(void) {
lt_insert_write_range(DB_LOCK_NOTGRANTED, 'b', k, k); lt_insert_write_range(DB_LOCK_NOTGRANTED, 'b', k, k);
for (int k = 5; k <= 20; k++) for (int k = 5; k <= 20; k++)
lt_insert_write_range(0, 'a', k, k); lt_insert_write_range(0, 'a', k, k);
lt_unlock('a');
close_tree(); close_tree();
setup_tree(); setup_tree();
...@@ -107,6 +108,7 @@ static void runtest(void) { ...@@ -107,6 +108,7 @@ static void runtest(void) {
lt_insert_write_range(DB_LOCK_NOTGRANTED, 'b', k, k); lt_insert_write_range(DB_LOCK_NOTGRANTED, 'b', k, k);
for (int k = 5; k <= 20; k++) for (int k = 5; k <= 20; k++)
lt_insert_write_range(0, 'a', k, k); lt_insert_write_range(0, 'a', k, k);
lt_unlock('a');
close_tree(); close_tree();
setup_tree(); setup_tree();
...@@ -115,18 +117,21 @@ static void runtest(void) { ...@@ -115,18 +117,21 @@ static void runtest(void) {
lt_insert_write_range(0, 'a', k, k); lt_insert_write_range(0, 'a', k, k);
for (int k = 10; k <= 20; k++) for (int k = 10; k <= 20; k++)
lt_insert_write_range(DB_LOCK_NOTGRANTED, 'b', k, k); lt_insert_write_range(DB_LOCK_NOTGRANTED, 'b', k, k);
lt_unlock('a');
close_tree(); close_tree();
setup_tree(); setup_tree();
lt_insert_write_range(0, 'a', 5, 10); lt_insert_write_range(0, 'a', 5, 10);
lt_insert_write_range(0, 'a', 20, 30); lt_insert_write_range(0, 'a', 20, 30);
lt_insert_write_range(0, 'a', 1, 8); lt_insert_write_range(0, 'a', 1, 8);
lt_unlock('a');
close_tree(); close_tree();
setup_tree(); setup_tree();
lt_insert_write_range(0, 'a', 5, 10); lt_insert_write_range(0, 'a', 5, 10);
lt_insert_write_range(0, 'a', 20, 30); lt_insert_write_range(0, 'a', 20, 30);
lt_insert_write_range(0, 'a', 25, 35); lt_insert_write_range(0, 'a', 25, 35);
lt_unlock('a');
close_tree(); close_tree();
} }
......
...@@ -43,11 +43,11 @@ int main(int argc, const char *argv[]) { ...@@ -43,11 +43,11 @@ int main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
DBT key_l; dbt_init(&key_l, "L", 1); DBT key_l; dbt_init(&key_l, "L", 1);
......
...@@ -43,11 +43,11 @@ int main(int argc, const char *argv[]) { ...@@ -43,11 +43,11 @@ int main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
DBT key_l; dbt_init(&key_l, "L", 1); DBT key_l; dbt_init(&key_l, "L", 1);
......
...@@ -33,11 +33,11 @@ int main(int argc, const char *argv[]) { ...@@ -33,11 +33,11 @@ int main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
const TXNID txn_a = 1; const TXNID txn_a = 1;
......
...@@ -33,11 +33,11 @@ int main(int argc, const char *argv[]) { ...@@ -33,11 +33,11 @@ int main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
DBT key_l; dbt_init(&key_l, "L", 1); DBT key_l; dbt_init(&key_l, "L", 1);
......
...@@ -33,11 +33,11 @@ int main(int argc, const char *argv[]) { ...@@ -33,11 +33,11 @@ int main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
DBT key_l; dbt_init(&key_l, "L", 1); DBT key_l; dbt_init(&key_l, "L", 1);
......
...@@ -50,11 +50,11 @@ int main(int argc, const char *argv[]) { ...@@ -50,11 +50,11 @@ int main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
const TXNID txn_a = 1; const TXNID txn_a = 1;
......
...@@ -30,7 +30,7 @@ int main(int argc, const char *argv[]) { ...@@ -30,7 +30,7 @@ int main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
uint64_t target_wait_time, the_wait_time; uint64_t target_wait_time, the_wait_time;
......
...@@ -3,7 +3,18 @@ ...@@ -3,7 +3,18 @@
// //
// example: ./benchmark_point_write_locks.tlog --max_locks 1000000 --max_lock_memory 1000000000 --nrows 1000000 // example: ./benchmark_point_write_locks.tlog --max_locks 1000000 --max_lock_memory 1000000000 --nrows 1000000
#define TOKU_ALLOW_DEPRECATED
#include <malloc.h>
#include "test.h" #include "test.h"
#include <byteswap.h>
static uint64_t htonl64(uint64_t x) {
#if BYTE_ORDER == LITTLE_ENDIAN
return bswap_64(x);
#else
#error
#endif
}
struct my_ltm_status { struct my_ltm_status {
uint32_t max_locks, curr_locks; uint32_t max_locks, curr_locks;
...@@ -15,12 +26,32 @@ static void my_ltm_get_status(toku_ltm *ltm, struct my_ltm_status *my_status) { ...@@ -15,12 +26,32 @@ static void my_ltm_get_status(toku_ltm *ltm, struct my_ltm_status *my_status) {
toku_ltm_get_status(ltm, &my_status->max_locks, &my_status->curr_locks, &my_status->max_lock_memory, &my_status->curr_lock_memory, &my_status->status); toku_ltm_get_status(ltm, &my_status->max_locks, &my_status->curr_locks, &my_status->max_lock_memory, &my_status->curr_lock_memory, &my_status->status);
} }
static void *my_malloc(size_t s) {
void * p = malloc(s);
if (verbose)
printf("%s %lu %lu\n", __FUNCTION__, s, malloc_usable_size(p));
return p;
}
static void *my_realloc(void *p, size_t s) {
if (verbose)
printf("%s %p %lu\n", __FUNCTION__, p, s);
return realloc(p, s);
}
static void my_free(void *p) {
if (verbose)
printf("%s %p %lu\n", __FUNCTION__, p, malloc_usable_size(p));
free(p);
}
int main(int argc, const char *argv[]) { int main(int argc, const char *argv[]) {
int r; int r;
uint32_t max_locks = 2; uint32_t max_locks = 2;
uint64_t max_lock_memory = 4096; uint64_t max_lock_memory = 4096;
uint64_t nrows = 1; uint64_t nrows = 1;
bool do_malloc_trace = false;
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) { if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) {
...@@ -43,12 +74,22 @@ int main(int argc, const char *argv[]) { ...@@ -43,12 +74,22 @@ int main(int argc, const char *argv[]) {
nrows = atoi(argv[++i]); nrows = atoi(argv[++i]);
continue; continue;
} }
if (strcmp(argv[i], "--malloc") == 0) {
do_malloc_trace = true;
continue;
}
assert(0); assert(0);
} }
if (do_malloc_trace) {
toku_set_func_malloc(my_malloc);
toku_set_func_free(my_free);
toku_set_func_realloc(my_realloc);
}
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
struct my_ltm_status s; struct my_ltm_status s;
...@@ -59,14 +100,15 @@ int main(int argc, const char *argv[]) { ...@@ -59,14 +100,15 @@ int main(int argc, const char *argv[]) {
assert(s.curr_lock_memory == 0); assert(s.curr_lock_memory == 0);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
DB *db_a = (DB *) 2; DB *db_a = (DB *) 2;
TXNID txn_a = 1; TXNID txn_a = 1;
// acquire the locks on keys 1 .. nrows // acquire the locks on keys 1 .. nrows
for (uint64_t k = 1; k <= nrows; k++) { for (uint64_t i = 1; i <= nrows; i++) {
uint64_t k = htonl64(i);
DBT key = { .data = &k, .size = sizeof k }; DBT key = { .data = &k, .size = sizeof k };
r = toku_lt_acquire_write_lock(lt, db_a, txn_a, &key); r = toku_lt_acquire_write_lock(lt, db_a, txn_a, &key);
if (r != 0) { if (r != 0) {
...@@ -77,12 +119,12 @@ int main(int argc, const char *argv[]) { ...@@ -77,12 +119,12 @@ int main(int argc, const char *argv[]) {
struct my_ltm_status t; struct my_ltm_status t;
my_ltm_get_status(ltm, &t); my_ltm_get_status(ltm, &t);
assert(t.max_locks == max_locks); assert(t.max_locks == max_locks);
assert(t.curr_locks == k); assert(t.curr_locks == i);
assert(t.max_lock_memory == max_lock_memory); assert(t.max_lock_memory == max_lock_memory);
assert(t.curr_lock_memory > s.curr_lock_memory); assert(t.curr_lock_memory > s.curr_lock_memory);
if (verbose) if (verbose)
printf("%"PRIu64" %"PRIu64"\n", k, t.curr_lock_memory); printf("%"PRIu64" %"PRIu64"\n", i, t.curr_lock_memory - s.curr_lock_memory);
s = t; s = t;
} }
...@@ -91,6 +133,9 @@ int main(int argc, const char *argv[]) { ...@@ -91,6 +133,9 @@ int main(int argc, const char *argv[]) {
// release the locks // release the locks
r = toku_lt_unlock(lt, txn_a); assert(r == 0); r = toku_lt_unlock(lt, txn_a); assert(r == 0);
my_ltm_get_status(ltm, &s);
assert(s.curr_locks == 0);
// shutdown // shutdown
r = toku_lt_close(lt); assert(r == 0); r = toku_lt_close(lt); assert(r == 0);
r = toku_ltm_close(ltm); assert(r == 0); r = toku_ltm_close(ltm); assert(r == 0);
......
// benchmark point write locks acquisition rate.
// rate = nrows / time to execute the benchmark.
//
// example: ./benchmark_point_write_locks.tlog --max_locks 1000000 --max_lock_memory 1000000000 --nrows 1000000
#define TOKU_ALLOW_DEPRECATED
#include <malloc.h>
#include "test.h"
#include <byteswap.h>
static uint64_t htonl64(uint64_t x) {
#if BYTE_ORDER == LITTLE_ENDIAN
return bswap_64(x);
#else
#error
#endif
}
struct my_ltm_status {
uint32_t max_locks, curr_locks;
uint64_t max_lock_memory, curr_lock_memory;
LTM_STATUS_S status;
};
static void my_ltm_get_status(toku_ltm *ltm, struct my_ltm_status *my_status) {
toku_ltm_get_status(ltm, &my_status->max_locks, &my_status->curr_locks, &my_status->max_lock_memory, &my_status->curr_lock_memory, &my_status->status);
}
static void *my_malloc(size_t s) {
void * p = malloc(s);
if (verbose)
printf("%s %lu %lu\n", __FUNCTION__, s, malloc_usable_size(p));
return p;
}
static void *my_realloc(void *p, size_t s) {
if (verbose)
printf("%s %p %lu\n", __FUNCTION__, p, s);
return realloc(p, s);
}
static void my_free(void *p) {
if (verbose)
printf("%s %p %lu\n", __FUNCTION__, p, malloc_usable_size(p));
free(p);
}
int main(int argc, const char *argv[]) {
int r;
uint32_t max_locks = 2;
uint64_t max_lock_memory = 4096;
uint64_t nrows = 1;
bool do_malloc_trace = false;
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) {
verbose++;
continue;
}
if (strcmp(argv[i], "-q") == 0 || strcmp(argv[i], "--quiet") == 0) {
if (verbose > 0) verbose--;
continue;
}
if (strcmp(argv[i], "--max_locks") == 0 && i+1 < argc) {
max_locks = atoi(argv[++i]);
continue;
}
if (strcmp(argv[i], "--max_lock_memory") == 0 && i+1 < argc) {
max_lock_memory = atoi(argv[++i]);
continue;
}
if (strcmp(argv[i], "--nrows") == 0 && i+1 < argc) {
nrows = atoi(argv[++i]);
continue;
}
if (strcmp(argv[i], "--malloc") == 0) {
do_malloc_trace = true;
continue;
}
assert(0);
}
if (do_malloc_trace) {
toku_set_func_malloc(my_malloc);
toku_set_func_free(my_free);
toku_set_func_realloc(my_realloc);
}
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm);
struct my_ltm_status s;
my_ltm_get_status(ltm, &s);
assert(s.max_locks == max_locks);
assert(s.curr_locks == 0);
assert(s.max_lock_memory == max_lock_memory);
assert(s.curr_lock_memory == 0);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt);
DB *db_a = (DB *) 2;
TXNID txn_a = 1;
// acquire the locks on keys 1 .. nrows
for (uint64_t i = 1; i <= nrows; i++) {
uint64_t k_left = htonl64(2*i);
uint64_t k_right = htonl64(2*i+1);
DBT key_left = { .data = &k_left, .size = sizeof k_left };
DBT key_right = { .data = &k_right, .size = sizeof k_right };
r = toku_lt_acquire_range_write_lock(lt, db_a, txn_a, &key_left, &key_right);
if (r != 0) {
assert(r == TOKUDB_OUT_OF_LOCKS);
break;
}
struct my_ltm_status t;
my_ltm_get_status(ltm, &t);
assert(t.max_locks == max_locks);
assert(t.curr_locks == i);
assert(t.max_lock_memory == max_lock_memory);
assert(t.curr_lock_memory > s.curr_lock_memory);
if (verbose)
printf("%"PRIu64" %"PRIu64"\n", i, t.curr_lock_memory - s.curr_lock_memory);
s = t;
}
// release the locks
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
my_ltm_get_status(ltm, &s);
assert(s.curr_locks == 0);
// shutdown
r = toku_lt_close(lt); assert(r == 0);
r = toku_ltm_close(ltm); assert(r == 0);
return 0;
}
...@@ -36,14 +36,10 @@ static void init_query(void) { ...@@ -36,14 +36,10 @@ static void init_query(void) {
static void setup_tree(void) { static void setup_tree(void) {
assert(!lt && !ltm); assert(!lt && !ltm);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(ltm); assert(ltm);
r = toku_lt_create(&lt, dbpanic, ltm, r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(lt); assert(lt);
init_query(); init_query();
...@@ -106,45 +102,57 @@ static void lt_insert_write_range(int r_expect, char txn, int key_l, int key_r) ...@@ -106,45 +102,57 @@ static void lt_insert_write_range(int r_expect, char txn, int key_l, int key_r)
lt_verify(); lt_verify();
} }
static void lt_unlock(TXNID txnid) {
r = toku_lt_unlock(lt, txnid); CKERR(r);
}
static void runtest(void) { static void runtest(void) {
setup_tree(); setup_tree();
lt_insert_write_range(0, 'a', neg_infinite, infinite); lt_insert_write_range(0, 'a', neg_infinite, infinite);
lt_unlock('a');
close_tree(); close_tree();
setup_tree(); setup_tree();
lt_insert_read_range(0, 'a', 1, 2); lt_insert_read_range(0, 'a', 1, 2);
lt_insert_write_range(0, 'a', neg_infinite, infinite); lt_insert_write_range(0, 'a', neg_infinite, infinite);
lt_unlock('a');
close_tree(); close_tree();
setup_tree(); setup_tree();
lt_insert_write_range(0, 'a', 1, 2); lt_insert_write_range(0, 'a', 1, 2);
lt_insert_write_range(0, 'a', neg_infinite, infinite); lt_insert_write_range(0, 'a', neg_infinite, infinite);
lt_unlock('a');
close_tree(); close_tree();
setup_tree(); setup_tree();
lt_insert_read_range(0, 'b', 1, 2); lt_insert_read_range(0, 'b', 1, 2);
lt_insert_write_range(DB_LOCK_NOTGRANTED, 'a', neg_infinite, infinite); lt_insert_write_range(DB_LOCK_NOTGRANTED, 'a', neg_infinite, infinite);
lt_unlock('b');
close_tree(); close_tree();
setup_tree(); setup_tree();
lt_insert_write_range(0, 'b', 1, 2); lt_insert_write_range(0, 'b', 1, 2);
lt_insert_write_range(DB_LOCK_NOTGRANTED, 'a', neg_infinite, infinite); lt_insert_write_range(DB_LOCK_NOTGRANTED, 'a', neg_infinite, infinite);
lt_unlock('b');
close_tree(); close_tree();
setup_tree(); setup_tree();
lt_insert_write_range(0, 'a', neg_infinite, infinite); lt_insert_write_range(0, 'a', neg_infinite, infinite);
lt_insert_write_range(0, 'a', neg_infinite, infinite); lt_insert_write_range(0, 'a', neg_infinite, infinite);
lt_unlock('a');
close_tree(); close_tree();
setup_tree(); setup_tree();
lt_insert_write_range(0, 'a', neg_infinite, infinite); lt_insert_write_range(0, 'a', neg_infinite, infinite);
lt_insert_write_range(DB_LOCK_NOTGRANTED, 'b', neg_infinite, infinite); lt_insert_write_range(DB_LOCK_NOTGRANTED, 'b', neg_infinite, infinite);
lt_unlock('a');
close_tree(); close_tree();
setup_tree(); setup_tree();
lt_insert_write_range(0, 'a', neg_infinite, infinite); lt_insert_write_range(0, 'a', neg_infinite, infinite);
lt_insert_read_range(0, 'a', 1, 2); lt_insert_read_range(0, 'a', 1, 2);
lt_insert_read_range(DB_LOCK_NOTGRANTED, 'b', 10, 20); lt_insert_read_range(DB_LOCK_NOTGRANTED, 'b', 10, 20);
lt_unlock('a');
close_tree(); close_tree();
} }
......
...@@ -50,11 +50,11 @@ int main(int argc, const char *argv[]) { ...@@ -50,11 +50,11 @@ int main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
const TXNID txn_a = 1; const TXNID txn_a = 1;
......
...@@ -22,9 +22,7 @@ int main(int argc, const char *argv[]) { ...@@ -22,9 +22,7 @@ int main(int argc, const char *argv[]) {
int r; int r;
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, MAX_LOCKS, MAX_LOCK_MEMORY, dbpanic, r = toku_ltm_create(&ltm, MAX_LOCKS, MAX_LOCK_MEMORY, dbpanic, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
do_ltm_status(ltm); do_ltm_status(ltm);
#if 0 #if 0
......
...@@ -49,11 +49,11 @@ int main(int argc, const char *argv[]) { ...@@ -49,11 +49,11 @@ int main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
const TXNID txn_a = 1; const TXNID txn_a = 1;
......
...@@ -38,11 +38,11 @@ int main(int argc, const char *argv[]) { ...@@ -38,11 +38,11 @@ int main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
const TXNID txn_a = 1; const TXNID txn_a = 1;
......
...@@ -37,11 +37,11 @@ int main(int argc, const char *argv[]) { ...@@ -37,11 +37,11 @@ int main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
const TXNID txn_a = 1; const TXNID txn_a = 1;
......
...@@ -36,7 +36,7 @@ main(int argc, const char *argv[]) { ...@@ -36,7 +36,7 @@ main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
toku_ltm_set_lock_wait_time(ltm, 5000); toku_ltm_set_lock_wait_time(ltm, 5000);
...@@ -45,7 +45,7 @@ main(int argc, const char *argv[]) { ...@@ -45,7 +45,7 @@ main(int argc, const char *argv[]) {
toku_ltm_set_mutex(ltm, &my_mutex); toku_ltm_set_mutex(ltm, &my_mutex);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
const TXNID txn_a = 1; const TXNID txn_a = 1;
......
...@@ -54,14 +54,14 @@ int main(int argc, const char *argv[]) { ...@@ -54,14 +54,14 @@ int main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
toku_pthread_mutex_t my_mutex = TOKU_PTHREAD_MUTEX_INITIALIZER; toku_pthread_mutex_t my_mutex = TOKU_PTHREAD_MUTEX_INITIALIZER;
toku_ltm_set_mutex(ltm, &my_mutex); toku_ltm_set_mutex(ltm, &my_mutex);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
const TXNID txn_a = 1; const TXNID txn_a = 1;
......
...@@ -36,11 +36,11 @@ int main(int argc, const char *argv[]) { ...@@ -36,11 +36,11 @@ int main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
const TXNID txn_a = 1; const TXNID txn_a = 1;
......
...@@ -36,11 +36,11 @@ int main(int argc, const char *argv[]) { ...@@ -36,11 +36,11 @@ int main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
const TXNID txn_a = 1; const TXNID txn_a = 1;
......
...@@ -36,11 +36,11 @@ int main(int argc, const char *argv[]) { ...@@ -36,11 +36,11 @@ int main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
const TXNID txn_a = 1; const TXNID txn_a = 1;
......
...@@ -65,11 +65,11 @@ int main(int argc, const char *argv[]) { ...@@ -65,11 +65,11 @@ int main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
const TXNID txn_a = 1; const TXNID txn_a = 1;
......
...@@ -40,11 +40,11 @@ int main(int argc, const char *argv[]) { ...@@ -40,11 +40,11 @@ int main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
const TXNID txn_a = 1; const TXNID txn_a = 1;
......
...@@ -36,14 +36,10 @@ static void init_query(void) { ...@@ -36,14 +36,10 @@ static void init_query(void) {
static void setup_tree(void) { static void setup_tree(void) {
assert(!lt && !ltm); assert(!lt && !ltm);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(ltm); assert(ltm);
r = toku_lt_create(&lt, dbpanic, ltm, r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(lt); assert(lt);
init_query(); init_query();
...@@ -75,7 +71,7 @@ static DBT* set_to_infty(DBT *dbt, int value) { ...@@ -75,7 +71,7 @@ static DBT* set_to_infty(DBT *dbt, int value) {
} }
static void lt_insert(int r_expect, char txn, int key_l, static void lt_insert(int r_expect, char txn, int key_l,
int key_r, BOOL read_flag) { int key_r, bool read_flag) {
DBT _key_left; DBT _key_left;
DBT _key_right; DBT _key_right;
DBT* key_left = &_key_left; DBT* key_left = &_key_left;
...@@ -102,12 +98,12 @@ static void lt_insert(int r_expect, char txn, int key_l, ...@@ -102,12 +98,12 @@ static void lt_insert(int r_expect, char txn, int key_l,
static void lt_insert_read(int r_expect, char txn, int key_l, int key_r) UU(); static void lt_insert_read(int r_expect, char txn, int key_l, int key_r) UU();
static void lt_insert_read(int r_expect, char txn, int key_l, int key_r) { static void lt_insert_read(int r_expect, char txn, int key_l, int key_r) {
lt_insert(r_expect, txn, key_l, key_r, TRUE); lt_insert(r_expect, txn, key_l, key_r, true);
} }
static void lt_insert_write(int r_expect, char txn, int key_l) UU(); static void lt_insert_write(int r_expect, char txn, int key_l) UU();
static void lt_insert_write(int r_expect, char txn, int key_l) { static void lt_insert_write(int r_expect, char txn, int key_l) {
lt_insert(r_expect, txn, key_l, 0, FALSE); lt_insert(r_expect, txn, key_l, 0, false);
} }
static void lt_insert_write_range(int r_expect, char txn, int key_l, int key_r) { static void lt_insert_write_range(int r_expect, char txn, int key_l, int key_r) {
...@@ -141,30 +137,35 @@ static void runtest(void) { ...@@ -141,30 +137,35 @@ static void runtest(void) {
lt_insert_write_range(0, 'a', 30, 40); lt_insert_write_range(0, 'a', 30, 40);
lt_insert_write(0, 'a', 25); lt_insert_write(0, 'a', 25);
lt_insert_write(0, 'a', 50); lt_insert_write(0, 'a', 50);
lt_unlock('a');
close_tree(); close_tree();
// no overlaps (reverse) // no overlaps (reverse)
setup_tree(); setup_tree();
lt_insert_write_range(0, 'a', 30, 40); lt_insert_write_range(0, 'a', 30, 40);
lt_insert_write_range(0, 'a', 10, 20); lt_insert_write_range(0, 'a', 10, 20);
lt_unlock('a');
close_tree(); close_tree();
// overlaps // overlaps
setup_tree(); setup_tree();
lt_insert_write_range(0, 'a', 5, 15); lt_insert_write_range(0, 'a', 5, 15);
lt_insert_write_range(0, 'a', 10, 20); lt_insert_write_range(0, 'a', 10, 20);
lt_unlock('a');
close_tree(); close_tree();
setup_tree(); setup_tree();
lt_insert_write_range(0, 'a', 5, 15); lt_insert_write_range(0, 'a', 5, 15);
lt_insert_write_range(0, 'a', 30, 40); lt_insert_write_range(0, 'a', 30, 40);
lt_insert_write_range(0, 'a', 10, 20); lt_insert_write_range(0, 'a', 10, 20);
lt_unlock('a');
close_tree(); close_tree();
// overlaps (reverse) // overlaps (reverse)
setup_tree(); setup_tree();
lt_insert_write_range(0, 'a', 10, 20); lt_insert_write_range(0, 'a', 10, 20);
lt_insert_write_range(0, 'a', 5, 15); lt_insert_write_range(0, 'a', 5, 15);
lt_unlock('a');
close_tree(); close_tree();
// test borderwrite split // test borderwrite split
...@@ -173,6 +174,8 @@ static void runtest(void) { ...@@ -173,6 +174,8 @@ static void runtest(void) {
lt_insert_write_range(0, 'a', 5, 6); lt_insert_write_range(0, 'a', 5, 6);
lt_insert_write_range(0, 'a', 20, 30); lt_insert_write_range(0, 'a', 20, 30);
lt_insert_write_range(0, 'b', 10, 10); lt_insert_write_range(0, 'b', 10, 10);
lt_unlock('a');
lt_unlock('b');
close_tree(); close_tree();
// test borderwrite split // test borderwrite split
...@@ -180,38 +183,46 @@ static void runtest(void) { ...@@ -180,38 +183,46 @@ static void runtest(void) {
lt_insert_write_range(0, 'a', 0, 5); lt_insert_write_range(0, 'a', 0, 5);
lt_insert_write_range(0, 'a', 20, 30); lt_insert_write_range(0, 'a', 20, 30);
lt_insert_write_range(0, 'b', 10, 10); lt_insert_write_range(0, 'b', 10, 10);
lt_unlock('a');
lt_unlock('b');
close_tree(); close_tree();
setup_tree(); setup_tree();
lt_insert_write_range(0, 'a', 15, 20); lt_insert_write_range(0, 'a', 15, 20);
lt_insert_write_range(0, 'a', 10, 30); lt_insert_write_range(0, 'a', 10, 30);
lt_unlock('a');
close_tree(); close_tree();
setup_tree(); setup_tree();
lt_insert_write_range(0, 'a', 10, 30); lt_insert_write_range(0, 'a', 10, 30);
lt_insert_write_range(0, 'a', 15, 20); lt_insert_write_range(0, 'a', 15, 20);
lt_unlock('a');
close_tree(); close_tree();
setup_tree(); setup_tree();
lt_insert_write_range(0, 'b', 70, 80); lt_insert_write_range(0, 'b', 70, 80);
lt_insert_write_range(0, 'b', 60, 70); lt_insert_write_range(0, 'b', 60, 70);
lt_insert_write_range(0, 'b', 80, 90); lt_insert_write_range(0, 'b', 80, 90);
lt_unlock('b');
close_tree(); close_tree();
setup_tree(); setup_tree();
lt_insert_write(0, 'a', 5); lt_insert_write(0, 'a', 5);
lt_insert_write_range(0, 'a', 1, 20); lt_insert_write_range(0, 'a', 1, 20);
lt_unlock('a');
close_tree(); close_tree();
setup_tree(); setup_tree();
lt_insert_write(0, 'a', 5); lt_insert_write(0, 'a', 5);
lt_insert_write(0, 'a', 10); lt_insert_write(0, 'a', 10);
lt_unlock('a');
close_tree(); close_tree();
setup_tree(); setup_tree();
lt_insert_write(0, 'a', 5); lt_insert_write(0, 'a', 5);
lt_insert_write(0, 'a', 10); lt_insert_write(0, 'a', 10);
lt_insert_write_range(0, 'a', 1, 20); lt_insert_write_range(0, 'a', 1, 20);
lt_unlock('a');
close_tree(); close_tree();
} }
......
...@@ -36,14 +36,10 @@ static void init_query(void) { ...@@ -36,14 +36,10 @@ static void init_query(void) {
static void setup_tree(void) { static void setup_tree(void) {
assert(!lt && !ltm); assert(!lt && !ltm);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(ltm); assert(ltm);
r = toku_lt_create(&lt, dbpanic, ltm, r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(lt); assert(lt);
init_query(); init_query();
...@@ -113,6 +109,8 @@ static void runtest(void) { ...@@ -113,6 +109,8 @@ static void runtest(void) {
setup_tree(); setup_tree();
lt_insert_read_range(0, 'a', 1, 50); lt_insert_read_range(0, 'a', 1, 50);
lt_insert_write_range(0, 'b', 51, 99); lt_insert_write_range(0, 'b', 51, 99);
lt_unlock('a');
lt_unlock('b');
close_tree(); close_tree();
setup_tree(); setup_tree();
...@@ -124,6 +122,8 @@ static void runtest(void) { ...@@ -124,6 +122,8 @@ static void runtest(void) {
lt_insert_write_range(DB_LOCK_NOTGRANTED, 'b', 10, 11); lt_insert_write_range(DB_LOCK_NOTGRANTED, 'b', 10, 11);
lt_insert_write_range(DB_LOCK_NOTGRANTED, 'b', 55, 56); lt_insert_write_range(DB_LOCK_NOTGRANTED, 'b', 55, 56);
lt_insert_write_range(DB_LOCK_NOTGRANTED, 'b', 55, 65); lt_insert_write_range(DB_LOCK_NOTGRANTED, 'b', 55, 65);
lt_unlock('a');
lt_unlock('b');
close_tree(); close_tree();
} }
......
...@@ -36,14 +36,10 @@ static void init_query(void) { ...@@ -36,14 +36,10 @@ static void init_query(void) {
static void setup_tree(void) { static void setup_tree(void) {
assert(!lt && !ltm); assert(!lt && !ltm);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(ltm); assert(ltm);
r = toku_lt_create(&lt, dbpanic, ltm, r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
get_compare_fun_from_db,
toku_malloc, toku_free, toku_realloc);
CKERR(r); CKERR(r);
assert(lt); assert(lt);
init_query(); init_query();
...@@ -114,6 +110,8 @@ static void runtest(void) { ...@@ -114,6 +110,8 @@ static void runtest(void) {
setup_tree(); setup_tree();
lt_insert_write_range(0, 'a', 1, 50); lt_insert_write_range(0, 'a', 1, 50);
lt_insert_write_range(0, 'b', 51, 99); lt_insert_write_range(0, 'b', 51, 99);
lt_unlock('a');
lt_unlock('b');
close_tree(); close_tree();
setup_tree(); setup_tree();
...@@ -123,6 +121,8 @@ static void runtest(void) { ...@@ -123,6 +121,8 @@ static void runtest(void) {
lt_insert_write_range(0, 'b', 80, 90); lt_insert_write_range(0, 'b', 80, 90);
lt_insert_write_range(DB_LOCK_NOTGRANTED, 'b', 50, 60); lt_insert_write_range(DB_LOCK_NOTGRANTED, 'b', 50, 60);
lt_insert_write_range(DB_LOCK_NOTGRANTED, 'b', 50, 50); lt_insert_write_range(DB_LOCK_NOTGRANTED, 'b', 50, 50);
lt_unlock('a');
lt_unlock('b');
close_tree(); close_tree();
} }
......
...@@ -34,11 +34,11 @@ int main(int argc, const char *argv[]) { ...@@ -34,11 +34,11 @@ int main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
const TXNID txn_a = 1; const TXNID txn_a = 1;
......
...@@ -33,11 +33,11 @@ int main(int argc, const char *argv[]) { ...@@ -33,11 +33,11 @@ int main(int argc, const char *argv[]) {
// setup // setup
toku_ltm *ltm = NULL; toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm); assert(r == 0 && ltm);
toku_lock_tree *lt = NULL; toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db, toku_malloc, toku_free, toku_realloc); r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt); assert(r == 0 && lt);
const TXNID txn_a = 1; const TXNID txn_a = 1;
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
//Currently this is a stub implementation just so we can write and compile tests //Currently this is a stub implementation just so we can write and compile tests
//before actually implementing the range tree. //before actually implementing the range tree.
#include "memory.h"
#include <rangetree.h> #include <rangetree.h>
#include <errno.h> #include <errno.h>
#include <toku_assert.h> #include <toku_assert.h>
...@@ -21,11 +22,13 @@ struct __toku_range_tree_local { ...@@ -21,11 +22,13 @@ struct __toku_range_tree_local {
//Linear version only fields: //Linear version only fields:
toku_range* ranges; toku_range* ranges;
u_int32_t ranges_len; u_int32_t ranges_len;
// The number of ranges in the range tree
u_int32_t numelements;
}; };
#include <rangetree-internal.h> #include <rangetree-internal.h>
static u_int32_t minlen = 1;
static const u_int32_t minlen = 64;
static inline int static inline int
toku__rt_decrease_capacity(toku_range_tree* tree, u_int32_t _num) { toku__rt_decrease_capacity(toku_range_tree* tree, u_int32_t _num) {
...@@ -37,11 +40,15 @@ toku__rt_decrease_capacity(toku_range_tree* tree, u_int32_t _num) { ...@@ -37,11 +40,15 @@ toku__rt_decrease_capacity(toku_range_tree* tree, u_int32_t _num) {
while (temp_len >= num * 2) while (temp_len >= num * 2)
temp_len /= 2; temp_len /= 2;
assert(temp_len >= _num); //Sanity check. assert(temp_len >= _num); //Sanity check.
toku_range* temp_ranges = tree->realloc(tree->i.ranges, temp_len * sizeof(toku_range)); size_t start_size = toku_rt_memory_size(tree);
toku_range* temp_ranges = toku_realloc(tree->i.ranges, temp_len * sizeof(toku_range));
if (!temp_ranges) if (!temp_ranges)
return errno; return errno;
tree->i.ranges = temp_ranges; tree->i.ranges = temp_ranges;
tree->i.ranges_len = temp_len; tree->i.ranges_len = temp_len;
size_t end_size = toku_rt_memory_size(tree);
assert(start_size >= end_size);
tree->decr_memory_size(tree->extra_memory_size, start_size - end_size);
} }
return 0; return 0;
} }
...@@ -53,32 +60,36 @@ toku__rt_increase_capacity(toku_range_tree* tree, u_int32_t num) { ...@@ -53,32 +60,36 @@ toku__rt_increase_capacity(toku_range_tree* tree, u_int32_t num) {
u_int32_t temp_len = tree->i.ranges_len; u_int32_t temp_len = tree->i.ranges_len;
while (temp_len < num) while (temp_len < num)
temp_len *= 2; temp_len *= 2;
toku_range* temp_ranges = tree->realloc(tree->i.ranges, temp_len * sizeof(toku_range)); size_t start_size = toku_rt_memory_size(tree);
toku_range* temp_ranges = toku_realloc(tree->i.ranges, temp_len * sizeof(toku_range));
if (!temp_ranges) if (!temp_ranges)
return errno; return errno;
tree->i.ranges = temp_ranges; tree->i.ranges = temp_ranges;
tree->i.ranges_len = temp_len; tree->i.ranges_len = temp_len;
size_t end_size = toku_rt_memory_size(tree);
assert(end_size >= start_size);
tree->incr_memory_size(tree->extra_memory_size, end_size - start_size);
} }
return 0; return 0;
} }
static inline BOOL static inline bool
toku__rt_overlap(toku_range_tree* tree, toku_interval* a, toku_interval* b) { toku__rt_overlap(toku_range_tree* tree, toku_interval* a, toku_interval* b) {
assert(tree); assert(tree);
assert(a); assert(a);
assert(b); assert(b);
//a->left <= b->right && b->left <= a->right //a->left <= b->right && b->left <= a->right
return (BOOL)((tree->end_cmp(a->left, b->right) <= 0) && return ((tree->end_cmp(a->left, b->right) <= 0) &&
(tree->end_cmp(b->left, a->right) <= 0)); (tree->end_cmp(b->left, a->right) <= 0));
} }
static inline BOOL static inline bool
toku__rt_exact(toku_range_tree* tree, toku_range* a, toku_range* b) { toku__rt_exact(toku_range_tree* tree, toku_range* a, toku_range* b) {
assert(tree); assert(tree);
assert(a); assert(a);
assert(b); assert(b);
return (BOOL)((tree->end_cmp (a->ends.left, b->ends.left) == 0) && return ((tree->end_cmp (a->ends.left, b->ends.left) == 0) &&
(tree->end_cmp (a->ends.right, b->ends.right) == 0) && (tree->end_cmp (a->ends.right, b->ends.right) == 0) &&
(tree->data_cmp(a->data, b->data) == 0)); (tree->data_cmp(a->data, b->data) == 0));
} }
...@@ -109,32 +120,33 @@ int ...@@ -109,32 +120,33 @@ int
toku_rt_create(toku_range_tree** ptree, toku_rt_create(toku_range_tree** ptree,
int (*end_cmp)(const toku_point*,const toku_point*), int (*end_cmp)(const toku_point*,const toku_point*),
int (*data_cmp)(const TXNID,const TXNID), int (*data_cmp)(const TXNID,const TXNID),
BOOL allow_overlaps, bool allow_overlaps,
void* (*user_malloc) (size_t), void (*incr_memory_size)(void *extra_memory_size, size_t s),
void (*user_free) (void*), void (*decr_memory_size)(void *extra_memory_size, size_t s),
void* (*user_realloc)(void*, size_t)) { void *extra_memory_size) {
int r; int r;
toku_range_tree* tmptree; toku_range_tree* tmptree;
if (!ptree) if (!ptree)
return EINVAL; return EINVAL;
r = toku_rt_super_create(ptree, &tmptree, end_cmp, data_cmp, allow_overlaps, r = toku_rt_super_create(ptree, &tmptree, end_cmp, data_cmp, allow_overlaps, incr_memory_size, decr_memory_size, extra_memory_size);
user_malloc, user_free, user_realloc);
if (0) { if (0) {
died1: died1:
user_free(tmptree); toku_free(tmptree);
return r; return r;
} }
if (r != 0) if (r != 0)
return r; return r;
//Any local initializers go here. //Any local initializers go here.
tmptree->i.numelements = 0;
tmptree->i.ranges_len = minlen; tmptree->i.ranges_len = minlen;
tmptree->i.ranges = (toku_range*) tmptree->i.ranges = (toku_range*) toku_malloc(tmptree->i.ranges_len * sizeof(toku_range));
user_malloc(tmptree->i.ranges_len * sizeof(toku_range));
if (!tmptree->i.ranges) { if (!tmptree->i.ranges) {
r = errno; goto died1; r = errno; goto died1;
} }
tmptree->incr_memory_size(tmptree->extra_memory_size, toku_rt_memory_size(tmptree));
*ptree = tmptree; *ptree = tmptree;
...@@ -145,15 +157,16 @@ void ...@@ -145,15 +157,16 @@ void
toku_rt_clear(toku_range_tree* tree) { toku_rt_clear(toku_range_tree* tree) {
assert(tree); assert(tree);
toku__rt_decrease_capacity(tree, 0); toku__rt_decrease_capacity(tree, 0);
tree->numelements = 0; tree->i.numelements = 0;
} }
int int
toku_rt_close(toku_range_tree* tree) { toku_rt_close(toku_range_tree* tree) {
if (!tree) if (!tree)
return EINVAL; return EINVAL;
tree->free(tree->i.ranges); tree->decr_memory_size(tree->extra_memory_size, toku_rt_memory_size(tree));
tree->free(tree); toku_free(tree->i.ranges);
toku_free(tree);
return 0; return 0;
} }
...@@ -166,7 +179,7 @@ toku_rt_find(toku_range_tree* tree, toku_interval* query, u_int32_t k, ...@@ -166,7 +179,7 @@ toku_rt_find(toku_range_tree* tree, toku_interval* query, u_int32_t k,
return EINVAL; return EINVAL;
u_int32_t temp_numfound = 0; u_int32_t temp_numfound = 0;
for (u_int32_t i = 0; i < tree->numelements; i++) { for (u_int32_t i = 0; i < tree->i.numelements; i++) {
if (toku__rt_overlap(tree, query, &tree->i.ranges[i].ends)) { if (toku__rt_overlap(tree, query, &tree->i.ranges[i].ends)) {
r = toku__rt_increase_buffer(tree, buf, buflen, temp_numfound + 1); r = toku__rt_increase_buffer(tree, buf, buflen, temp_numfound + 1);
if (r != 0) if (r != 0)
...@@ -191,27 +204,27 @@ toku_rt_insert(toku_range_tree* tree, toku_range* range) { ...@@ -191,27 +204,27 @@ toku_rt_insert(toku_range_tree* tree, toku_range* range) {
//EDOM cases //EDOM cases
u_int32_t i; u_int32_t i;
if (tree->allow_overlaps) { if (tree->allow_overlaps) {
for (i = 0; i < tree->numelements; i++) { for (i = 0; i < tree->i.numelements; i++) {
if (toku__rt_exact (tree, range, &tree->i.ranges[i])) if (toku__rt_exact (tree, range, &tree->i.ranges[i]))
return EDOM; return EDOM;
} }
} else { } else {
for (i = 0; i < tree->numelements; i++) { for (i = 0; i < tree->i.numelements; i++) {
if (toku__rt_overlap(tree, &range->ends, &tree->i.ranges[i].ends)) if (toku__rt_overlap(tree, &range->ends, &tree->i.ranges[i].ends))
return EDOM; return EDOM;
} }
} }
for (i = 0; i < tree->numelements; i++) { for (i = 0; i < tree->i.numelements; i++) {
if (toku__rt_cmp(tree, range, &tree->i.ranges[i]) < 0) if (toku__rt_cmp(tree, range, &tree->i.ranges[i]) < 0)
break; break;
} }
/* Goes in slot 'i' */ /* Goes in slot 'i' */
r = toku__rt_increase_capacity(tree, tree->numelements + 1); r = toku__rt_increase_capacity(tree, tree->i.numelements + 1);
if (r != 0) if (r != 0)
return r; return r;
tree->numelements++; tree->i.numelements++;
/* Shift to make room. */ /* Shift to make room. */
for (u_int32_t move = tree->numelements - 1; move > i; move--) { for (u_int32_t move = tree->i.numelements - 1; move > i; move--) {
tree->i.ranges[move] = tree->i.ranges[move - 1]; tree->i.ranges[move] = tree->i.ranges[move - 1];
} }
tree->i.ranges[i] = *range; tree->i.ranges[i] = *range;
...@@ -223,72 +236,69 @@ toku_rt_delete(toku_range_tree* tree, toku_range* range) { ...@@ -223,72 +236,69 @@ toku_rt_delete(toku_range_tree* tree, toku_range* range) {
if (!tree || !range) if (!tree || !range)
return EINVAL; return EINVAL;
u_int32_t i; u_int32_t i;
for (i = 0; i < tree->numelements && for (i = 0; i < tree->i.numelements &&
!toku__rt_exact(tree, range, &(tree->i.ranges[i])); i++) { !toku__rt_exact(tree, range, &(tree->i.ranges[i])); i++) {
} }
//EDOM case: Not Found //EDOM case: Not Found
if (i == tree->numelements) if (i == tree->i.numelements)
return EDOM; return EDOM;
/* Shift left. */ /* Shift left. */
for (u_int32_t move = i; move < tree->numelements - 1; move++) { for (u_int32_t move = i; move < tree->i.numelements - 1; move++) {
tree->i.ranges[move] = tree->i.ranges[move + 1]; tree->i.ranges[move] = tree->i.ranges[move + 1];
} }
toku__rt_decrease_capacity(tree, --tree->numelements); toku__rt_decrease_capacity(tree, --tree->i.numelements);
return 0; return 0;
} }
int int
toku_rt_predecessor (toku_range_tree* tree, toku_point* point, toku_range* pred, BOOL* wasfound) { toku_rt_predecessor (toku_range_tree* tree, toku_point* point, toku_range* pred, bool* wasfound) {
if (!tree || !point || !pred || !wasfound) if (!tree || !point || !pred || !wasfound)
return EINVAL; return EINVAL;
if (tree->allow_overlaps) if (tree->allow_overlaps)
return EINVAL; return EINVAL;
toku_range* best = NULL; toku_range* best = NULL;
for (u_int32_t i = 0; i < tree->numelements; i++) { for (u_int32_t i = 0; i < tree->i.numelements; i++) {
if (toku__rt_p_cmp(tree, point, &tree->i.ranges[i].ends) > 0 && if (toku__rt_p_cmp(tree, point, &tree->i.ranges[i].ends) > 0 &&
(!best || tree->end_cmp(best->ends.left, tree->i.ranges[i].ends.left) < 0)) { (!best || tree->end_cmp(best->ends.left, tree->i.ranges[i].ends.left) < 0)) {
best = &tree->i.ranges[i]; best = &tree->i.ranges[i];
} }
} }
*wasfound = (BOOL)(best != NULL); *wasfound = (best != NULL);
if (best) if (best)
*pred = *best; *pred = *best;
return 0; return 0;
} }
int int
toku_rt_successor (toku_range_tree* tree, toku_point* point, toku_range* succ, BOOL* wasfound) { toku_rt_successor (toku_range_tree* tree, toku_point* point, toku_range* succ, bool* wasfound) {
if (!tree || !point || !succ || !wasfound) if (!tree || !point || !succ || !wasfound)
return EINVAL; return EINVAL;
if (tree->allow_overlaps) if (tree->allow_overlaps)
return EINVAL; return EINVAL;
toku_range* best = NULL; toku_range* best = NULL;
for (u_int32_t i = 0; i < tree->numelements; i++) { for (u_int32_t i = 0; i < tree->i.numelements; i++) {
if (toku__rt_p_cmp(tree, point, &tree->i.ranges[i].ends) < 0 && if (toku__rt_p_cmp(tree, point, &tree->i.ranges[i].ends) < 0 &&
(!best || tree->end_cmp(best->ends.left, tree->i.ranges[i].ends.left) > 0)) { (!best || tree->end_cmp(best->ends.left, tree->i.ranges[i].ends.left) > 0)) {
best = &tree->i.ranges[i]; best = &tree->i.ranges[i];
} }
} }
*wasfound = (BOOL)(best != NULL); *wasfound = (best != NULL);
if (best) if (best)
*succ = *best; *succ = *best;
return 0; return 0;
} }
int int
toku_rt_get_allow_overlaps(toku_range_tree* tree, BOOL* allowed) { toku_rt_get_allow_overlaps(toku_range_tree* tree, bool* allowed) {
if (!tree || !allowed) if (!tree || !allowed)
return EINVAL; return EINVAL;
*allowed = tree->allow_overlaps; *allowed = tree->allow_overlaps;
return 0; return 0;
} }
int size_t
toku_rt_get_size(toku_range_tree* tree, u_int32_t* size) { toku_rt_get_size(toku_range_tree* tree) {
if (!tree || !size) return tree->i.numelements;
return EINVAL;
*size = tree->numelements;
return 0;
} }
int int
...@@ -296,7 +306,7 @@ toku_rt_iterate(toku_range_tree* tree, int (*f)(toku_range*,void*), void* extra) ...@@ -296,7 +306,7 @@ toku_rt_iterate(toku_range_tree* tree, int (*f)(toku_range*,void*), void* extra)
u_int32_t index; u_int32_t index;
int r = ENOSYS; int r = ENOSYS;
for (index = 0; index < tree->numelements; index++) { for (index = 0; index < tree->i.numelements; index++) {
if ((r = f(&tree->i.ranges[index], extra))) if ((r = f(&tree->i.ranges[index], extra)))
goto cleanup; goto cleanup;
} }
...@@ -308,16 +318,21 @@ cleanup: ...@@ -308,16 +318,21 @@ cleanup:
void void
toku_rt_verify(toku_range_tree *tree) { toku_rt_verify(toku_range_tree *tree) {
if (!tree->allow_overlaps) { if (!tree->allow_overlaps) {
for (u_int32_t i = 0; i < tree->numelements; i++) { for (u_int32_t i = 0; i < tree->i.numelements; i++) {
// assert left <= right // assert left <= right
assert(tree->end_cmp(tree->i.ranges[i].ends.left, tree->i.ranges[i].ends.right) <= 0); assert(tree->end_cmp(tree->i.ranges[i].ends.left, tree->i.ranges[i].ends.right) <= 0);
// assert ranges are sorted // assert ranges are sorted
if (i < tree->numelements-1) if (i < tree->i.numelements-1)
assert(tree->end_cmp(tree->i.ranges[i].ends.right, tree->i.ranges[i+1].ends.left) < 0); assert(tree->end_cmp(tree->i.ranges[i].ends.right, tree->i.ranges[i+1].ends.left) < 0);
} }
// verify no overlaps // verify no overlaps
for (u_int32_t i = 1; i < tree->numelements; i++) { for (u_int32_t i = 1; i < tree->i.numelements; i++) {
assert(!toku__rt_overlap(tree, &tree->i.ranges[i-1].ends, &tree->i.ranges[i].ends)); assert(!toku__rt_overlap(tree, &tree->i.ranges[i-1].ends, &tree->i.ranges[i].ends));
} }
} }
} }
size_t
toku_rt_memory_size(toku_range_tree *tree) {
return sizeof (toku_range_tree) + toku_malloc_usable_size(tree->i.ranges);
}
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
//Currently this is a stub implementation just so we can write and compile tests //Currently this is a stub implementation just so we can write and compile tests
//before actually implementing the range tree. //before actually implementing the range tree.
#include "memory.h"
#include <rangetree.h> #include <rangetree.h>
#include <errno.h> #include <errno.h>
#include <toku_assert.h> #include <toku_assert.h>
...@@ -31,39 +32,42 @@ int ...@@ -31,39 +32,42 @@ int
toku_rt_create(toku_range_tree** ptree, toku_rt_create(toku_range_tree** ptree,
int (*end_cmp)(const toku_point*,const toku_point*), int (*end_cmp)(const toku_point*,const toku_point*),
int (*data_cmp)(const TXNID,const TXNID), int (*data_cmp)(const TXNID,const TXNID),
BOOL allow_overlaps, bool allow_overlaps,
void* (*user_malloc) (size_t), void (*incr_memory_size)(void *extra_memory_size, size_t s),
void (*user_free) (void*), void (*decr_memory_size)(void *extra_memory_size, size_t s),
void* (*user_realloc)(void*, size_t)) { void *extra_memory_size) {
int r = ENOSYS; int r = ENOSYS;
toku_range_tree* temptree = NULL; toku_range_tree* tmptree = NULL;
if (allow_overlaps) if (allow_overlaps)
return EINVAL; return EINVAL;
r = toku_rt_super_create(ptree, &temptree, end_cmp, data_cmp, allow_overlaps, r = toku_rt_super_create(ptree, &tmptree, end_cmp, data_cmp, allow_overlaps, incr_memory_size, decr_memory_size, extra_memory_size);
user_malloc, user_free, user_realloc);
if (r != 0) if (r != 0)
goto cleanup; goto cleanup;
//Any local initializers go here. //Any local initializers go here.
r = toku_omt_create(&temptree->i.omt); r = toku_omt_create(&tmptree->i.omt);
if (r != 0) if (r != 0)
goto cleanup; goto cleanup;
*ptree = temptree; tmptree->incr_memory_size(tmptree->extra_memory_size, toku_rt_memory_size(tmptree));
*ptree = tmptree;
r = 0; r = 0;
cleanup: cleanup:
if (r != 0) { if (r != 0) {
if (temptree) if (tmptree)
user_free(temptree); toku_free(tmptree);
} }
return r; return r;
} }
static int static int
rt_clear_helper(OMTVALUE value, u_int32_t UU(index), void* extra) { rt_clear_helper(OMTVALUE value, u_int32_t UU(index), void* extra) {
void (*user_free)(void*) = (void(*)(void*))extra; toku_range_tree *tree = (toku_range_tree *) extra;
user_free(value); size_t s = toku_malloc_usable_size(value);
tree->decr_memory_size(tree->extra_memory_size, s);
toku_free(value);
return 0; return 0;
} }
...@@ -71,20 +75,24 @@ int ...@@ -71,20 +75,24 @@ int
toku_rt_close(toku_range_tree* tree) { toku_rt_close(toku_range_tree* tree) {
if (!tree) if (!tree)
return EINVAL; return EINVAL;
int r = toku_omt_iterate(tree->i.omt, rt_clear_helper, tree->free); int r = toku_omt_iterate(tree->i.omt, rt_clear_helper, tree);
assert_zero(r); assert_zero(r);
tree->decr_memory_size(tree->extra_memory_size, toku_rt_memory_size(tree));
toku_omt_destroy(&tree->i.omt); toku_omt_destroy(&tree->i.omt);
tree->free(tree); toku_free(tree);
return 0; return 0;
} }
void void
toku_rt_clear(toku_range_tree* tree) { toku_rt_clear(toku_range_tree* tree) {
assert(tree); assert(tree);
int r = toku_omt_iterate(tree->i.omt, rt_clear_helper, tree->free); int r = toku_omt_iterate(tree->i.omt, rt_clear_helper, tree);
assert_zero(r); assert_zero(r);
size_t start_size = toku_omt_memory_size(tree->i.omt);;
toku_omt_clear(tree->i.omt); toku_omt_clear(tree->i.omt);
tree->numelements = 0; size_t end_size = toku_omt_memory_size(tree->i.omt);
assert(start_size >= end_size);
tree->decr_memory_size(tree->extra_memory_size, start_size - end_size);
} }
typedef struct { typedef struct {
...@@ -204,17 +212,24 @@ toku_rt_insert(toku_range_tree* tree, toku_range* range) { ...@@ -204,17 +212,24 @@ toku_rt_insert(toku_range_tree* tree, toku_range* range) {
r = EDOM; goto cleanup; r = EDOM; goto cleanup;
} }
assert(r == DB_NOTFOUND); assert(r == DB_NOTFOUND);
insert_range = tree->malloc(sizeof(*insert_range)); insert_range = toku_xmalloc(sizeof *insert_range);
*insert_range = *range; *insert_range = *range;
size_t start_omt_size = toku_omt_memory_size(tree->i.omt);
static int count = 0;
count++;
r = toku_omt_insert_at(tree->i.omt, insert_range, index); r = toku_omt_insert_at(tree->i.omt, insert_range, index);
assert_zero(r); assert_zero(r);
size_t end_omt_size = toku_omt_memory_size(tree->i.omt);
tree->numelements++; if (end_omt_size >= start_omt_size)
tree->incr_memory_size(tree->extra_memory_size, end_omt_size - start_omt_size);
else
tree->decr_memory_size(tree->extra_memory_size, start_omt_size - end_omt_size);
tree->incr_memory_size(tree->extra_memory_size, toku_malloc_usable_size(insert_range));
r = 0; r = 0;
cleanup: cleanup:
if (r != 0) { if (r != 0) {
if (insert_range) if (insert_range)
tree->free(insert_range); toku_free(insert_range);
} }
return r; return r;
} }
...@@ -245,11 +260,16 @@ toku_rt_delete(toku_range_tree* tree, toku_range* range) { ...@@ -245,11 +260,16 @@ toku_rt_delete(toku_range_tree* tree, toku_range* range) {
r = EDOM; r = EDOM;
goto cleanup; goto cleanup;
} }
size_t start_omt_size = toku_omt_memory_size(tree->i.omt);
r = toku_omt_delete_at(tree->i.omt, index); r = toku_omt_delete_at(tree->i.omt, index);
assert_zero(r); assert_zero(r);
size_t end_omt_size = toku_omt_memory_size(tree->i.omt);
tree->free(data); if (start_omt_size >= end_omt_size)
tree->numelements--; tree->decr_memory_size(tree->extra_memory_size, start_omt_size - end_omt_size);
else
tree->incr_memory_size(tree->extra_memory_size, end_omt_size - start_omt_size);
tree->decr_memory_size(tree->extra_memory_size, toku_malloc_usable_size(data));
toku_free(data);
r = 0; r = 0;
cleanup: cleanup:
return r; return r;
...@@ -257,7 +277,7 @@ cleanup: ...@@ -257,7 +277,7 @@ cleanup:
static inline int static inline int
rt_neightbor(toku_range_tree* tree, toku_point* point, rt_neightbor(toku_range_tree* tree, toku_point* point,
toku_range* neighbor, BOOL* wasfound, int direction) { toku_range* neighbor, bool* wasfound, int direction) {
int r = ENOSYS; int r = ENOSYS;
if (!tree || !point || !neighbor || !wasfound || tree->allow_overlaps) { if (!tree || !point || !neighbor || !wasfound || tree->allow_overlaps) {
r = EINVAL; goto cleanup; r = EINVAL; goto cleanup;
...@@ -272,14 +292,14 @@ rt_neightbor(toku_range_tree* tree, toku_point* point, ...@@ -272,14 +292,14 @@ rt_neightbor(toku_range_tree* tree, toku_point* point,
assert(direction==1 || direction==-1); assert(direction==1 || direction==-1);
r = toku_omt_find(tree->i.omt, rt_heaviside, &extra, direction, &value, &index); r = toku_omt_find(tree->i.omt, rt_heaviside, &extra, direction, &value, &index);
if (r == DB_NOTFOUND) { if (r == DB_NOTFOUND) {
*wasfound = FALSE; *wasfound = false;
r = 0; r = 0;
goto cleanup; goto cleanup;
} }
assert_zero(r); assert_zero(r);
assert(value); assert(value);
toku_range* data = value; toku_range* data = value;
*wasfound = TRUE; *wasfound = true;
*neighbor = *data; *neighbor = *data;
r = 0; r = 0;
cleanup: cleanup:
...@@ -287,17 +307,17 @@ cleanup: ...@@ -287,17 +307,17 @@ cleanup:
} }
int int
toku_rt_predecessor (toku_range_tree* tree, toku_point* point, toku_range* pred, BOOL* wasfound) { toku_rt_predecessor (toku_range_tree* tree, toku_point* point, toku_range* pred, bool* wasfound) {
return rt_neightbor(tree, point, pred, wasfound, -1); return rt_neightbor(tree, point, pred, wasfound, -1);
} }
int int
toku_rt_successor (toku_range_tree* tree, toku_point* point, toku_range* succ, BOOL* wasfound) { toku_rt_successor (toku_range_tree* tree, toku_point* point, toku_range* succ, bool* wasfound) {
return rt_neightbor(tree, point, succ, wasfound, 1); return rt_neightbor(tree, point, succ, wasfound, 1);
} }
int int
toku_rt_get_allow_overlaps(toku_range_tree* tree, BOOL* allowed) { toku_rt_get_allow_overlaps(toku_range_tree* tree, bool* allowed) {
if (!tree || !allowed) if (!tree || !allowed)
return EINVAL; return EINVAL;
assert(!tree->allow_overlaps); assert(!tree->allow_overlaps);
...@@ -305,12 +325,9 @@ toku_rt_get_allow_overlaps(toku_range_tree* tree, BOOL* allowed) { ...@@ -305,12 +325,9 @@ toku_rt_get_allow_overlaps(toku_range_tree* tree, BOOL* allowed) {
return 0; return 0;
} }
int size_t
toku_rt_get_size(toku_range_tree* tree, u_int32_t* size) { toku_rt_get_size(toku_range_tree* tree) {
if (!tree || !size) return toku_omt_size(tree->i.omt);
return EINVAL;
*size = tree->numelements;
return 0;
} }
typedef struct { typedef struct {
...@@ -332,13 +349,13 @@ toku_rt_iterate(toku_range_tree* tree, int (*f)(toku_range*,void*), void* extra) ...@@ -332,13 +349,13 @@ toku_rt_iterate(toku_range_tree* tree, int (*f)(toku_range*,void*), void* extra)
return toku_omt_iterate(tree->i.omt, rt_iterate_helper, &info); return toku_omt_iterate(tree->i.omt, rt_iterate_helper, &info);
} }
static inline BOOL static inline bool
toku__rt_overlap(toku_range_tree* tree, toku_interval* a, toku_interval* b) { toku__rt_overlap(toku_range_tree* tree, toku_interval* a, toku_interval* b) {
assert(tree); assert(tree);
assert(a); assert(a);
assert(b); assert(b);
//a->left <= b->right && b->left <= a->right //a->left <= b->right && b->left <= a->right
return (BOOL)((tree->end_cmp(a->left, b->right) <= 0) && return ((tree->end_cmp(a->left, b->right) <= 0) &&
(tree->end_cmp(b->left, a->right) <= 0)); (tree->end_cmp(b->left, a->right) <= 0));
} }
...@@ -346,7 +363,8 @@ void ...@@ -346,7 +363,8 @@ void
toku_rt_verify(toku_range_tree *tree) { toku_rt_verify(toku_range_tree *tree) {
int r; int r;
if (!tree->allow_overlaps) { if (!tree->allow_overlaps) {
for (u_int32_t i = 0; i < tree->numelements; i++) { u_int32_t numelements = toku_omt_size(tree->i.omt);
for (u_int32_t i = 0; i < numelements; i++) {
// assert left <= right // assert left <= right
OMTVALUE omtv; OMTVALUE omtv;
r = toku_omt_fetch(tree->i.omt, i, &omtv); r = toku_omt_fetch(tree->i.omt, i, &omtv);
...@@ -354,7 +372,7 @@ toku_rt_verify(toku_range_tree *tree) { ...@@ -354,7 +372,7 @@ toku_rt_verify(toku_range_tree *tree) {
toku_range *v = (toku_range *) omtv; toku_range *v = (toku_range *) omtv;
assert(tree->end_cmp(v->ends.left, v->ends.right) <= 0); assert(tree->end_cmp(v->ends.left, v->ends.right) <= 0);
// assert ranges are sorted // assert ranges are sorted
if (i < tree->numelements-1) { if (i < numelements-1) {
OMTVALUE omtvnext; OMTVALUE omtvnext;
r = toku_omt_fetch(tree->i.omt, i+1, &omtvnext); r = toku_omt_fetch(tree->i.omt, i+1, &omtvnext);
assert_zero(r); assert_zero(r);
...@@ -363,7 +381,7 @@ toku_rt_verify(toku_range_tree *tree) { ...@@ -363,7 +381,7 @@ toku_rt_verify(toku_range_tree *tree) {
} }
} }
// verify no overlaps // verify no overlaps
for (u_int32_t i = 1; i < tree->numelements; i++) { for (u_int32_t i = 1; i < numelements; i++) {
OMTVALUE omtvprev; OMTVALUE omtvprev;
r = toku_omt_fetch(tree->i.omt, i-1, &omtvprev); r = toku_omt_fetch(tree->i.omt, i-1, &omtvprev);
assert_zero(r); assert_zero(r);
...@@ -376,3 +394,8 @@ toku_rt_verify(toku_range_tree *tree) { ...@@ -376,3 +394,8 @@ toku_rt_verify(toku_range_tree *tree) {
} }
} }
} }
size_t
toku_rt_memory_size(toku_range_tree *tree) {
return sizeof (toku_range_tree) + toku_omt_memory_size(tree->i.omt);
}
...@@ -25,17 +25,12 @@ struct __toku_range_tree { ...@@ -25,17 +25,12 @@ struct __toku_range_tree {
with a range */ with a range */
int (*data_cmp)(const TXNID,const TXNID); int (*data_cmp)(const TXNID,const TXNID);
/** Whether this tree allows ranges to overlap */ /** Whether this tree allows ranges to overlap */
BOOL allow_overlaps; bool allow_overlaps;
/** The number of ranges in the range tree */
u_int32_t numelements;
/** The user malloc function */
void* (*malloc) (size_t);
/** The user free function */
void (*free) (void*);
/** The user realloc function */
void* (*realloc)(void*, size_t);
toku_range_tree_local i; toku_range_tree_local i;
void (*incr_memory_size)(void *extra_memory_size, size_t s);
void (*decr_memory_size)(void *extra_memory_size, size_t s);
void *extra_memory_size;
}; };
/* /*
...@@ -53,7 +48,7 @@ static inline int toku__rt_p_cmp(toku_range_tree* tree, ...@@ -53,7 +48,7 @@ static inline int toku__rt_p_cmp(toku_range_tree* tree,
return 0; return 0;
} }
static inline int toku__rt_increase_buffer(toku_range_tree* tree, toku_range** buf, static inline int toku__rt_increase_buffer(toku_range_tree* tree UU(), toku_range** buf,
u_int32_t* buflen, u_int32_t num) { u_int32_t* buflen, u_int32_t num) {
assert(buf); assert(buf);
//TODO: SOME ATTRIBUTE TO REMOVE NEVER EXECUTABLE ERROR: assert(buflen); //TODO: SOME ATTRIBUTE TO REMOVE NEVER EXECUTABLE ERROR: assert(buflen);
...@@ -63,7 +58,7 @@ static inline int toku__rt_increase_buffer(toku_range_tree* tree, toku_range** b ...@@ -63,7 +58,7 @@ static inline int toku__rt_increase_buffer(toku_range_tree* tree, toku_range** b
temp_len = 1; temp_len = 1;
while (temp_len < num) while (temp_len < num)
temp_len *= 2; temp_len *= 2;
toku_range* temp_buf = tree->realloc(*buf, temp_len * sizeof(toku_range)); toku_range* temp_buf = toku_realloc(*buf, temp_len * sizeof(toku_range));
if (!temp_buf) if (!temp_buf)
return errno; return errno;
*buf = temp_buf; *buf = temp_buf;
...@@ -72,31 +67,31 @@ static inline int toku__rt_increase_buffer(toku_range_tree* tree, toku_range** b ...@@ -72,31 +67,31 @@ static inline int toku__rt_increase_buffer(toku_range_tree* tree, toku_range** b
return 0; return 0;
} }
static inline int toku_rt_super_create(toku_range_tree** upperptree, static inline int
toku_rt_super_create(toku_range_tree** upperptree,
toku_range_tree** ptree, toku_range_tree** ptree,
int (*end_cmp)(const toku_point*,const toku_point*), int (*end_cmp)(const toku_point*,const toku_point*),
int (*data_cmp)(const TXNID,const TXNID), int (*data_cmp)(const TXNID,const TXNID),
BOOL allow_overlaps, bool allow_overlaps,
void* (*user_malloc) (size_t), void (*incr_memory_size)(void *extra_memory_size, size_t s),
void (*user_free) (void*), void (*decr_memory_size)(void *extra_memory_size, size_t s),
void* (*user_realloc)(void*, size_t)) { void *extra_memory_size) {
toku_range_tree* temptree; toku_range_tree* temptree;
if (!upperptree || !ptree || !end_cmp || !data_cmp || if (!upperptree || !ptree || !end_cmp || !data_cmp)
!user_malloc || !user_free || !user_realloc)
return EINVAL; return EINVAL;
temptree = (toku_range_tree*)user_malloc(sizeof(toku_range_tree)); temptree = (toku_range_tree*) toku_malloc(sizeof(toku_range_tree));
if (!temptree) if (!temptree)
return ENOMEM; return ENOMEM;
//Any initializers go here. //Any initializers go here.
memset(temptree, 0, sizeof(*temptree));
temptree->end_cmp = end_cmp; temptree->end_cmp = end_cmp;
temptree->data_cmp = data_cmp; temptree->data_cmp = data_cmp;
temptree->allow_overlaps = allow_overlaps; temptree->allow_overlaps = allow_overlaps;
temptree->malloc = user_malloc; temptree->incr_memory_size = incr_memory_size;
temptree->free = user_free; temptree->decr_memory_size = decr_memory_size;
temptree->realloc = user_realloc; temptree->extra_memory_size = extra_memory_size;
*ptree = temptree; *ptree = temptree;
return 0; return 0;
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
MIT Press and McGraw-Hill, 2001. ISBN 0-262-03293-7 MIT Press and McGraw-Hill, 2001. ISBN 0-262-03293-7
*/ */
//Defines BOOL data type.
#include <toku_portability.h> #include <toku_portability.h>
#include <brttypes.h> #include <brttypes.h>
#include <db.h> #include <db.h>
...@@ -67,7 +66,7 @@ struct __toku_range_tree; ...@@ -67,7 +66,7 @@ struct __toku_range_tree;
\return \return
- 0: Success. - 0: Success.
- EINVAL: If any pointer argument is NULL. */ - EINVAL: If any pointer argument is NULL. */
int toku_rt_get_allow_overlaps(toku_range_tree* tree, BOOL* allowed); int toku_rt_get_allow_overlaps(toku_range_tree* tree, bool* allowed);
/** /**
Creates a range tree. Creates a range tree.
...@@ -87,16 +86,16 @@ int toku_rt_get_allow_overlaps(toku_range_tree* tree, BOOL* allowed); ...@@ -87,16 +86,16 @@ int toku_rt_get_allow_overlaps(toku_range_tree* tree, BOOL* allowed);
\return \return
- 0: Success. - 0: Success.
- EINVAL: If any pointer argument is NULL. - EINVAL: If any pointer argument is NULL.
- EINVAL: If allow_overlaps = TRUE and the implementation does - EINVAL: If allow_overlaps = true and the implementation does
not support overlaps. not support overlaps.
- Other exit codes may be forwarded from underlying system calls. */ - Other exit codes may be forwarded from underlying system calls. */
int toku_rt_create(toku_range_tree** ptree, int toku_rt_create(toku_range_tree** ptree,
int (*end_cmp)(const toku_point*,const toku_point*), int (*end_cmp)(const toku_point*,const toku_point*),
int (*data_cmp)(const TXNID,const TXNID), int (*data_cmp)(const TXNID,const TXNID),
BOOL allow_overlaps, bool allow_overlaps,
void* (*user_malloc) (size_t), void (*incr_memory_size)(void *extra_memory_size, size_t s),
void (*user_free) (void*), void (*decr_memory_size)(void *extra_memory_size, size_t s),
void* (*user_realloc)(void*, size_t)); void *extra_memory_size);
/** /**
Destroys and frees a range tree. Destroys and frees a range tree.
...@@ -164,7 +163,7 @@ int toku_rt_find(toku_range_tree* tree,toku_interval* query, u_int32_t k, ...@@ -164,7 +163,7 @@ int toku_rt_find(toku_range_tree* tree,toku_interval* query, u_int32_t k,
- EDOM: If an equivalent range (left, right, and data according to - EDOM: If an equivalent range (left, right, and data according to
end_cmp and data_cmp) already exists in the tree. end_cmp and data_cmp) already exists in the tree.
If an overlapping range exists in the tree and If an overlapping range exists in the tree and
allow_overlaps == FALSE. allow_overlaps == false.
- Other exit codes may be forwarded from underlying system calls. - Other exit codes may be forwarded from underlying system calls.
*/ */
int toku_rt_insert(toku_range_tree* tree, toku_range* range); int toku_rt_insert(toku_range_tree* tree, toku_range* range);
...@@ -186,7 +185,7 @@ int toku_rt_delete(toku_range_tree* tree, toku_range* range); ...@@ -186,7 +185,7 @@ int toku_rt_delete(toku_range_tree* tree, toku_range* range);
/** /**
Finds the strict predecessor range of a point i.e. the rightmost range Finds the strict predecessor range of a point i.e. the rightmost range
completely to the left of the query point according to end_cmp. completely to the left of the query point according to end_cmp.
This operation is only defined if allow_overlaps == FALSE. This operation is only defined if allow_overlaps == false.
\param tree The range tree to search in. \param tree The range tree to search in.
\param point The point to query. Must be a valid argument to \param point The point to query. Must be a valid argument to
...@@ -203,12 +202,12 @@ int toku_rt_delete(toku_range_tree* tree, toku_range* range); ...@@ -203,12 +202,12 @@ int toku_rt_delete(toku_range_tree* tree, toku_range* range);
- Other exit codes may be forwarded from underlying system calls. - Other exit codes may be forwarded from underlying system calls.
*/ */
int toku_rt_predecessor(toku_range_tree* tree, toku_point* point, int toku_rt_predecessor(toku_range_tree* tree, toku_point* point,
toku_range* pred, BOOL* wasfound); toku_range* pred, bool* wasfound);
/** /**
Finds the strict successor range of a point i.e. the leftmost range Finds the strict successor range of a point i.e. the leftmost range
completely to the right of the query point according to end_cmp. completely to the right of the query point according to end_cmp.
This operation is only defined if allow_overlaps == FALSE. This operation is only defined if allow_overlaps == false.
\param tree The range tree to search in. \param tree The range tree to search in.
\param point The point to query. Must be a valid argument to \param point The point to query. Must be a valid argument to
...@@ -225,24 +224,21 @@ int toku_rt_predecessor(toku_range_tree* tree, toku_point* point, ...@@ -225,24 +224,21 @@ int toku_rt_predecessor(toku_range_tree* tree, toku_point* point,
- Other exit codes may be forwarded from underlying system calls. - Other exit codes may be forwarded from underlying system calls.
*/ */
int toku_rt_successor(toku_range_tree* tree, toku_point* point, int toku_rt_successor(toku_range_tree* tree, toku_point* point,
toku_range* succ, BOOL* wasfound); toku_range* succ, bool* wasfound);
/** /**
Finds the number of elements in the range tree. Finds the number of elements in the range tree.
\param tree The range tree. \param tree The range tree.
\param size A buffer to return the the number of elements \return The number of ranges in the range tree
in the range tree.
\return
- 0: Success.
- EINVAL: If any pointer argument is NULL.
*/ */
int toku_rt_get_size(toku_range_tree* tree, u_int32_t* size); size_t toku_rt_get_size(toku_range_tree* tree);
int toku_rt_iterate(toku_range_tree* tree, int (*f)(toku_range*,void*), void* extra); int toku_rt_iterate(toku_range_tree* tree, int (*f)(toku_range*,void*), void* extra);
void toku_rt_verify(toku_range_tree *tree); void toku_rt_verify(toku_range_tree *tree);
size_t toku_rt_memory_size(toku_range_tree *tree);
#if defined(__cplusplus) #if defined(__cplusplus)
} }
#endif #endif
......
...@@ -20,10 +20,10 @@ init_range (toku_range* range, int left, int right, int data) { ...@@ -20,10 +20,10 @@ init_range (toku_range* range, int left, int right, int data) {
} }
static void static void
setup_tree (BOOL allow_overlaps, BOOL insert, int left, int right, int data) { setup_tree (bool allow_overlaps, BOOL insert, int left, int right, int data) {
int r; int r;
toku_range range; toku_range range;
r = toku_rt_create(&tree, int_cmp, char_cmp, allow_overlaps, toku_malloc, toku_free, toku_realloc); r = toku_rt_create(&tree, int_cmp, char_cmp, allow_overlaps, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR(r); CKERR(r);
if (insert) { if (insert) {
......
...@@ -100,3 +100,10 @@ verify_all_overlap (toku_interval* query, toku_range* list, unsigned listlen) { ...@@ -100,3 +100,10 @@ verify_all_overlap (toku_interval* query, toku_range* list, unsigned listlen) {
} }
} }
static inline void
test_incr_memory_size(void *extra UU(), size_t s UU()) {
}
static inline void
test_decr_memory_size(void *extra UU(), size_t s UU()) {
}
...@@ -2,17 +2,17 @@ ...@@ -2,17 +2,17 @@
#include "test.h" #include "test.h"
static void test_create_close(BOOL allow_overlaps) { static void test_create_close(bool allow_overlaps) {
int r; int r;
#ifdef TOKU_RT_NOOVERLAPS #ifdef TOKU_RT_NOOVERLAPS
if (allow_overlaps) return; if (allow_overlaps) return;
#endif #endif
toku_range_tree *tree = NULL; toku_range_tree *tree = NULL;
r = toku_rt_create(&tree, int_cmp, char_cmp, allow_overlaps, toku_malloc, toku_free, toku_realloc); r = toku_rt_create(&tree, int_cmp, char_cmp, allow_overlaps, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR(r); CKERR(r);
assert(tree!=NULL); assert(tree!=NULL);
BOOL temp; bool temp;
r = toku_rt_get_allow_overlaps(tree, &temp); r = toku_rt_get_allow_overlaps(tree, &temp);
CKERR(r); CKERR(r);
assert((temp != 0) == (allow_overlaps != 0)); assert((temp != 0) == (allow_overlaps != 0));
...@@ -22,23 +22,6 @@ static void test_create_close(BOOL allow_overlaps) { ...@@ -22,23 +22,6 @@ static void test_create_close(BOOL allow_overlaps) {
tree = NULL; tree = NULL;
} }
static void test_create_close_nomem(BOOL allow_overlaps) {
#ifdef TOKU_RT_NOOVERLAPS
if (allow_overlaps) return;
#endif
for (int i = 1; i <= 1; i++) {
mallocced = 0;
failon = i;
toku_range_tree *tree = NULL;
int r = toku_rt_create(&tree, int_cmp, char_cmp, allow_overlaps,
fail_malloc, toku_free, toku_realloc);
CKERR2(r, ENOMEM);
assert(tree==NULL);
}
}
int main(int argc, const char *argv[]) { int main(int argc, const char *argv[]) {
parse_args(argc, argv); parse_args(argc, argv);
...@@ -46,9 +29,6 @@ int main(int argc, const char *argv[]) { ...@@ -46,9 +29,6 @@ int main(int argc, const char *argv[]) {
test_create_close(false); test_create_close(false);
test_create_close(true); test_create_close(true);
test_create_close_nomem(false);
test_create_close_nomem(true);
return 0; return 0;
} }
...@@ -10,26 +10,16 @@ int main(int argc, const char *argv[]) { ...@@ -10,26 +10,16 @@ int main(int argc, const char *argv[]) {
parse_args(argc, argv); parse_args(argc, argv);
/* Create tests */ /* Create tests */
r = toku_rt_create(NULL, int_cmp, TXNID_cmp, FALSE, toku_malloc, toku_free, toku_realloc); r = toku_rt_create(NULL, int_cmp, TXNID_cmp, false, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR2(r, EINVAL); CKERR2(r, EINVAL);
r = toku_rt_create(&tree, NULL, TXNID_cmp, FALSE, toku_malloc, toku_free, toku_realloc); r = toku_rt_create(&tree, NULL, TXNID_cmp, false, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR2(r, EINVAL); CKERR2(r, EINVAL);
assert(tree == NULL); assert(tree == NULL);
r = toku_rt_create(&tree, int_cmp, NULL, FALSE, toku_malloc, toku_free, toku_realloc); r = toku_rt_create(&tree, int_cmp, NULL, false, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR2(r, EINVAL); CKERR2(r, EINVAL);
r = toku_rt_create(&tree, int_cmp, TXNID_cmp, FALSE, NULL, toku_free, toku_realloc);
CKERR2(r, EINVAL);
r = toku_rt_create(&tree, int_cmp, TXNID_cmp, FALSE, toku_malloc, NULL, toku_realloc);
CKERR2(r, EINVAL);
r = toku_rt_create(&tree, int_cmp, TXNID_cmp, FALSE, toku_malloc, toku_free, NULL);
CKERR2(r, EINVAL);
assert(tree == NULL);
/* Close tests */ /* Close tests */
r = toku_rt_close(NULL); r = toku_rt_close(NULL);
CKERR2(r, EINVAL); CKERR2(r, EINVAL);
...@@ -38,7 +28,7 @@ int main(int argc, const char *argv[]) { ...@@ -38,7 +28,7 @@ int main(int argc, const char *argv[]) {
r = toku_rt_insert(NULL, &range); r = toku_rt_insert(NULL, &range);
CKERR2(r, EINVAL); CKERR2(r, EINVAL);
r = toku_rt_create(&tree, int_cmp, TXNID_cmp, FALSE, toku_malloc, toku_free, toku_realloc); r = toku_rt_create(&tree, int_cmp, TXNID_cmp, false, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR(r); CKERR(r);
assert(tree != NULL); assert(tree != NULL);
...@@ -51,7 +41,7 @@ int main(int argc, const char *argv[]) { ...@@ -51,7 +41,7 @@ int main(int argc, const char *argv[]) {
r = toku_rt_delete(NULL, &range); r = toku_rt_delete(NULL, &range);
CKERR2(r, EINVAL); CKERR2(r, EINVAL);
r = toku_rt_create(&tree, int_cmp, TXNID_cmp, FALSE, toku_malloc, toku_free, toku_realloc); r = toku_rt_create(&tree, int_cmp, TXNID_cmp, false, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR(r); CKERR(r);
assert(tree != NULL); assert(tree != NULL);
...@@ -68,7 +58,7 @@ int main(int argc, const char *argv[]) { ...@@ -68,7 +58,7 @@ int main(int argc, const char *argv[]) {
range.ends.right = (toku_point*)&stuff[1]; range.ends.right = (toku_point*)&stuff[1];
range.data = 0; range.data = 0;
r = toku_rt_create(&tree, int_cmp, TXNID_cmp, FALSE, toku_malloc, toku_free, toku_realloc); r = toku_rt_create(&tree, int_cmp, TXNID_cmp, false, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR(r); CKERR(r);
assert(tree != NULL); assert(tree != NULL);
...@@ -99,8 +89,8 @@ int main(int argc, const char *argv[]) { ...@@ -99,8 +89,8 @@ int main(int argc, const char *argv[]) {
/* Predecessor tests */ /* Predecessor tests */
toku_point* foo = (toku_point*)&stuff[0]; toku_point* foo = (toku_point*)&stuff[0];
BOOL wasfound; bool wasfound;
r = toku_rt_create(&tree, int_cmp, TXNID_cmp, FALSE, toku_malloc, toku_free, toku_realloc); r = toku_rt_create(&tree, int_cmp, TXNID_cmp, false, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR(r); CKERR(r);
assert(tree != NULL); assert(tree != NULL);
...@@ -119,7 +109,7 @@ int main(int argc, const char *argv[]) { ...@@ -119,7 +109,7 @@ int main(int argc, const char *argv[]) {
r = toku_rt_close(tree); CKERR(r); r = toku_rt_close(tree); CKERR(r);
#ifndef TOKU_RT_NOOVERLAPS #ifndef TOKU_RT_NOOVERLAPS
r = toku_rt_create(&tree, int_cmp, TXNID_cmp, TRUE, toku_malloc, toku_free, toku_realloc); r = toku_rt_create(&tree, int_cmp, TXNID_cmp, true, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR(r); CKERR(r);
assert(tree != NULL); assert(tree != NULL);
...@@ -133,7 +123,7 @@ int main(int argc, const char *argv[]) { ...@@ -133,7 +123,7 @@ int main(int argc, const char *argv[]) {
/* Successor tests */ /* Successor tests */
r = toku_rt_create(&tree, int_cmp, TXNID_cmp, FALSE, toku_malloc, toku_free, toku_realloc); r = toku_rt_create(&tree, int_cmp, TXNID_cmp, false, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR(r); CKERR(r);
assert(tree != NULL); assert(tree != NULL);
...@@ -152,7 +142,7 @@ int main(int argc, const char *argv[]) { ...@@ -152,7 +142,7 @@ int main(int argc, const char *argv[]) {
r = toku_rt_close(tree); CKERR(r); r = toku_rt_close(tree); CKERR(r);
#ifndef TOKU_RT_NOOVERLAPS #ifndef TOKU_RT_NOOVERLAPS
r = toku_rt_create(&tree, int_cmp, TXNID_cmp, TRUE, toku_malloc, toku_free, toku_realloc); r = toku_rt_create(&tree, int_cmp, TXNID_cmp, true, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR(r); CKERR(r);
assert(tree != NULL); assert(tree != NULL);
...@@ -165,11 +155,11 @@ int main(int argc, const char *argv[]) { ...@@ -165,11 +155,11 @@ int main(int argc, const char *argv[]) {
#endif #endif
/* Get allow overlap */ /* Get allow overlap */
BOOL allowed; bool allowed;
r = toku_rt_get_allow_overlaps(NULL, &allowed); r = toku_rt_get_allow_overlaps(NULL, &allowed);
CKERR2(r, EINVAL); CKERR2(r, EINVAL);
r = toku_rt_create(&tree, int_cmp, TXNID_cmp, FALSE, toku_malloc, toku_free, toku_realloc); r = toku_rt_create(&tree, int_cmp, TXNID_cmp, false, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR(r); CKERR(r);
assert(tree != NULL); assert(tree != NULL);
...@@ -180,16 +170,10 @@ int main(int argc, const char *argv[]) { ...@@ -180,16 +170,10 @@ int main(int argc, const char *argv[]) {
tree = NULL; tree = NULL;
/* size tests */ /* size tests */
r = toku_rt_create(&tree, int_cmp, TXNID_cmp, FALSE, toku_malloc, toku_free, toku_realloc); r = toku_rt_create(&tree, int_cmp, TXNID_cmp, false, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR(r); CKERR(r);
assert(tree != NULL); assert(tree != NULL);
r = toku_rt_get_size(NULL, NULL); CKERR2(r, EINVAL);
r = toku_rt_get_size(tree, NULL); CKERR2(r, EINVAL);
u_int32_t tree_size;
r = toku_rt_get_size(NULL, &tree_size); CKERR2(r, EINVAL);
r = toku_rt_get_size(tree, &tree_size); CKERR(r);
r = toku_rt_close(tree); CKERR(r); r = toku_rt_close(tree); CKERR(r);
tree = NULL; tree = NULL;
......
...@@ -21,7 +21,7 @@ int main(int argc, const char *argv[]) { ...@@ -21,7 +21,7 @@ int main(int argc, const char *argv[]) {
|-------B-------| |-------B-------|
*/ */
#ifndef TOKU_RT_NOOVERLAPS #ifndef TOKU_RT_NOOVERLAPS
r = toku_rt_create(&tree, int_cmp, char_cmp, TRUE, toku_malloc, toku_free, toku_realloc); r = toku_rt_create(&tree, int_cmp, char_cmp, true, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR(r); CKERR(r);
/* Verify we can insert a trivial range and lose it. */ /* Verify we can insert a trivial range and lose it. */
...@@ -29,8 +29,7 @@ int main(int argc, const char *argv[]) { ...@@ -29,8 +29,7 @@ int main(int argc, const char *argv[]) {
range.ends.right = (toku_point*)&nums[1]; range.ends.right = (toku_point*)&nums[1];
range.data = (TXNID)letters[0]; range.data = (TXNID)letters[0];
r = toku_rt_insert(tree, &range); CKERR(r); r = toku_rt_insert(tree, &range); CKERR(r);
u_int32_t num_in_range; size_t num_in_range = toku_rt_get_size(tree);
r = toku_rt_get_size(tree, &num_in_range); CKERR(r);
assert(num_in_range == 1); assert(num_in_range == 1);
r = toku_rt_delete(tree, &range); CKERR(r); r = toku_rt_delete(tree, &range); CKERR(r);
...@@ -112,7 +111,7 @@ int main(int argc, const char *argv[]) { ...@@ -112,7 +111,7 @@ int main(int argc, const char *argv[]) {
|---A---| |---A---|
|---B---| |---B---|
*/ */
r = toku_rt_create(&tree, int_cmp, char_cmp, FALSE, toku_malloc, toku_free, toku_realloc); r = toku_rt_create(&tree, int_cmp, char_cmp, false, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR(r); CKERR(r);
/* Verify we can insert a trivial range and lose it. */ /* Verify we can insert a trivial range and lose it. */
......
...@@ -3,20 +3,8 @@ ...@@ -3,20 +3,8 @@
#include "test.h" #include "test.h"
unsigned malloc_cnt;
unsigned malloc_cntl;
/* Controllable malloc failure: it fails only the ith time it is invoked */
static void* malloc_fail(size_t size) {
if (malloc_cntl == ++malloc_cnt) {
errno = ENOMEM;
return NULL;
} else
return toku_malloc(size);
}
static void static void
RunTest (BOOL f_overlaps_allowed) { RunTest (bool f_overlaps_allowed) {
int i, j; int i, j;
int r; int r;
toku_range_tree *tree; toku_range_tree *tree;
...@@ -30,7 +18,7 @@ RunTest (BOOL f_overlaps_allowed) { ...@@ -30,7 +18,7 @@ RunTest (BOOL f_overlaps_allowed) {
/* Insert and delete lots of ranges to force memory increase and decrease */ /* Insert and delete lots of ranges to force memory increase and decrease */
r = toku_rt_create(&tree, int_cmp, char_cmp, f_overlaps_allowed, toku_malloc, toku_free, toku_realloc); r = toku_rt_create(&tree, int_cmp, char_cmp, f_overlaps_allowed, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR(r); CKERR(r);
/* Insert lots of ranges */ /* Insert lots of ranges */
...@@ -52,28 +40,16 @@ RunTest (BOOL f_overlaps_allowed) { ...@@ -52,28 +40,16 @@ RunTest (BOOL f_overlaps_allowed) {
} }
r = toku_rt_close(tree); CKERR(r); r = toku_rt_close(tree); CKERR(r);
tree = NULL; tree = NULL;
/* Force malloc to fail */
/* Failure when allocating the tree */
malloc_cnt = 0;
malloc_cntl = 1;
r = toku_rt_create(&tree, int_cmp, char_cmp, f_overlaps_allowed, malloc_fail, toku_free,
toku_realloc);
CKERR2(r, ENOMEM);
} }
int main(int argc, const char *argv[]) { int main(int argc, const char *argv[]) {
parse_args(argc, argv); parse_args(argc, argv);
#ifndef TOKU_RT_NOOVERLAPS #ifndef TOKU_RT_NOOVERLAPS
RunTest(TRUE); RunTest(true);
#endif #endif
RunTest(FALSE); RunTest(false);
return 0; return 0;
} }
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include "test.h" #include "test.h"
static void static void
run_test (BOOL overlap_allowed) { run_test (bool overlap_allowed) {
int r; int r;
toku_range_tree *tree; toku_range_tree *tree;
toku_range range; toku_range range;
...@@ -17,15 +17,7 @@ run_test (BOOL overlap_allowed) { ...@@ -17,15 +17,7 @@ run_test (BOOL overlap_allowed) {
1 2 3 4 5 6 7 1 2 3 4 5 6 7
|---A-----------| |---A-----------|
*/ */
r = toku_rt_create( r = toku_rt_create(&tree, int_cmp, char_cmp, overlap_allowed, test_incr_memory_size, test_decr_memory_size, NULL);
&tree,
int_cmp,
char_cmp,
overlap_allowed,
toku_malloc,
toku_free,
toku_realloc
);
CKERR(r); CKERR(r);
range.ends.left = (toku_point*)&nums[1]; range.ends.left = (toku_point*)&nums[1];
...@@ -43,8 +35,8 @@ int main(int argc, const char *argv[]) { ...@@ -43,8 +35,8 @@ int main(int argc, const char *argv[]) {
parse_args(argc, argv); parse_args(argc, argv);
#ifndef TOKU_RT_NOOVERLAPS #ifndef TOKU_RT_NOOVERLAPS
run_test(TRUE); run_test(true);
#endif #endif
run_test(FALSE); run_test(false);
return 0; return 0;
} }
...@@ -40,7 +40,7 @@ int main(int argc, const char *argv[]) { ...@@ -40,7 +40,7 @@ int main(int argc, const char *argv[]) {
|-------A-------| |-------A-------|
|-------B-------| |-------B-------|
*/ */
r = toku_rt_create(&tree, int_cmp, char_cmp, TRUE, toku_malloc, toku_free, toku_realloc); r = toku_rt_create(&tree, int_cmp, char_cmp, true, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR(r); CKERR(r);
r = toku_rt_find(tree, &find_range, 4, &buf, &bufsize, &found); CKERR(r); r = toku_rt_find(tree, &find_range, 4, &buf, &bufsize, &found); CKERR(r);
...@@ -190,7 +190,7 @@ int main(int argc, const char *argv[]) { ...@@ -190,7 +190,7 @@ int main(int argc, const char *argv[]) {
find_range.left = (toku_point*)&nums[3]; find_range.left = (toku_point*)&nums[3];
find_range.right = (toku_point*)&nums[4]; find_range.right = (toku_point*)&nums[4];
r = toku_rt_create(&tree, int_cmp, char_cmp, FALSE, toku_malloc, toku_free, toku_realloc); r = toku_rt_create(&tree, int_cmp, char_cmp, false, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR(r); CKERR(r);
r = toku_rt_find(tree, &find_range, 4, &buf, &bufsize, &found); CKERR(r); r = toku_rt_find(tree, &find_range, 4, &buf, &bufsize, &found); CKERR(r);
......
...@@ -12,7 +12,7 @@ unsigned buflen; ...@@ -12,7 +12,7 @@ unsigned buflen;
#include "run.h" #include "run.h"
static void static void
tests (BOOL allow_overlaps) { tests (bool allow_overlaps) {
toku_interval query; toku_interval query;
toku_range insert; toku_range insert;
/* /*
...@@ -23,7 +23,7 @@ tests (BOOL allow_overlaps) { ...@@ -23,7 +23,7 @@ tests (BOOL allow_overlaps) {
/* Tree: {|0-1|,|2-3|,|4-5|,|6-7|,|8-9|}, query of |2-7|, limit 2 finds 2, /* Tree: {|0-1|,|2-3|,|4-5|,|6-7|,|8-9|}, query of |2-7|, limit 2 finds 2,
limit 3 finds 3, limit 4 finds 3, limit 0 finds 3 */ limit 3 finds 3, limit 4 finds 3, limit 0 finds 3 */
setup_tree(allow_overlaps, TRUE, 0, 1, 0); setup_tree(allow_overlaps, true, 0, 1, 0);
runinsert(0, init_range(&insert, 2, 3, 0)); runinsert(0, init_range(&insert, 2, 3, 0));
runinsert(0, init_range(&insert, 4, 5, 0)); runinsert(0, init_range(&insert, 4, 5, 0));
runinsert(0, init_range(&insert, 6, 7, 0)); runinsert(0, init_range(&insert, 6, 7, 0));
...@@ -37,26 +37,26 @@ tests (BOOL allow_overlaps) { ...@@ -37,26 +37,26 @@ tests (BOOL allow_overlaps) {
close_tree(); close_tree();
/* Tree is empty (return none) */ /* Tree is empty (return none) */
setup_tree(allow_overlaps, FALSE, 0, 0, 0); setup_tree(allow_overlaps, false, 0, 0, 0);
runlimitsearch(init_query(&query, 0, 0), 0, 0); runlimitsearch(init_query(&query, 0, 0), 0, 0);
close_tree(); close_tree();
/* Tree contains only elements to the left. */ /* Tree contains only elements to the left. */
setup_tree(allow_overlaps, FALSE, 0, 0, 0); setup_tree(allow_overlaps, false, 0, 0, 0);
runinsert(0, init_range(&insert, 1, 2, 0)); runinsert(0, init_range(&insert, 1, 2, 0));
runinsert(0, init_range(&insert, 3, 4, 0)); runinsert(0, init_range(&insert, 3, 4, 0));
runlimitsearch(init_query(&query, 8, 30), 0, 0); runlimitsearch(init_query(&query, 8, 30), 0, 0);
close_tree(); close_tree();
/* Tree contains only elements to the right. */ /* Tree contains only elements to the right. */
setup_tree(allow_overlaps, FALSE, 0, 0, 0); setup_tree(allow_overlaps, false, 0, 0, 0);
runinsert(0, init_range(&insert, 10, 20, 0)); runinsert(0, init_range(&insert, 10, 20, 0));
runinsert(0, init_range(&insert, 30, 40, 0)); runinsert(0, init_range(&insert, 30, 40, 0));
runlimitsearch(init_query(&query, 5, 7), 0, 0); runlimitsearch(init_query(&query, 5, 7), 0, 0);
close_tree(); close_tree();
/* Tree contains only elements to the left and to the right. */ /* Tree contains only elements to the left and to the right. */
setup_tree(allow_overlaps, FALSE, 0, 0, 0); setup_tree(allow_overlaps, false, 0, 0, 0);
runinsert(0, init_range(&insert, 10, 20, 0)); runinsert(0, init_range(&insert, 10, 20, 0));
runinsert(0, init_range(&insert, 30, 40, 0)); runinsert(0, init_range(&insert, 30, 40, 0));
runinsert(0, init_range(&insert, 70, 80, 0)); runinsert(0, init_range(&insert, 70, 80, 0));
...@@ -65,7 +65,7 @@ tests (BOOL allow_overlaps) { ...@@ -65,7 +65,7 @@ tests (BOOL allow_overlaps) {
close_tree(); close_tree();
/* Tree contains overlaps and elements to the left. */ /* Tree contains overlaps and elements to the left. */
setup_tree(allow_overlaps, FALSE, 0, 0, 0); setup_tree(allow_overlaps, false, 0, 0, 0);
runinsert(0, init_range(&insert, 10, 20, 0)); runinsert(0, init_range(&insert, 10, 20, 0));
runinsert(0, init_range(&insert, 30, 40, 0)); runinsert(0, init_range(&insert, 30, 40, 0));
runinsert(0, init_range(&insert, 60, 80, 0)); runinsert(0, init_range(&insert, 60, 80, 0));
...@@ -74,7 +74,7 @@ tests (BOOL allow_overlaps) { ...@@ -74,7 +74,7 @@ tests (BOOL allow_overlaps) {
close_tree(); close_tree();
/* Tree contains overlaps and elements to the right. */ /* Tree contains overlaps and elements to the right. */
setup_tree(allow_overlaps, FALSE, 0, 0, 0); setup_tree(allow_overlaps, false, 0, 0, 0);
runinsert(0, init_range(&insert, 110, 120, 0)); runinsert(0, init_range(&insert, 110, 120, 0));
runinsert(0, init_range(&insert, 130, 140, 0)); runinsert(0, init_range(&insert, 130, 140, 0));
runinsert(0, init_range(&insert, 60, 80, 0)); runinsert(0, init_range(&insert, 60, 80, 0));
...@@ -83,7 +83,7 @@ tests (BOOL allow_overlaps) { ...@@ -83,7 +83,7 @@ tests (BOOL allow_overlaps) {
close_tree(); close_tree();
/* Tree contains overlaps and elements to the left and to the right. */ /* Tree contains overlaps and elements to the left and to the right. */
setup_tree(allow_overlaps, FALSE, 0, 0, 0); setup_tree(allow_overlaps, false, 0, 0, 0);
runinsert(0, init_range(&insert, 10, 20, 0)); runinsert(0, init_range(&insert, 10, 20, 0));
runinsert(0, init_range(&insert, 30, 40, 0)); runinsert(0, init_range(&insert, 30, 40, 0));
runinsert(0, init_range(&insert, 110, 120, 0)); runinsert(0, init_range(&insert, 110, 120, 0));
...@@ -101,9 +101,9 @@ int main(int argc, const char *argv[]) { ...@@ -101,9 +101,9 @@ int main(int argc, const char *argv[]) {
for (i = 0; i < sizeof(nums) / sizeof(nums[0]); i++) nums[i] = i; for (i = 0; i < sizeof(nums) / sizeof(nums[0]); i++) nums[i] = i;
buflen = 2; buflen = 2;
buf = (toku_range*)toku_malloc(2 * sizeof(toku_range)); buf = (toku_range*)toku_malloc(2 * sizeof(toku_range));
tests(FALSE); tests(false);
#ifndef TOKU_RT_NOOVERLAPS #ifndef TOKU_RT_NOOVERLAPS
tests(TRUE); tests(true);
#endif #endif
tree = NULL; tree = NULL;
toku_free(buf); toku_free(buf);
......
...@@ -11,16 +11,16 @@ unsigned buflen; ...@@ -11,16 +11,16 @@ unsigned buflen;
#include "run.h" #include "run.h"
static void verify_overlap(BOOL allow_overlaps) { static void verify_overlap(bool allow_overlaps) {
int r; int r;
BOOL allowed; bool allowed;
r = toku_rt_get_allow_overlaps(tree, &allowed); r = toku_rt_get_allow_overlaps(tree, &allowed);
CKERR(r); CKERR(r);
assert(allowed == allow_overlaps); assert(allowed == allow_overlaps);
} }
static void tests(BOOL allow_overlaps) { static void tests(bool allow_overlaps) {
toku_range expect; toku_range expect;
toku_interval query; toku_interval query;
toku_range toinsert; toku_range toinsert;
...@@ -37,23 +37,23 @@ static void tests(BOOL allow_overlaps) { ...@@ -37,23 +37,23 @@ static void tests(BOOL allow_overlaps) {
/* Tree: {|0-1|}, query of |1-2| returns |0-1| /* Tree: {|0-1|}, query of |1-2| returns |0-1|
In this test, I am also going to verify that the allow_overlaps bit In this test, I am also going to verify that the allow_overlaps bit
is set appropriately. */ is set appropriately. */
setup_tree(allow_overlaps, TRUE, 0, 1, 0); setup_tree(allow_overlaps, true, 0, 1, 0);
verify_overlap(allow_overlaps); verify_overlap(allow_overlaps);
runsearch(0, init_query(&query, 1, 2), init_range(&expect, 0, 1, 0)); runsearch(0, init_query(&query, 1, 2), init_range(&expect, 0, 1, 0));
close_tree(); close_tree();
/* Tree: {|1-2|}, query of |0-1| returns |1-2| */ /* Tree: {|1-2|}, query of |0-1| returns |1-2| */
setup_tree(allow_overlaps, TRUE, 1, 2, 0); setup_tree(allow_overlaps, true, 1, 2, 0);
runsearch(0, init_query(&query, 0, 1), init_range(&expect, 1, 2, 0)); runsearch(0, init_query(&query, 0, 1), init_range(&expect, 1, 2, 0));
close_tree(); close_tree();
/* Tree: {|1-2|}, insert of of |0-1| success == allow_overlaps */ /* Tree: {|1-2|}, insert of of |0-1| success == allow_overlaps */
setup_tree(allow_overlaps, TRUE, 1, 2, 0); setup_tree(allow_overlaps, true, 1, 2, 0);
runinsert((allow_overlaps ? 0 : EDOM), init_range(&toinsert, 0, 1, 0)); runinsert((allow_overlaps ? 0 : EDOM), init_range(&toinsert, 0, 1, 0));
close_tree(); close_tree();
/* Tree: {|0-1|}, insert of of |1-2| success == allow_overlaps */ /* Tree: {|0-1|}, insert of of |1-2| success == allow_overlaps */
setup_tree(allow_overlaps, TRUE, 0, 1, 0); setup_tree(allow_overlaps, true, 0, 1, 0);
runinsert((allow_overlaps ? 0 : EDOM), init_range(&toinsert, 1, 2, 0)); runinsert((allow_overlaps ? 0 : EDOM), init_range(&toinsert, 1, 2, 0));
close_tree(); close_tree();
...@@ -67,22 +67,22 @@ static void tests(BOOL allow_overlaps) { ...@@ -67,22 +67,22 @@ static void tests(BOOL allow_overlaps) {
*/ */
/* Tree: {|0-3|}, query of |1-2| returns |0-3| */ /* Tree: {|0-3|}, query of |1-2| returns |0-3| */
setup_tree(allow_overlaps, TRUE, 0, 3, 0); setup_tree(allow_overlaps, true, 0, 3, 0);
runsearch(0, init_query(&query, 1, 2), init_range(&expect, 0, 3, 0)); runsearch(0, init_query(&query, 1, 2), init_range(&expect, 0, 3, 0));
close_tree(); close_tree();
/* Tree: {|1-2|}, query of |0-3| returns |1-2| */ /* Tree: {|1-2|}, query of |0-3| returns |1-2| */
setup_tree(allow_overlaps, TRUE, 1, 2, 0); setup_tree(allow_overlaps, true, 1, 2, 0);
runsearch(0, init_query(&query, 0, 3), init_range(&expect, 1, 2, 0)); runsearch(0, init_query(&query, 0, 3), init_range(&expect, 1, 2, 0));
close_tree(); close_tree();
/* Tree: {|1-2|}, insert of of |0-3| success == allow_overlaps */ /* Tree: {|1-2|}, insert of of |0-3| success == allow_overlaps */
setup_tree(allow_overlaps, TRUE, 1, 2, 0); setup_tree(allow_overlaps, true, 1, 2, 0);
runinsert((allow_overlaps ? 0 : EDOM), init_range(&toinsert, 0, 3, 0)); runinsert((allow_overlaps ? 0 : EDOM), init_range(&toinsert, 0, 3, 0));
close_tree(); close_tree();
/* Tree: {|0-3|}, insert of of |1-2| success == allow_overlaps */ /* Tree: {|0-3|}, insert of of |1-2| success == allow_overlaps */
setup_tree(allow_overlaps, TRUE, 0, 3, 0); setup_tree(allow_overlaps, true, 0, 3, 0);
runinsert((allow_overlaps ? 0 : EDOM), init_range(&toinsert, 1, 2, 0)); runinsert((allow_overlaps ? 0 : EDOM), init_range(&toinsert, 1, 2, 0));
close_tree(); close_tree();
...@@ -94,17 +94,17 @@ static void tests(BOOL allow_overlaps) { ...@@ -94,17 +94,17 @@ static void tests(BOOL allow_overlaps) {
*/ */
/* Tree: {|0-3|}, query of |0-3| returns |0-3| */ /* Tree: {|0-3|}, query of |0-3| returns |0-3| */
setup_tree(allow_overlaps, TRUE, 0, 3, 0); setup_tree(allow_overlaps, true, 0, 3, 0);
runsearch(0, init_query(&query, 0, 3), init_range(&expect, 0, 3, 0)); runsearch(0, init_query(&query, 0, 3), init_range(&expect, 0, 3, 0));
close_tree(); close_tree();
/* Tree: {(|0-3|,0)}, insert of of (|0-3|,1) success == allow_overlaps */ /* Tree: {(|0-3|,0)}, insert of of (|0-3|,1) success == allow_overlaps */
setup_tree(allow_overlaps, TRUE, 0, 3, 0); setup_tree(allow_overlaps, true, 0, 3, 0);
runinsert((allow_overlaps ? 0 : EDOM), init_range(&toinsert, 0, 3, 1)); runinsert((allow_overlaps ? 0 : EDOM), init_range(&toinsert, 0, 3, 1));
close_tree(); close_tree();
/* Tree: {(|1-3|,0),(|5-6|,0)} */ /* Tree: {(|1-3|,0),(|5-6|,0)} */
setup_tree(allow_overlaps, TRUE, 1, 3, 0); setup_tree(allow_overlaps, true, 1, 3, 0);
runinsert(0, init_range(&toinsert, 5, 6, 0)); runinsert(0, init_range(&toinsert, 5, 6, 0));
runsearch(0, init_query(&query, 3, 4), init_range(&expect, 1, 3, 0)); runsearch(0, init_query(&query, 3, 4), init_range(&expect, 1, 3, 0));
runsearch(0, init_query(&query, 4, 5), init_range(&expect, 5, 6, 0)); runsearch(0, init_query(&query, 4, 5), init_range(&expect, 5, 6, 0));
...@@ -120,9 +120,9 @@ int main(int argc, const char *argv[]) { ...@@ -120,9 +120,9 @@ int main(int argc, const char *argv[]) {
buflen = 2; buflen = 2;
buf = (toku_range*)toku_malloc(2 * sizeof(toku_range)); buf = (toku_range*)toku_malloc(2 * sizeof(toku_range));
tests(FALSE); tests(false);
#ifndef TOKU_RT_NOOVERLAPS #ifndef TOKU_RT_NOOVERLAPS
tests(TRUE); tests(true);
#endif #endif
tree = NULL; tree = NULL;
......
...@@ -20,11 +20,11 @@ rundelete (int rexpect, toku_range* todelete) { ...@@ -20,11 +20,11 @@ rundelete (int rexpect, toku_range* todelete) {
} }
static void static void
tests (BOOL allow_overlaps) { tests (bool allow_overlaps) {
toku_range insert; toku_range insert;
int i; int i;
/* Force buf to increase. */ /* Force buf to increase. */
setup_tree(allow_overlaps, FALSE, 0, 0, 0); setup_tree(allow_overlaps, false, 0, 0, 0);
for (i = 0; i < (int)numlen / 2; i++) { for (i = 0; i < (int)numlen / 2; i++) {
runinsert(0, init_range(&insert, i, i, 0)); runinsert(0, init_range(&insert, i, i, 0));
int j = numlen /2 + i; int j = numlen /2 + i;
...@@ -48,9 +48,9 @@ int main(int argc, const char *argv[]) { ...@@ -48,9 +48,9 @@ int main(int argc, const char *argv[]) {
for (i = 0; i < sizeof(nums) / sizeof(nums[0]); i++) nums[i] = i; for (i = 0; i < sizeof(nums) / sizeof(nums[0]); i++) nums[i] = i;
buflen = 2; buflen = 2;
buf = (toku_range*)toku_malloc(2 * sizeof(toku_range)); buf = (toku_range*)toku_malloc(2 * sizeof(toku_range));
tests(FALSE); tests(false);
#ifndef TOKU_RT_NOOVERLAPS #ifndef TOKU_RT_NOOVERLAPS
tests(TRUE); tests(true);
#endif #endif
tree = NULL; tree = NULL;
......
...@@ -33,10 +33,10 @@ runsearch (int rexpect, toku_interval* query, toku_range* expect) { ...@@ -33,10 +33,10 @@ runsearch (int rexpect, toku_interval* query, toku_range* expect) {
typedef enum {PRED=0, SUCC=1} predsucc; typedef enum {PRED=0, SUCC=1} predsucc;
static void static void
runtest (predsucc testtype, toku_point* query, BOOL findexpect, runtest (predsucc testtype, toku_point* query, bool findexpect,
unsigned left, unsigned right, unsigned data) { unsigned left, unsigned right, unsigned data) {
int r; int r;
BOOL found; bool found;
toku_range out; toku_range out;
assert(data < sizeof(letters) / sizeof(letters[0])); assert(data < sizeof(letters) / sizeof(letters[0]));
assert(left < sizeof(nums) / sizeof(nums[0])); assert(left < sizeof(nums) / sizeof(nums[0]));
...@@ -60,7 +60,7 @@ runtest (predsucc testtype, toku_point* query, BOOL findexpect, ...@@ -60,7 +60,7 @@ runtest (predsucc testtype, toku_point* query, BOOL findexpect,
static void static void
tests (BOOL allow_overlaps) { tests (bool allow_overlaps) {
toku_range insert; toku_range insert;
/* /*
...@@ -84,25 +84,25 @@ tests (BOOL allow_overlaps) { ...@@ -84,25 +84,25 @@ tests (BOOL allow_overlaps) {
*/ */
/* Empty tree. */ /* Empty tree. */
setup_tree(allow_overlaps, FALSE, 0, 0, 0); setup_tree(allow_overlaps, false, 0, 0, 0);
runtest(PRED, init_point(5), FALSE, 0, 0, 0); runtest(PRED, init_point(5), false, 0, 0, 0);
runtest(SUCC, init_point(5), FALSE, 0, 0, 0); runtest(SUCC, init_point(5), false, 0, 0, 0);
close_tree(); close_tree();
/* Single element tree. Before left, left end point, middle, /* Single element tree. Before left, left end point, middle,
right end point, after right. */ right end point, after right. */
setup_tree(allow_overlaps, FALSE, 0, 0, 0); setup_tree(allow_overlaps, false, 0, 0, 0);
runinsert(0, init_range(&insert, 10, 20, 0)); runinsert(0, init_range(&insert, 10, 20, 0));
runtest(PRED, init_point(5), FALSE, 0, 0, 0); runtest(PRED, init_point(5), false, 0, 0, 0);
runtest(PRED, init_point(10), FALSE, 0, 0, 0); runtest(PRED, init_point(10), false, 0, 0, 0);
runtest(PRED, init_point(15), FALSE, 0, 0, 0); runtest(PRED, init_point(15), false, 0, 0, 0);
runtest(PRED, init_point(20), FALSE, 0, 0, 0); runtest(PRED, init_point(20), false, 0, 0, 0);
runtest(PRED, init_point(25), TRUE, 10, 20, 0); runtest(PRED, init_point(25), true, 10, 20, 0);
runtest(SUCC, init_point(5), TRUE, 10, 20, 0); runtest(SUCC, init_point(5), true, 10, 20, 0);
runtest(SUCC, init_point(10), FALSE, 0, 0, 0); runtest(SUCC, init_point(10), false, 0, 0, 0);
runtest(SUCC, init_point(15), FALSE, 0, 0, 0); runtest(SUCC, init_point(15), false, 0, 0, 0);
runtest(SUCC, init_point(20), FALSE, 0, 0, 0); runtest(SUCC, init_point(20), false, 0, 0, 0);
runtest(SUCC, init_point(25), FALSE, 0, 0, 0); runtest(SUCC, init_point(25), false, 0, 0, 0);
close_tree(); close_tree();
/* /*
...@@ -124,7 +124,7 @@ tests (BOOL allow_overlaps) { ...@@ -124,7 +124,7 @@ tests (BOOL allow_overlaps) {
* Something on left. * Something on left.
* Nothing on left. * Nothing on left.
*/ */
setup_tree(allow_overlaps, FALSE, 0, 0, 0); setup_tree(allow_overlaps, false, 0, 0, 0);
runinsert(0, init_range(&insert, 10, 20, 0)); runinsert(0, init_range(&insert, 10, 20, 0));
runinsert(0, init_range(&insert, 30, 40, 0)); runinsert(0, init_range(&insert, 30, 40, 0));
...@@ -133,64 +133,64 @@ tests (BOOL allow_overlaps) { ...@@ -133,64 +133,64 @@ tests (BOOL allow_overlaps) {
* Something on left. * Something on left.
* Nothing on left. * Nothing on left.
*/ */
runtest(PRED, init_point(25), TRUE, 10, 20, 0); runtest(PRED, init_point(25), true, 10, 20, 0);
runtest(PRED, init_point(5), FALSE, 0, 0, 0); runtest(PRED, init_point(5), false, 0, 0, 0);
/* /*
* At a left end point. * At a left end point.
* Something on left. * Something on left.
* Nothing on left. * Nothing on left.
*/ */
runtest(PRED, init_point(30), TRUE, 10, 20, 0); runtest(PRED, init_point(30), true, 10, 20, 0);
runtest(PRED, init_point(10), FALSE, 0, 0, 0); runtest(PRED, init_point(10), false, 0, 0, 0);
/* /*
* Inside a range. * Inside a range.
* Something on left. * Something on left.
* Nothing on left. * Nothing on left.
*/ */
runtest(PRED, init_point(35), TRUE, 10, 20, 0); runtest(PRED, init_point(35), true, 10, 20, 0);
runtest(PRED, init_point(15), FALSE, 0, 0, 0); runtest(PRED, init_point(15), false, 0, 0, 0);
/* /*
* At a right end point. * At a right end point.
* Something on left. * Something on left.
* Nothing on left. * Nothing on left.
*/ */
runtest(PRED, init_point(40), TRUE, 10, 20, 0); runtest(PRED, init_point(40), true, 10, 20, 0);
runtest(PRED, init_point(20), FALSE, 0, 0, 0); runtest(PRED, init_point(20), false, 0, 0, 0);
/* /*
* In empty space. * In empty space.
* Something on right. * Something on right.
* Nothing on right. * Nothing on right.
*/ */
runtest(SUCC, init_point(25), TRUE, 30, 40, 0); runtest(SUCC, init_point(25), true, 30, 40, 0);
runtest(SUCC, init_point(45), FALSE, 0, 0, 0); runtest(SUCC, init_point(45), false, 0, 0, 0);
/* /*
* At a right end point. * At a right end point.
* Something on right. * Something on right.
* Nothing on right. * Nothing on right.
*/ */
runtest(SUCC, init_point(20), TRUE, 30, 40, 0); runtest(SUCC, init_point(20), true, 30, 40, 0);
runtest(SUCC, init_point(40), FALSE, 0, 0, 0); runtest(SUCC, init_point(40), false, 0, 0, 0);
/* /*
* Inside a range. * Inside a range.
* Something on right. * Something on right.
* Nothing on right. * Nothing on right.
*/ */
runtest(SUCC, init_point(15), TRUE, 30, 40, 0); runtest(SUCC, init_point(15), true, 30, 40, 0);
runtest(SUCC, init_point(35), FALSE, 0, 0, 0); runtest(SUCC, init_point(35), false, 0, 0, 0);
/* /*
* At a right end point. * At a right end point.
* Something on right. * Something on right.
* Nothing on right. * Nothing on right.
*/ */
runtest(SUCC, init_point(20), TRUE, 30, 40, 0); runtest(SUCC, init_point(20), true, 30, 40, 0);
runtest(SUCC, init_point(40), FALSE, 0, 0, 0); runtest(SUCC, init_point(40), false, 0, 0, 0);
close_tree(); close_tree();
...@@ -199,7 +199,7 @@ tests (BOOL allow_overlaps) { ...@@ -199,7 +199,7 @@ tests (BOOL allow_overlaps) {
With other interval that cannot be the predecessor With other interval that cannot be the predecessor
or the successor, but that need to be looked at. */ or the successor, but that need to be looked at. */
setup_tree(allow_overlaps, FALSE, 0, 0, 0); setup_tree(allow_overlaps, false, 0, 0, 0);
runinsert(0, init_range(&insert, 5, 7, 0)); runinsert(0, init_range(&insert, 5, 7, 0));
runinsert(0, init_range(&insert, 50, 60, 0)); runinsert(0, init_range(&insert, 50, 60, 0));
runinsert(0, init_range(&insert, 10, 20, 0)); runinsert(0, init_range(&insert, 10, 20, 0));
...@@ -207,10 +207,10 @@ tests (BOOL allow_overlaps) { ...@@ -207,10 +207,10 @@ tests (BOOL allow_overlaps) {
runinsert(0, init_range(&insert, 2, 4, 0)); runinsert(0, init_range(&insert, 2, 4, 0));
runinsert(0, init_range(&insert, 70, 80, 0)); runinsert(0, init_range(&insert, 70, 80, 0));
runtest(PRED, init_point(25), TRUE, 10, 20, 0); runtest(PRED, init_point(25), true, 10, 20, 0);
runtest(PRED, init_point(4), FALSE, 0, 0, 0); runtest(PRED, init_point(4), false, 0, 0, 0);
runtest(SUCC, init_point(25), TRUE, 30, 40, 0); runtest(SUCC, init_point(25), true, 30, 40, 0);
runtest(SUCC, init_point(95), FALSE, 0, 0, 0); runtest(SUCC, init_point(95), false, 0, 0, 0);
close_tree(); close_tree();
} }
...@@ -223,7 +223,7 @@ int main(int argc, const char *argv[]) { ...@@ -223,7 +223,7 @@ int main(int argc, const char *argv[]) {
for (i = 0; i < sizeof(nums) / sizeof(nums[0]); i++) nums[i] = i; for (i = 0; i < sizeof(nums) / sizeof(nums[0]); i++) nums[i] = i;
buflen = 2; buflen = 2;
buf = (toku_range*)toku_malloc(2 * sizeof(toku_range)); buf = (toku_range*)toku_malloc(2 * sizeof(toku_range));
tests(FALSE); tests(false);
tree = NULL; tree = NULL;
toku_free(buf); toku_free(buf);
......
...@@ -26,15 +26,15 @@ int main(int argc, const char *argv[]) { ...@@ -26,15 +26,15 @@ int main(int argc, const char *argv[]) {
parse_args(argc, argv); parse_args(argc, argv);
toku_range_tree *tree; toku_range_tree *tree;
r = toku_rt_create(&tree, int_cmp, char_cmp, FALSE, toku_malloc, toku_free, toku_realloc); CKERR(r); r = toku_rt_create(&tree, int_cmp, char_cmp, false, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR(r);
assert(count_ranges(tree) == 0); assert(count_ranges(tree) == 0);
const int nranges = 10; const int nranges = 10;
int nums[nranges]; int nums[nranges];
for (int i = 0; i < nranges; i++) { for (int i = 0; i < nranges; i++) {
assert(count_ranges(tree) == i); assert(count_ranges(tree) == i);
u_int32_t treesize = 0; u_int32_t treesize = toku_rt_get_size(tree);
r = toku_rt_get_size(tree, &treesize); CKERR(r);
assert(treesize == (u_int32_t) i); assert(treesize == (u_int32_t) i);
nums[i] = i; nums[i] = i;
toku_range range; my_init_range(&range, &nums[i], &nums[i], 'a'); toku_range range; my_init_range(&range, &nums[i], &nums[i], 'a');
......
...@@ -14,7 +14,8 @@ int main(int argc, const char *argv[]) { ...@@ -14,7 +14,8 @@ int main(int argc, const char *argv[]) {
parse_args(argc, argv); parse_args(argc, argv);
toku_range_tree *tree; toku_range_tree *tree;
r = toku_rt_create(&tree, int_cmp, char_cmp, FALSE, toku_malloc, toku_free, toku_realloc); CKERR(r); r = toku_rt_create(&tree, int_cmp, char_cmp, false, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR(r);
int insert_left = 10; int insert_right = 20; int insert_left = 10; int insert_right = 20;
toku_range insert_range; my_init_range(&insert_range, &insert_left, &insert_right, 'a'); toku_range insert_range; my_init_range(&insert_range, &insert_left, &insert_right, 'a');
......
// verify the range tree memory size function
#include "test.h"
static void my_init_range(toku_range *range, int *left, int *right, int data) {
range->ends.left = (toku_point *) left;
range->ends.right = (toku_point *) right;
range->data = data;
}
int main(int argc, const char *argv[]) {
int r;
parse_args(argc, argv);
toku_range_tree *tree;
r = toku_rt_create(&tree, int_cmp, char_cmp, false, test_incr_memory_size, test_decr_memory_size, NULL);
CKERR(r);
size_t last_memory_size = toku_rt_memory_size(tree);
u_int32_t last_size;
const int nranges = 10;
int nums[nranges];
for (int i = 0; i < nranges; i++) {
last_size = toku_rt_get_size(tree);
assert(last_size == (u_int32_t) i);
nums[i] = i;
toku_range range; my_init_range(&range, &nums[i], &nums[i], 'a');
r = toku_rt_insert(tree, &range); CKERR(r);
size_t memory_size = toku_rt_memory_size(tree);
assert(memory_size >= last_memory_size);
if (verbose)
printf("%lu\n", memory_size);
last_memory_size = memory_size;
}
toku_rt_clear(tree);
last_size = toku_rt_get_size(tree);
assert(last_size == 0);
r = toku_rt_close(tree); CKERR(r);
return 0;
}
...@@ -2388,8 +2388,7 @@ toku_env_create(DB_ENV ** envp, u_int32_t flags) { ...@@ -2388,8 +2388,7 @@ toku_env_create(DB_ENV ** envp, u_int32_t flags) {
r = toku_ltm_create(&result->i->ltm, r = toku_ltm_create(&result->i->ltm,
__toku_env_default_max_locks, __toku_env_default_max_lock_memory, __toku_env_default_max_locks, __toku_env_default_max_lock_memory,
toku_db_lt_panic, toku_db_lt_panic,
toku_db_get_compare_fun, toku_db_get_compare_fun);
toku_malloc, toku_free, toku_realloc);
if (r!=0) { goto cleanup; } if (r!=0) { goto cleanup; }
toku_ltm_set_mutex(result->i->ltm, toku_ydb_mutex()); toku_ltm_set_mutex(result->i->ltm, toku_ydb_mutex());
...@@ -2779,8 +2778,7 @@ toku_txn_begin(DB_ENV *env, DB_TXN * stxn, DB_TXN ** txn, u_int32_t flags, int i ...@@ -2779,8 +2778,7 @@ toku_txn_begin(DB_ENV *env, DB_TXN * stxn, DB_TXN ** txn, u_int32_t flags, int i
int r; int r;
if (env->i->open_flags & DB_INIT_LOCK && !stxn) { if (env->i->open_flags & DB_INIT_LOCK && !stxn) {
r = toku_lth_create(&db_txn_struct_i(result)->lth, r = toku_lth_create(&db_txn_struct_i(result)->lth);
toku_malloc, toku_free, toku_realloc);
if (r!=0) { if (r!=0) {
#if !TOKUDB_NATIVE_H #if !TOKUDB_NATIVE_H
toku_free(db_txn_struct_i(result)); toku_free(db_txn_struct_i(result));
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
extern "C" { extern "C" {
#endif #endif
/* Tokutek memory allocation functions and macros. /* Tokutek memory allocation functions and macros.
* These are functions for malloc and free */ * These are functions for malloc and free */
...@@ -30,6 +29,8 @@ void toku_free(void*) __attribute__((__visibility__("default"))); ...@@ -30,6 +29,8 @@ void toku_free(void*) __attribute__((__visibility__("default")));
void toku_free_n(void*, size_t size); void toku_free_n(void*, size_t size);
void *toku_realloc(void *, size_t size) __attribute__((__visibility__("default"))); void *toku_realloc(void *, size_t size) __attribute__((__visibility__("default")));
size_t toku_malloc_usable_size(void *p) __attribute__((__visibility__("default")));
/* MALLOC is a macro that helps avoid a common error: /* MALLOC is a macro that helps avoid a common error:
* Suppose I write * Suppose I write
* struct foo *x = malloc(sizeof(struct foo)); * struct foo *x = malloc(sizeof(struct foo));
...@@ -81,20 +82,6 @@ void toku_memory_check_all_free (void); ...@@ -81,20 +82,6 @@ void toku_memory_check_all_free (void);
/* Check to see if memory is "sane". Might be a no-op. Probably better to simply use valgrind. */ /* Check to see if memory is "sane". Might be a no-op. Probably better to simply use valgrind. */
void toku_do_memory_check(void); void toku_do_memory_check(void);
extern int toku_memory_check; // Set to nonzero to get a (much) slower version of malloc that does (much) more checking.
int toku_get_n_items_malloced(void); /* How many items are malloc'd but not free'd. May return 0 depending on the configuration of memory.c */
void toku_print_malloced_items(void); /* Try to print some malloced-but-not-freed items. May be a noop. */
void toku_malloc_report (void); /* report on statistics about number of mallocs. Maybe a no-op. */
// For memory-debug.c Set this to an array of integers that say which mallocs should return NULL and ENOMEM.
// The array is terminated by a -1.
extern int *toku_dead_mallocs;
extern int toku_malloc_counter; // so you can reset it
extern int toku_realloc_counter;
extern int toku_calloc_counter;
extern int toku_free_counter;
typedef void *(*malloc_fun_t)(size_t); typedef void *(*malloc_fun_t)(size_t);
typedef void (*free_fun_t)(void*); typedef void (*free_fun_t)(void*);
typedef void *(*realloc_fun_t)(void*,size_t); typedef void *(*realloc_fun_t)(void*,size_t);
......
...@@ -10,8 +10,6 @@ ...@@ -10,8 +10,6 @@
#include "toku_assert.h" #include "toku_assert.h"
#include "toku_pthread.h" #include "toku_pthread.h"
int toku_memory_check=0;
static malloc_fun_t t_malloc = 0; static malloc_fun_t t_malloc = 0;
static malloc_fun_t t_xmalloc = 0; static malloc_fun_t t_xmalloc = 0;
static free_fun_t t_free = 0; static free_fun_t t_free = 0;
...@@ -168,6 +166,11 @@ toku_xrealloc(void *v, size_t size) { ...@@ -168,6 +166,11 @@ toku_xrealloc(void *v, size_t size) {
return p; return p;
} }
size_t
toku_malloc_usable_size(void *p) {
return malloc_usable_size(p);
}
void * void *
toku_xmemdup (const void *v, size_t len) { toku_xmemdup (const void *v, size_t len) {
void *p = toku_xmalloc(len); void *p = toku_xmalloc(len);
......
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