2007-07-13 19:37:47 +00:00
|
|
|
#ifndef HASHTABLE_H
|
|
|
|
#define HASHTABLE_H
|
|
|
|
|
2007-11-29 14:18:54 +00:00
|
|
|
#ident "Copyright (c) 2007 Tokutek Inc. All rights reserved."
|
|
|
|
|
2007-07-13 19:37:47 +00:00
|
|
|
#include "brttypes.h"
|
|
|
|
/* Hash table with chaining. */
|
|
|
|
/* The keys and values are byte sequences. */
|
|
|
|
/* The keys and values are malloc'd by the hashtable. */
|
2007-11-19 00:46:09 +00:00
|
|
|
/* Duplicate keys are allowed by default and are stored in a FIFO list */
|
2007-07-13 19:37:47 +00:00
|
|
|
|
|
|
|
typedef struct hashtable *HASHTABLE;
|
|
|
|
|
2007-07-24 15:08:05 +00:00
|
|
|
int toku_hashtable_create (HASHTABLE*);
|
2007-07-13 19:37:47 +00:00
|
|
|
|
2007-11-19 00:46:09 +00:00
|
|
|
/* Configure the hash table for duplicate keys.
|
|
|
|
allow_dups != 0 -> duplications allowed, allow_dups == 0 -> no duplicates */
|
|
|
|
|
|
|
|
int toku_hashtable_set_dups (HASHTABLE, unsigned int allow_dups);
|
|
|
|
|
2007-07-13 19:37:47 +00:00
|
|
|
/* Return 0 if the key is found in the hashtable, -1 otherwise. */
|
|
|
|
/* Warning: The data returned points to the internals of the hashtable. It is set to "const" to try to prevent you from messing it up. */
|
2007-11-19 16:09:30 +00:00
|
|
|
int toku_hash_find (HASHTABLE tab, bytevec key, ITEMLEN keylen, bytevec *data, ITEMLEN *datalen, int *type);
|
|
|
|
|
|
|
|
/* match on key, index on duplicates */
|
|
|
|
int toku_hash_find_idx (HASHTABLE tab, bytevec key, ITEMLEN keylen, int idx, bytevec *data, ITEMLEN *datalen, int *type);
|
2007-07-13 19:37:47 +00:00
|
|
|
|
2007-11-19 00:46:09 +00:00
|
|
|
/* Insert the key/data pair into the hash table.
|
|
|
|
If the key is not in the hash table then insert it.
|
|
|
|
If the key already exists and duplicates are allowed then append it to the list of duplicates.
|
|
|
|
If the key already exists and duplicates are not allowed then return an error */
|
|
|
|
|
2007-09-06 21:36:45 +00:00
|
|
|
int toku_hash_insert (HASHTABLE tab, const void *key, ITEMLEN keylen, const void *data, ITEMLEN datalen, int type);
|
2007-07-13 19:37:47 +00:00
|
|
|
|
2007-11-19 00:46:09 +00:00
|
|
|
/* Delete the first entry with the given key
|
|
|
|
It is OK to delete something that isn't there. */
|
|
|
|
|
2007-08-13 19:04:38 +00:00
|
|
|
int toku_hash_delete (HASHTABLE tab, const void *key, ITEMLEN keylen);
|
2007-11-19 00:46:09 +00:00
|
|
|
|
|
|
|
/* Delete all entries with the given key */
|
|
|
|
|
|
|
|
int toku_hash_delete_all (HASHTABLE tab, const void *key, ITEMLEN keylen);
|
|
|
|
|
2007-07-24 15:08:05 +00:00
|
|
|
void toku_hashtable_free(HASHTABLE *tab);
|
|
|
|
int toku_hashtable_n_entries(HASHTABLE);
|
2007-07-13 19:37:47 +00:00
|
|
|
|
2007-07-24 15:08:05 +00:00
|
|
|
void toku_hashtable_clear(HASHTABLE);
|
2007-07-13 19:37:47 +00:00
|
|
|
|
2007-09-06 21:36:45 +00:00
|
|
|
int toku_hashtable_random_pick(HASHTABLE h, bytevec *key, ITEMLEN *keylen, bytevec *data, ITEMLEN *datalen, int *type, long int *randomnumber);
|
2007-07-13 19:37:47 +00:00
|
|
|
//int hashtable_find_last(HASHTABLE h, bytevec *key, ITEMLEN *keylen, bytevec *data, ITEMLEN *datalen);
|
|
|
|
|
|
|
|
typedef struct hashelt *HASHELT;
|
|
|
|
struct hashelt {
|
|
|
|
HASHELT next;
|
2007-11-19 00:46:09 +00:00
|
|
|
unsigned int hash;
|
2007-09-06 21:36:45 +00:00
|
|
|
int type;
|
|
|
|
ITEMLEN keylen;
|
|
|
|
ITEMLEN vallen;
|
2007-08-13 22:07:55 +00:00
|
|
|
char keyval[]; /* the first KEYLEN bytes are the key. The next bytes are the value. */
|
2007-07-13 19:37:47 +00:00
|
|
|
};
|
|
|
|
|
2007-11-19 00:46:09 +00:00
|
|
|
struct hashelt_list {
|
|
|
|
HASHELT head;
|
|
|
|
HASHELT tail;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct hashdup *HASHDUP;
|
|
|
|
struct hashdup {
|
|
|
|
HASHDUP next;
|
|
|
|
struct hashelt_list kdlist;
|
|
|
|
};
|
|
|
|
|
2007-07-13 19:37:47 +00:00
|
|
|
struct hashtable {
|
2007-11-19 00:46:09 +00:00
|
|
|
HASHDUP *array;
|
2007-08-13 21:53:19 +00:00
|
|
|
unsigned int n_keys;
|
|
|
|
unsigned int arraysize;
|
|
|
|
unsigned int primeidx;
|
2007-11-19 00:46:09 +00:00
|
|
|
unsigned int allow_dups;
|
2007-07-13 19:37:47 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* You cannot add or delete elements from the hashtable while iterating. */
|
2007-09-06 21:36:45 +00:00
|
|
|
void toku_hashtable_iterate (HASHTABLE tab, void(*f)(bytevec key,ITEMLEN keylen,bytevec data,ITEMLEN datalen,int type, void*), void*);
|
2007-11-19 00:46:09 +00:00
|
|
|
|
2007-07-13 19:37:47 +00:00
|
|
|
// If you don't want to use something, do something like use "key __attribute__((__unused__))" for keyvar.
|
2007-09-06 21:36:45 +00:00
|
|
|
#define HASHTABLE_ITERATE(table,keyvar,keylenvar,datavar,datalenvar,typevar,body) ({ \
|
2007-11-19 00:46:09 +00:00
|
|
|
unsigned int hi_counter; \
|
|
|
|
for (hi_counter=0; hi_counter<table->arraysize; hi_counter++) { \
|
|
|
|
HASHDUP hi_dup; \
|
|
|
|
for (hi_dup=table->array[hi_counter]; hi_dup; hi_dup=hi_dup->next) { \
|
|
|
|
HASHELT hi_he; \
|
|
|
|
for (hi_he=hi_dup->kdlist.head; hi_he; hi_he=hi_he->next) { \
|
|
|
|
const char *keyvar = &hi_he->keyval[0]; \
|
|
|
|
ITEMLEN keylenvar = hi_he->keylen; \
|
|
|
|
const char *datavar = &hi_he->keyval[hi_he->keylen]; \
|
|
|
|
ITEMLEN datalenvar = hi_he->vallen; \
|
|
|
|
int typevar = hi_he->type; \
|
|
|
|
body; \
|
|
|
|
}}}})
|
2007-07-13 19:37:47 +00:00
|
|
|
|
|
|
|
#endif
|