/* A cuckoo hash implementation Copyright (C) 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef CUCKOO_H #define CUCKOO_H /** * @file * Cuckoo hashing * This hashing gives guaranteed O(1) lookup complexity and amortized O(1) insert and remove complexity. * Hash tables by default grow and shrink automatically. It is posible to preallocate entries and turn * automatic shrinking off taking out the memory management factors for insert and remove operations. * This implementation uses 3 Tables which exponential growing sizes. */ #include #include struct cuckoo_struct; typedef struct cuckoo_struct * Cuckoo; /** * Hash function. * User supplied universal hash function * @param item address of the item to be hashed * @param r pseudo random number, 31 significant bits, regenerated on each rehash * @return hash value */ typedef size_t (*cuckoo_hashfunc)(const void* item, const uint32_t r); /** * Compare function. * User supplied compare function * @param item1 address of the first item * @param item2 address of the second item * @return 1 when the items are identical, 0 otherwise */ typedef int (*cuckoo_cmpfunc)(const void* item1, const void* item2); /** * Item destructor function. * User supplied destructor function. This function is called when items are removed * from the hash or at hash detroy/delete time. Must be safe to be called on a zeroed element. * @param item address of the item to be destroyed */ typedef void (*cuckoo_dtorfunc)(void* item); /** * Move function. * User supplied item move function * @param dest target address for the move operation * @param src source for the move operation * @param size size of a item (requested size rounded up to the next CUCKOO_GRANULARITY) * It might be necessary to invalidate the source in some case, cuckoo will zero it out * after moving. */ typedef void (*cuckoo_movfunc)(void* dest, void* src, size_t size); /** * Function table used to specialize various funtions used by the hash. * TODO some elements might be NULL, then defaults are used */ struct cuckoo_vtable { cuckoo_hashfunc h1; cuckoo_hashfunc h2; cuckoo_hashfunc h3; cuckoo_cmpfunc cmp; cuckoo_dtorfunc dtor; cuckoo_movfunc mov; }; /** * Initialize a cuckoo hash. * @param self pointer to a uninitialized cuckoo datastructure * @param itemsize size for a single hash entry, will be rounded up to align CUCKOO_GRANULARITY * @param vtable initialized vtable * @return The initialized hashtable or NULL at allocation failure */ Cuckoo cuckoo_init (Cuckoo self, size_t itemsize, struct cuckoo_vtable* vtable); /** * Allocate a new cuckoo hash. * @param itemsize size for a single hash entry, will be rounded up to align CUCKOO_GRANULARITY * @param startsize initial size of table t3, as 2's exponent * @param vtable initialized vtable * @return The initialized hashtable or NULL at allocation failure */ Cuckoo cuckoo_new (size_t itemsize, struct cuckoo_vtable* vtable); /** * Destroy a cuckoo hash. * Frees internal used resources. * @param self cuckoo hash to destroy * @return The now uninitialized hashtable */ Cuckoo cuckoo_destroy (Cuckoo self); /** * Deallocate a cuckoo hash. * @param self handle of the hash table to be freed */ void cuckoo_delete (Cuckoo self); /** * Get the number of elements stored in a hash. * @return number of elements, 0 when empty */ size_t cuckoo_nelements (Cuckoo self); /** * Insert an element into a hash. * amortized O(1) complexity because it may rarely rehash the tables or even grow them. * see cuckoo_reserve() about how to preallocate entries to prevent the growing costs. * Inserting an element already in the hash calls the dtor for the old entry and places * the new one into the hash. * @param self handle to the hash table * @param item pointer to a item to be inserted * @return pointer to inserted element on successful insert, NULL on allocation failure * Note: at failure there is one arbitary hash cell lost! */ void* cuckoo_insert (Cuckoo self, void* item); /** * Find a value by key in a hash. * @param self handle to the hash table * @param item pointer to an item to be looked up * @return found object or NULL if not present */ void* cuckoo_find (Cuckoo self, void* item); /** * Remove a item from a hash. * amortized O(1) complexity when it automatically shrink its tables. * guaranteed O(1) complexity when automatic shrinking is turned off. * see cuckoo_reserve() about how turn automatic shrinking off. * @param self handle to the hash table * @param item pointer to the item to be removed */ void cuckoo_remove (Cuckoo self, void* item); /** * Shrink the hash sizes when possible and turn autocompacting on. * only useful when autmatic shrinking is turned off. * see cuckoo_reserve() about how turn shrinking off. * @param self handle to the hash table */ int cuckoo_compact (Cuckoo self); /** * Prereserve hash entries and turn autocompacting off. * @param self handle to the hash table * @param more number of entries to be additionally reserved * In rare circumstances inserting into a hash which has reserved some entries * it may still need to rehash (or even rarer) to grow the table. * While autocompacting is turned off, removing is completely O(1). */ int cuckoo_reserve (Cuckoo self, size_t more); #endif /* // Local Variables: // mode: C // c-file-style: "gnu" // indent-tabs-mode: nil // End: */