Commit 8ae9b13b authored by Bradley C. Kuszmaul's avatar Bradley C. Kuszmaul

Use fewer mallocs in the hash table

git-svn-id: file:///svn/tokudb@127 c7de825b-a66e-492c-adef-691d508d4ae1
parent 701339ea
...@@ -31,7 +31,7 @@ static void hash_find_internal (HASHTABLE tab, unsigned int hash, const unsigned ...@@ -31,7 +31,7 @@ static void hash_find_internal (HASHTABLE tab, unsigned int hash, const unsigned
HASHELT he; HASHELT he;
HASHELT *prev = &tab->array[h]; HASHELT *prev = &tab->array[h];
for (he=*prev; he; prev=&he->next, he=*prev) { for (he=*prev; he; prev=&he->next, he=*prev) {
if (keylen==he->keylen && memcmp(key, he->key, keylen)==0) { if (keylen==he->keylen && memcmp(key, he->keyval, keylen)==0) {
*prev_ptr = prev; *prev_ptr = prev;
*hashelt = he; *hashelt = he;
return; return;
...@@ -47,7 +47,7 @@ int toku_hash_find (HASHTABLE tab, bytevec key, ITEMLEN keylen, bytevec *data, I ...@@ -47,7 +47,7 @@ int toku_hash_find (HASHTABLE tab, bytevec key, ITEMLEN keylen, bytevec *data, I
if (he==0) { if (he==0) {
return -1; return -1;
} else { } else {
*data = he->val; *data = &he->keyval[he->keylen];
*datalen = he->vallen; *datalen = he->vallen;
return 0; return 0;
} }
...@@ -90,11 +90,13 @@ int toku_hash_insert (HASHTABLE tab, const void *key, ITEMLEN keylen, const void ...@@ -90,11 +90,13 @@ int toku_hash_insert (HASHTABLE tab, const void *key, ITEMLEN keylen, const void
} }
{ {
/* Otherwise the key is not already present, so we need to add it. */ /* Otherwise the key is not already present, so we need to add it. */
HASHELT MALLOC(he); HASHELT he=toku_malloc(sizeof(*he)+keylen+vallen);
he->key = memdup(key, keylen); assert(he); // ?????
he->keylen = keylen; he->keylen = keylen;
he->val = memdup(val, vallen);
he->vallen = vallen; he->vallen = vallen;
memmove(&he->keyval[0], key, keylen);
memmove(&he->keyval[keylen], val, vallen);
he->hash = hk; he->hash = hk;
he->next = tab->array[h]; he->next = tab->array[h];
tab->array[h]=he; tab->array[h]=he;
...@@ -116,9 +118,7 @@ int toku_hash_delete (HASHTABLE tab, const void *key, ITEMLEN keylen) { ...@@ -116,9 +118,7 @@ int toku_hash_delete (HASHTABLE tab, const void *key, ITEMLEN keylen) {
assert(*prev_ptr==he); assert(*prev_ptr==he);
*prev_ptr = he->next; *prev_ptr = he->next;
//printf("Freeing %s %s\n", he->key, he->val); //printf("Freeing %s %s\n", he->key, he->val);
toku_free_n(he->key, he->keylen); toku_free_n(he, sizeof(*he)+he->keylen+he->vallen);
toku_free_n(he->val, he->vallen);
toku_free_n(he, sizeof(*he));
tab->n_keys--; tab->n_keys--;
if ((tab->n_keys * 4 < tab->arraysize) && tab->arraysize>4) { if ((tab->n_keys * 4 < tab->arraysize) && tab->arraysize>4) {
...@@ -136,9 +136,9 @@ int toku_hashtable_random_pick(HASHTABLE h, bytevec *key, ITEMLEN *keylen, bytev ...@@ -136,9 +136,9 @@ int toku_hashtable_random_pick(HASHTABLE h, bytevec *key, ITEMLEN *keylen, bytev
if (usei>=h->arraysize) usei=0; if (usei>=h->arraysize) usei=0;
HASHELT he=h->array[usei]; HASHELT he=h->array[usei];
if (he) { if (he) {
*key = he->key; *key = &he->keyval[0];
*keylen = he->keylen; *keylen = he->keylen;
*data = he->val; *data = &he->keyval[he->keylen];
*datalen = he->vallen; *datalen = he->vallen;
return 0; return 0;
} }
...@@ -193,9 +193,7 @@ static void hasheltlist_free (HASHELT elt) { ...@@ -193,9 +193,7 @@ static void hasheltlist_free (HASHELT elt) {
if (elt==0) return; if (elt==0) return;
else { else {
hasheltlist_free(elt->next); hasheltlist_free(elt->next);
toku_free_n(elt->key, elt->keylen); toku_free_n(elt, sizeof(*elt)+elt->keylen+elt->vallen);
toku_free_n(elt->val, elt->vallen);
toku_free_n(elt, sizeof(*elt));
} }
} }
......
...@@ -29,10 +29,11 @@ int toku_hashtable_random_pick(HASHTABLE h, bytevec *key, ITEMLEN *keylen, bytev ...@@ -29,10 +29,11 @@ int toku_hashtable_random_pick(HASHTABLE h, bytevec *key, ITEMLEN *keylen, bytev
typedef struct hashelt *HASHELT; typedef struct hashelt *HASHELT;
struct hashelt { struct hashelt {
char *key; ITEMLEN keylen; /* key is NULL for empty elements */ ITEMLEN keylen;
char *val; ITEMLEN vallen; ITEMLEN vallen;
unsigned int hash; unsigned int hash;
HASHELT next; HASHELT next;
char keyval[]; /* the first KEYLEN bytes are the key. The next bytes are the value. */
}; };
struct hashtable { struct hashtable {
...@@ -50,9 +51,9 @@ void toku_hashtable_iterate (HASHTABLE tab, void(*f)(bytevec key,ITEMLEN keylen, ...@@ -50,9 +51,9 @@ void toku_hashtable_iterate (HASHTABLE tab, void(*f)(bytevec key,ITEMLEN keylen,
for (hi_counter=0; hi_counter<table->arraysize; hi_counter++) { \ for (hi_counter=0; hi_counter<table->arraysize; hi_counter++) { \
HASHELT hi_he; \ HASHELT hi_he; \
for (hi_he=table->array[hi_counter]; hi_he; hi_he=hi_he->next) { \ for (hi_he=table->array[hi_counter]; hi_he; hi_he=hi_he->next) { \
const char *keyvar = hi_he->key; \ const char *keyvar = &hi_he->keyval[0]; \
ITEMLEN keylenvar = hi_he->keylen; \ ITEMLEN keylenvar = hi_he->keylen; \
const char *datavar = hi_he->val; \ const char *datavar = &hi_he->keyval[hi_he->keylen]; \
ITEMLEN datalenvar = hi_he->vallen; \ ITEMLEN datalenvar = hi_he->vallen; \
body; \ body; \
}}}) }}})
......
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