From 30a66896c0ea2d5ee9ef3e9ffeaf86f0f0d5cbb9 Mon Sep 17 00:00:00 2001 From: Yoni Fogel Date: Sat, 2 Feb 2008 02:06:22 +0000 Subject: [PATCH] Addresses #329 Addresses #293 Addresses #307 Finished code and integration of rangetree hashtable and lock tree. All tests pass now (although tests have not yet been written for the hashtable). git-svn-id: file:///svn/tokudb@2045 c7de825b-a66e-492c-adef-691d508d4ae1 --- src/lock_tree/rth.c | 33 +++++++++++++++++++++++---------- src/lock_tree/rth.h | 1 + 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/lock_tree/rth.c b/src/lock_tree/rth.c index 0ddc202eee8..3ad7c2c3b21 100644 --- a/src/lock_tree/rth.c +++ b/src/lock_tree/rth.c @@ -23,6 +23,10 @@ static uint32 __toku_rth_hash(toku_rt_hashtable* table, DB_TXN* key) { return tmp % table->array_size; } +static inline void __toku_invalidate_scan(toku_rt_hashtable* table) { + table->finger_end = TRUE; +} + int toku_rth_create(toku_rt_hashtable** ptable, void* (*user_malloc) (size_t), void (*user_free) (void*), @@ -33,13 +37,15 @@ int toku_rth_create(toku_rt_hashtable** ptable, if (!tmp) return errno; memset(tmp, 0, sizeof(*tmp)); - tmp->malloc = user_malloc; - tmp->free = user_free; - tmp->realloc = user_realloc; - tmp->array_size = __toku_rth_init_size; - tmp->table = (toku_rth_elt**) - tmp->malloc(tmp->array_size * sizeof(*tmp->table)); + tmp->malloc = user_malloc; + tmp->free = user_free; + tmp->realloc = user_realloc; + tmp->array_size = __toku_rth_init_size; + tmp->table = (toku_rth_elt**) + tmp->malloc(tmp->array_size * sizeof(*tmp->table)); if (!tmp->table) { r = errno; goto died1; } + memset(tmp->table, 0, tmp->array_size * sizeof(*tmp->table)); + __toku_invalidate_scan(tmp); *ptable = tmp; return 0; } @@ -56,15 +62,19 @@ toku_rt_forest* toku_rth_find(toku_rt_hashtable* table, DB_TXN* key) { void toku_rth_start_scan(toku_rt_hashtable* table) { assert(table); table->finger_index = 0; - table->finger_ptr = NULL; + table->finger_ptr = table->table[table->finger_index]; + table->finger_end = FALSE; } toku_rth_elt* __toku_rth_next(toku_rt_hashtable* table) { assert(table); + assert(!table->finger_end); + if (table->finger_ptr) table->finger_ptr = table->finger_ptr->next; - while (!table->finger_ptr && table->finger_index < table->array_size) { - table->finger_ptr = table->table[++table->finger_index]; - }; + while (!table->finger_ptr && ++table->finger_index < table->array_size) { + table->finger_ptr = table->table[table->finger_index]; + } + table->finger_end = !table->finger_ptr; return table->finger_ptr; } @@ -76,6 +86,8 @@ toku_rt_forest* toku_rth_next(toku_rt_hashtable* table) { int toku_rth_delete(toku_rt_hashtable* table, DB_TXN* key) { assert(table && key); + __toku_invalidate_scan(table); + /* No elements. */ if (!table->num_keys) return EDOM; @@ -133,6 +145,7 @@ void toku_rth_close(toku_rt_hashtable* table) { /* Will allow you to insert it over and over. You need to keep track. */ int toku_rth_insert(toku_rt_hashtable* table, DB_TXN* key) { assert(table && key); + __toku_invalidate_scan(table); uint32 index = __toku_rth_hash(table, key); diff --git a/src/lock_tree/rth.h b/src/lock_tree/rth.h index 10ae2b68cd4..9e1998b437a 100644 --- a/src/lock_tree/rth.h +++ b/src/lock_tree/rth.h @@ -36,6 +36,7 @@ struct __toku_rt_hashtable { uint32 array_size; uint32 finger_index; toku_rth_elt* finger_ptr; + BOOL finger_end; toku_rth_elt* free_list; /** The user malloc function */ void* (*malloc) (size_t);