Commit 72d39612 authored by Yoni Fogel's avatar Yoni Fogel

Addresses #293

Addresses #329
Combined rangetree hashtables and the lock tree.

git-svn-id: file:///svn/tokudb@2044 c7de825b-a66e-492c-adef-691d508d4ae1
parent f3b38bfb
...@@ -45,8 +45,11 @@ clean: ...@@ -45,8 +45,11 @@ clean:
locktree.o: locktree.c locktree.h locktree.o: locktree.c locktree.h
gcc $(CFLAGS) $(CPPFLAGS) -c -DTOKU_LINEAR_RANGE_TREE $< -o $@ gcc $(CFLAGS) $(CPPFLAGS) -c -DTOKU_LINEAR_RANGE_TREE $< -o $@
$(LIBNAME).$(LIBEXT): locktree.o rth.o: rth.c rth.h
cc $(CPPFLAGS) $< $(SHARED) -o $@ $(CFLAGS) -lrangetreelinear gcc $(CFLAGS) $(CPPFLAGS) -c -DTOKU_LINEAR_RANGE_TREE $< -o $@
$(LIBNAME).$(LIBEXT): locktree.o rth.o
cc $(CPPFLAGS) $^ $(SHARED) -o $@ $(CFLAGS) -lrangetreelinear
$(LIBNAME).a: locktree.o $(LIBNAME).a: locktree.o rth.o
$(AR) rv $@ $< $(AR) rv $@ $^
...@@ -176,42 +176,22 @@ static int __toku_p_makecopy(toku_lock_tree* tree, void** ppoint) { ...@@ -176,42 +176,22 @@ static int __toku_p_makecopy(toku_lock_tree* tree, void** ppoint) {
return 0; return 0;
} }
/* Provides access to a selfwrite tree for a particular transaction.
Returns NULL if it does not exist yet. */
toku_range_tree* __toku_lt_ifexist_selfwrite(toku_lock_tree* tree,
DB_TXN* txn) {
assert(tree && txn);
//TODO: Implement real version.
return tree->selfwrite;
}
/* 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, DB_TXN* txn) { toku_range_tree* __toku_lt_ifexist_selfread(toku_lock_tree* tree, DB_TXN* txn) {
assert(tree && txn); assert(tree && txn);
//TODO: Implement. toku_rt_forest* forest = toku_rth_find(tree->rth, txn);
return tree->selfread; return forest ? forest->self_read : NULL;
} }
/* 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. */ Returns NULL if it does not exist yet. */
static int __toku_lt_selfwrite(toku_lock_tree* tree, DB_TXN* txn, toku_range_tree* __toku_lt_ifexist_selfwrite(toku_lock_tree* tree,
toku_range_tree** pselfwrite) { DB_TXN* txn) {
int r; assert(tree && txn);
assert(tree && txn && pselfwrite); toku_rt_forest* forest = toku_rth_find(tree->rth, txn);
return forest ? forest->self_write : NULL;
//TODO: Remove this, and use multiples per transaction
if (!tree->selfwrite)
{
r = toku_rt_create(&tree->selfwrite,
__toku_lt_point_cmp, __toku_lt_txn_cmp, FALSE,
tree->malloc, tree->free, tree->realloc);
if(r!=0) return r;
}
assert(tree->selfwrite);
*pselfwrite = tree->selfwrite;
return 0;
} }
/* Provides access to a selfread tree for a particular transaction. /* Provides access to a selfread tree for a particular transaction.
...@@ -221,20 +201,52 @@ static int __toku_lt_selfread(toku_lock_tree* tree, DB_TXN* txn, ...@@ -221,20 +201,52 @@ static int __toku_lt_selfread(toku_lock_tree* tree, DB_TXN* txn,
int r; int r;
assert(tree && txn && pselfread); assert(tree && txn && pselfread);
//TODO: Remove this, and use multiples per transaction toku_rt_forest* forest = toku_rth_find(tree->rth, txn);
if (!tree->selfread) if (!forest) {
{ r = toku_rth_insert(tree->rth, txn);
r = toku_rt_create(&tree->selfread, if (r!=0) return r;
__toku_lt_point_cmp, __toku_lt_txn_cmp, FALSE, forest = toku_rth_find(tree->rth, txn);
tree->malloc, tree->free, tree->realloc); }
if(r!=0) return r; assert(forest);
if (!forest->self_read) {
r = toku_rt_create(&forest->self_read,
__toku_lt_point_cmp, __toku_lt_txn_cmp,
FALSE,
tree->malloc, tree->free, tree->realloc);
if (r!=0) return r;
assert(forest->self_read);
}
*pselfread = forest->self_read;
return 0;
} }
assert(tree->selfread);
*pselfread = tree->selfread;
/* Provides access to a selfwrite tree for a particular transaction.
Creates it if it does not exist. */
static int __toku_lt_selfwrite(toku_lock_tree* tree, DB_TXN* txn,
toku_range_tree** pselfwrite) {
int r;
assert(tree && txn && pselfwrite);
toku_rt_forest* forest = toku_rth_find(tree->rth, txn);
if (!forest) {
r = toku_rth_insert(tree->rth, txn);
if (r!=0) return r;
forest = toku_rth_find(tree->rth, txn);
}
assert(forest);
if (!forest->self_write) {
r = toku_rt_create(&forest->self_write,
__toku_lt_point_cmp, __toku_lt_txn_cmp,
FALSE,
tree->malloc, tree->free, tree->realloc);
if (r!=0) return r;
assert(forest->self_write);
}
*pselfwrite = forest->self_write;
return 0; return 0;
} }
/* /*
This function only supports non-overlapping trees. This function only supports non-overlapping trees.
Uses the standard definition of dominated from the design document. Uses the standard definition of dominated from the design document.
...@@ -884,12 +896,13 @@ int toku_lt_create(toku_lock_tree** ptree, DB* db, BOOL duplicates, ...@@ -884,12 +896,13 @@ int toku_lt_create(toku_lock_tree** ptree, DB* db, BOOL duplicates,
user_malloc, user_free, user_realloc); user_malloc, user_free, user_realloc);
if (0) { died3: toku_rt_close(tmp_tree->borderwrite); goto died2; } if (0) { died3: toku_rt_close(tmp_tree->borderwrite); goto died2; }
if (r!=0) goto died2; if (r!=0) goto died2;
r = toku_rth_create(&tmp_tree->rth, user_malloc, user_free, user_realloc);
if (0) { died4: toku_rth_close(tmp_tree->rth); goto died3; }
if (r!=0) goto died3;
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)); user_malloc(tmp_tree->buflen * sizeof(toku_range));
if (!tmp_tree->buf) { r = errno; goto died3; } if (!tmp_tree->buf) { r = errno; goto died4; }
//TODO: Create list of selfreads
//TODO: Create list of selfwrites
*ptree = tmp_tree; *ptree = tmp_tree;
return 0; return 0;
} }
...@@ -902,16 +915,18 @@ int toku_lt_close(toku_lock_tree* tree) { ...@@ -902,16 +915,18 @@ int toku_lt_close(toku_lock_tree* tree) {
if (r!=0) r2 = r; if (r!=0) r2 = r;
r = toku_rt_close(tree->borderwrite); r = toku_rt_close(tree->borderwrite);
if (!r2 && r!=0) r2 = r; if (!r2 && r!=0) r2 = r;
//TODO: Do this to ALLLLLLLL selfread and ALLLLLL selfwrite tables.
/* Free all points referred to in a range tree (and close the tree). */ toku_rth_start_scan(tree->rth);
r = __toku_lt_free_contents(tree, toku_rt_forest* forest;
__toku_lt_ifexist_selfread (tree, (DB_TXN*)1), NULL);
if (!r2 && r!=0) r2 = r; while ((forest = toku_rth_next(tree->rth)) != NULL) {
r= __toku_lt_free_contents( tree, r = __toku_lt_free_contents(tree, forest->self_read, NULL);
__toku_lt_ifexist_selfwrite(tree, (DB_TXN*)1), NULL); if (!r2 && r!=0) r2 = r;
if (!r2 && r!=0) r2 = r; r = __toku_lt_free_contents(tree, forest->self_write, NULL);
//TODO: After freeing the tree, need to remove it from both lists!!! if (!r2 && r!=0) r2 = r;
// One list probably IN the transaction, and one additional one here. }
toku_rth_close(tree->rth);
tree->free(tree->buf); tree->free(tree->buf);
tree->free(tree); tree->free(tree);
return r2; return r2;
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include <db.h> #include <db.h>
#include <brttypes.h> #include <brttypes.h>
#include <rangetree.h> #include <rangetree.h>
#include <rth.h>
/** \brief The lock tree structure */ /** \brief The lock tree structure */
typedef struct { typedef struct {
...@@ -56,10 +57,7 @@ typedef struct { ...@@ -56,10 +57,7 @@ typedef struct {
BOOL duplicates; BOOL duplicates;
toku_range_tree* mainread; /**< See design document */ toku_range_tree* mainread; /**< See design document */
toku_range_tree* borderwrite; /**< See design document */ toku_range_tree* borderwrite; /**< See design document */
//TODO: Remove this tree and have one per transaction. toku_rt_hashtable* rth;
toku_range_tree* selfread;
//TODO: Remove this tree and have one per transaction.
toku_range_tree* selfwrite;
/** A temporary area where we store the results of various find on /** A temporary area where we store the results of various find on
the range trees that this lock tree owns */ the range trees that this lock tree owns */
toku_range* buf; toku_range* buf;
......
...@@ -9,7 +9,13 @@ ...@@ -9,7 +9,13 @@
*/ */
#include "hash_table.h" #include "rth.h"
#include <assert.h>
#include <errno.h>
#include <string.h>
/* TODO: reallocate the hash table if it grows too big. Perhaps, use toku_get_prime in newbrt/primes.c */
const uint32 __toku_rth_init_size = 521;
static uint32 __toku_rth_hash(toku_rt_hashtable* table, DB_TXN* key) { static uint32 __toku_rth_hash(toku_rt_hashtable* table, DB_TXN* key) {
assert(table); assert(table);
...@@ -41,8 +47,8 @@ int toku_rth_create(toku_rt_hashtable** ptable, ...@@ -41,8 +47,8 @@ int toku_rth_create(toku_rt_hashtable** ptable,
toku_rt_forest* toku_rth_find(toku_rt_hashtable* table, DB_TXN* key) { toku_rt_forest* toku_rth_find(toku_rt_hashtable* table, DB_TXN* key) {
assert(table && key); assert(table && key);
uint32 index = __toku_rth_hash(table, key); uint32 index = __toku_rth_hash(table, key);
toku_rt_hash_elt* element = table->table[index]; toku_rth_elt* element = table->table[index];
while (element && element->key != key) element = element->next; while (element && element->key != key) element = element->next;
return element ? &element->value : NULL; return element ? &element->value : NULL;
} }
...@@ -53,8 +59,8 @@ void toku_rth_start_scan(toku_rt_hashtable* table) { ...@@ -53,8 +59,8 @@ void toku_rth_start_scan(toku_rt_hashtable* table) {
table->finger_ptr = NULL; table->finger_ptr = NULL;
} }
toku_rt_forest* toku_rth_next(toku_rt_hashtable* table) { toku_rth_elt* __toku_rth_next(toku_rt_hashtable* table) {
assert(table && value && found); assert(table);
if (table->finger_ptr) table->finger_ptr = table->finger_ptr->next; if (table->finger_ptr) table->finger_ptr = table->finger_ptr->next;
while (!table->finger_ptr && table->finger_index < table->array_size) { while (!table->finger_ptr && table->finger_index < table->array_size) {
table->finger_ptr = table->table[++table->finger_index]; table->finger_ptr = table->table[++table->finger_index];
...@@ -62,13 +68,19 @@ toku_rt_forest* toku_rth_next(toku_rt_hashtable* table) { ...@@ -62,13 +68,19 @@ toku_rt_forest* toku_rth_next(toku_rt_hashtable* table) {
return table->finger_ptr; return table->finger_ptr;
} }
toku_rt_forest* toku_rth_next(toku_rt_hashtable* table) {
assert(table);
toku_rth_elt* next = __toku_rth_next(table);
return next ? &next->value : NULL;
}
int toku_rth_delete(toku_rt_hashtable* table, DB_TXN* key) { int toku_rth_delete(toku_rt_hashtable* table, DB_TXN* key) {
assert(table && key); assert(table && key);
/* No elements. */ /* No elements. */
if (!table->num_keys) return EDOM; if (!table->num_keys) return EDOM;
uint32 index = __toku_rth_hash(table, key); uint32 index = __toku_rth_hash(table, key);
toku_rt_hash_elt* element = table->table[index]; toku_rth_elt* element = table->table[index];
/* No elements of the right hash. */ /* No elements of the right hash. */
if (!element) return EDOM; if (!element) return EDOM;
...@@ -77,7 +89,7 @@ int toku_rth_delete(toku_rt_hashtable* table, DB_TXN* key) { ...@@ -77,7 +89,7 @@ int toku_rth_delete(toku_rt_hashtable* table, DB_TXN* key) {
table->table[index] = element->next; table->table[index] = element->next;
goto recycle; goto recycle;
} }
toku_rt_hash_elt* prev; toku_rth_elt* prev;
/* Case where it is not the first element. */ /* Case where it is not the first element. */
do { do {
prev = element; prev = element;
...@@ -96,14 +108,14 @@ int toku_rth_delete(toku_rt_hashtable* table, DB_TXN* key) { ...@@ -96,14 +108,14 @@ int toku_rth_delete(toku_rt_hashtable* table, DB_TXN* key) {
} }
void toku_rth_close(toku_rt_hashtable* table) { void toku_rth_close(toku_rt_hashtable* table) {
toku_rt_hash_elt* element; toku_rth_elt* element;
toku_rt_hash_elt* next = NULL; toku_rth_elt* next = NULL;
toku_rth_start_scan(table); toku_rth_start_scan(table);
next = toku_rth_next(table); next = __toku_rth_next(table);
while (next) { while (next) {
element = next; element = next;
next = toku_rth_next(table); next = __toku_rth_next(table);
table->free(element); table->free(element);
} }
...@@ -119,27 +131,26 @@ void toku_rth_close(toku_rt_hashtable* table) { ...@@ -119,27 +131,26 @@ void toku_rth_close(toku_rt_hashtable* table) {
} }
/* Will allow you to insert it over and over. You need to keep track. */ /* 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, int toku_rth_insert(toku_rt_hashtable* table, DB_TXN* key) {
toku_rt_forsest* value) { assert(table && key);
assert(table && key && value);
uint32 index = __toku_rth_hash(table, key); uint32 index = __toku_rth_hash(table, key);
toku_rt_hash_elt* next = table->table[index];
/* Recycle */ /* Recycle */
toku_rt_hash_elt* element; toku_rth_elt* element;
if (table->free_list) { if (table->free_list) {
element = table->free_list; element = table->free_list;
table->free_list = table->free_list->next; table->free_list = table->free_list->next;
} }
else { else {
/* Allocate a new one. */ /* Allocate a new one. */
element = (toku_rt_hash_elt*)table->malloc(sizeof(*element)); element = (toku_rth_elt*)table->malloc(sizeof(*element));
if (!element) return errno; if (!element) return errno;
} }
element->next = table->table[index]; memset(&element->value, 0, sizeof(toku_rt_forest));
table->table[index]->next = element; element->key = key;
element->next = table->table[index];
table->table[index] = element;
table->num_keys++; table->num_keys++;
return 0; return 0;
} }
\ No newline at end of file
...@@ -10,33 +10,27 @@ ...@@ -10,33 +10,27 @@
*/ */
//Defines BOOL data type. //Defines BOOL data type.
#include <db.h>
#include <brttypes.h> #include <brttypes.h>
#include <rangetree.h>
typedef u_int32_t uint32; typedef u_int32_t uint32;
/* TODO: reallocate the hash table if it grows too big. Perhaps, use toku_get_prime in newbrt/primes.c */
const uint32 __toku_rth_init_size = 521;
typedef struct __toku_rt_forest toku_rt_forest; typedef struct __toku_rt_forest toku_rt_forest;
struct __toku_rt_forest { struct __toku_rt_forest {
toku_range_tree* selfread; toku_range_tree* self_read;
toku_range_tree* selfwrite; toku_range_tree* self_write;
}; };
typedef struct __toku_rth_elt toku_rth_elt; typedef struct __toku_rth_elt toku_rth_elt;
struct __toku_rth_elt { struct __toku_rth_elt {
DB_TXN* key; DB_TXN* key;
toku_range_forest value; toku_rt_forest value;
toku_rth_elt* next; toku_rth_elt* next;
}; };
typedef struct { typedef struct __toku_rt_hashtable toku_rt_hashtable;
uint32 index; struct __toku_rt_hashtable {
toku_rth_elt* next;
} toku_rth_finger;
typedef struct __toku_rt_hash_elt toku_rt_hash_elt;
struct toku_rt_hashtable {
toku_rth_elt** table; toku_rth_elt** table;
uint32 num_keys; uint32 num_keys;
uint32 array_size; uint32 array_size;
...@@ -56,8 +50,8 @@ int toku_rth_create(toku_rt_hashtable** ptable, ...@@ -56,8 +50,8 @@ int toku_rth_create(toku_rt_hashtable** ptable,
void (*user_free) (void*), void (*user_free) (void*),
void* (*user_realloc)(void*, size_t)); void* (*user_realloc)(void*, size_t));
void toku_rth_find(toku_rt_hashtable* table, DB_TXN* key, toku_rt_forest* value, toku_rt_forest* toku_rth_find(toku_rt_hashtable* table, DB_TXN* key);
BOOL* found);
void toku_rth_start_scan(toku_rt_hashtable* table); void toku_rth_start_scan(toku_rt_hashtable* table);
toku_rt_forest* toku_rth_next(toku_rt_hashtable* table); toku_rt_forest* toku_rth_next(toku_rt_hashtable* table);
...@@ -66,5 +60,4 @@ int toku_rth_delete(toku_rt_hashtable* table, DB_TXN* key); ...@@ -66,5 +60,4 @@ int toku_rth_delete(toku_rt_hashtable* table, DB_TXN* key);
void toku_rth_close(toku_rt_hashtable* table); void toku_rth_close(toku_rt_hashtable* table);
int toku_rth_insert(toku_rt_hashtable* table, DB_TXN* key, int toku_rth_insert(toku_rt_hashtable* table, DB_TXN* key);
toku_rt_forsest* value);
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
#ident "The technology is licensed by the Massachusetts Institute of Technology, Rutgers State University of New Jersey, and the Research Foundation of State University of New York at Stony Brook under United States of America Serial No. 11/760379 and to the patents and/or patent applications resulting from it." #ident "The technology is licensed by the Massachusetts Institute of Technology, Rutgers State University of New Jersey, and the Research Foundation of State University of New York at Stony Brook under United States of America Serial No. 11/760379 and to the patents and/or patent applications resulting from it."
#if !defined(TOKU_RANGE_TREE_H)
#define TOKU_RANGE_TREE_H
/** /**
\file rangetree.h \file rangetree.h
\brief Range trees: header and comments \brief Range trees: header and comments
...@@ -223,3 +225,4 @@ int toku_rt_predecessor(toku_range_tree* tree, void* point, toku_range* pred, ...@@ -223,3 +225,4 @@ int toku_rt_predecessor(toku_range_tree* tree, void* point, toku_range* pred,
*/ */
int toku_rt_successor(toku_range_tree* tree, void* point, toku_range* succ, int toku_rt_successor(toku_range_tree* tree, void* point, toku_range* succ,
BOOL* wasfound); BOOL* wasfound);
#endif /* #if !defined(TOKU_RANGE_TREE_H) */
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