1b7579f77SDag-Erling Smørgrav /* 2b7579f77SDag-Erling Smørgrav * util/storage/slabhash.h - hashtable consisting of several smaller tables. 3b7579f77SDag-Erling Smørgrav * 4b7579f77SDag-Erling Smørgrav * Copyright (c) 2007, NLnet Labs. All rights reserved. 5b7579f77SDag-Erling Smørgrav * 6b7579f77SDag-Erling Smørgrav * This software is open source. 7b7579f77SDag-Erling Smørgrav * 8b7579f77SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 9b7579f77SDag-Erling Smørgrav * modification, are permitted provided that the following conditions 10b7579f77SDag-Erling Smørgrav * are met: 11b7579f77SDag-Erling Smørgrav * 12b7579f77SDag-Erling Smørgrav * Redistributions of source code must retain the above copyright notice, 13b7579f77SDag-Erling Smørgrav * this list of conditions and the following disclaimer. 14b7579f77SDag-Erling Smørgrav * 15b7579f77SDag-Erling Smørgrav * Redistributions in binary form must reproduce the above copyright notice, 16b7579f77SDag-Erling Smørgrav * this list of conditions and the following disclaimer in the documentation 17b7579f77SDag-Erling Smørgrav * and/or other materials provided with the distribution. 18b7579f77SDag-Erling Smørgrav * 19b7579f77SDag-Erling Smørgrav * Neither the name of the NLNET LABS nor the names of its contributors may 20b7579f77SDag-Erling Smørgrav * be used to endorse or promote products derived from this software without 21b7579f77SDag-Erling Smørgrav * specific prior written permission. 22b7579f77SDag-Erling Smørgrav * 23b7579f77SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2417d15b25SDag-Erling Smørgrav * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2517d15b25SDag-Erling Smørgrav * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2617d15b25SDag-Erling Smørgrav * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2717d15b25SDag-Erling Smørgrav * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2817d15b25SDag-Erling Smørgrav * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 2917d15b25SDag-Erling Smørgrav * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 3017d15b25SDag-Erling Smørgrav * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3117d15b25SDag-Erling Smørgrav * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3217d15b25SDag-Erling Smørgrav * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3317d15b25SDag-Erling Smørgrav * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34b7579f77SDag-Erling Smørgrav */ 35b7579f77SDag-Erling Smørgrav 36b7579f77SDag-Erling Smørgrav /** 37b7579f77SDag-Erling Smørgrav * \file 38b7579f77SDag-Erling Smørgrav * 39b7579f77SDag-Erling Smørgrav * Hash table that consists of smaller hash tables. 40b7579f77SDag-Erling Smørgrav * It cannot grow, but that gives it the ability to have multiple 41b7579f77SDag-Erling Smørgrav * locks. Also this means there are multiple LRU lists. 42b7579f77SDag-Erling Smørgrav */ 43b7579f77SDag-Erling Smørgrav 44b7579f77SDag-Erling Smørgrav #ifndef UTIL_STORAGE_SLABHASH_H 45b7579f77SDag-Erling Smørgrav #define UTIL_STORAGE_SLABHASH_H 46b7579f77SDag-Erling Smørgrav #include "util/storage/lruhash.h" 47b7579f77SDag-Erling Smørgrav 48b7579f77SDag-Erling Smørgrav /** default number of slabs */ 49b7579f77SDag-Erling Smørgrav #define HASH_DEFAULT_SLABS 4 50b7579f77SDag-Erling Smørgrav 51b7579f77SDag-Erling Smørgrav /** 52b7579f77SDag-Erling Smørgrav * Hash table formed from several smaller ones. 53b7579f77SDag-Erling Smørgrav * This results in a partitioned lruhash table, a 'slashtable'. 54b7579f77SDag-Erling Smørgrav * None of the data inside the slabhash may be altered. 55b7579f77SDag-Erling Smørgrav * Therefore, no locks are needed to access the structure. 56b7579f77SDag-Erling Smørgrav */ 57b7579f77SDag-Erling Smørgrav struct slabhash { 58b7579f77SDag-Erling Smørgrav /** the size of the array - must be power of 2 */ 59b7579f77SDag-Erling Smørgrav size_t size; 60b7579f77SDag-Erling Smørgrav /** size bitmask - uses high bits. */ 61b7579f77SDag-Erling Smørgrav uint32_t mask; 62b7579f77SDag-Erling Smørgrav /** shift right this many bits to get index into array. */ 63b7579f77SDag-Erling Smørgrav unsigned int shift; 64b7579f77SDag-Erling Smørgrav /** lookup array of hash tables */ 65b7579f77SDag-Erling Smørgrav struct lruhash** array; 66b7579f77SDag-Erling Smørgrav }; 67b7579f77SDag-Erling Smørgrav 68b7579f77SDag-Erling Smørgrav /** 69b7579f77SDag-Erling Smørgrav * Create new slabbed hash table. 70b7579f77SDag-Erling Smørgrav * @param numtables: number of hash tables to use, other parameters used to 71b7579f77SDag-Erling Smørgrav * initialize these smaller hashtables. 72b7579f77SDag-Erling Smørgrav * @param start_size: size of hashtable array at start, must be power of 2. 73b7579f77SDag-Erling Smørgrav * @param maxmem: maximum amount of memory this table is allowed to use. 74b7579f77SDag-Erling Smørgrav * so every table gets maxmem/numtables to use for itself. 75b7579f77SDag-Erling Smørgrav * @param sizefunc: calculates memory usage of entries. 76b7579f77SDag-Erling Smørgrav * @param compfunc: compares entries, 0 on equality. 77b7579f77SDag-Erling Smørgrav * @param delkeyfunc: deletes key. 78b7579f77SDag-Erling Smørgrav * @param deldatafunc: deletes data. 79b7579f77SDag-Erling Smørgrav * @param arg: user argument that is passed to user function calls. 80b7579f77SDag-Erling Smørgrav * @return: new hash table or NULL on malloc failure. 81b7579f77SDag-Erling Smørgrav */ 82b7579f77SDag-Erling Smørgrav struct slabhash* slabhash_create(size_t numtables, size_t start_size, 833005e0a3SDag-Erling Smørgrav size_t maxmem, lruhash_sizefunc_type sizefunc, 843005e0a3SDag-Erling Smørgrav lruhash_compfunc_type compfunc, lruhash_delkeyfunc_type delkeyfunc, 853005e0a3SDag-Erling Smørgrav lruhash_deldatafunc_type deldatafunc, void* arg); 86b7579f77SDag-Erling Smørgrav 87b7579f77SDag-Erling Smørgrav /** 88b7579f77SDag-Erling Smørgrav * Delete hash table. Entries are all deleted. 89b7579f77SDag-Erling Smørgrav * @param table: to delete. 90b7579f77SDag-Erling Smørgrav */ 91b7579f77SDag-Erling Smørgrav void slabhash_delete(struct slabhash* table); 92b7579f77SDag-Erling Smørgrav 93b7579f77SDag-Erling Smørgrav /** 94b7579f77SDag-Erling Smørgrav * Clear hash table. Entries are all deleted. 95b7579f77SDag-Erling Smørgrav * @param table: to make empty. 96b7579f77SDag-Erling Smørgrav */ 97b7579f77SDag-Erling Smørgrav void slabhash_clear(struct slabhash* table); 98b7579f77SDag-Erling Smørgrav 99b7579f77SDag-Erling Smørgrav /** 100b7579f77SDag-Erling Smørgrav * Insert a new element into the hashtable, uses lruhash_insert. 101b7579f77SDag-Erling Smørgrav * If key is already present data pointer in that entry is updated. 102b7579f77SDag-Erling Smørgrav * 103b7579f77SDag-Erling Smørgrav * @param table: hash table. 104b7579f77SDag-Erling Smørgrav * @param hash: hash value. User calculates the hash. 105b7579f77SDag-Erling Smørgrav * @param entry: identifies the entry. 106b7579f77SDag-Erling Smørgrav * If key already present, this entry->key is deleted immediately. 107b7579f77SDag-Erling Smørgrav * But entry->data is set to NULL before deletion, and put into 108b7579f77SDag-Erling Smørgrav * the existing entry. The data is then freed. 109b7579f77SDag-Erling Smørgrav * @param data: the data. 1108a384985SDag-Erling Smørgrav * @param cb_override: if not NULL overrides the cb_arg for deletefunc. 111b7579f77SDag-Erling Smørgrav */ 1123005e0a3SDag-Erling Smørgrav void slabhash_insert(struct slabhash* table, hashvalue_type hash, 113b7579f77SDag-Erling Smørgrav struct lruhash_entry* entry, void* data, void* cb_override); 114b7579f77SDag-Erling Smørgrav 115b7579f77SDag-Erling Smørgrav /** 116b7579f77SDag-Erling Smørgrav * Lookup an entry in the hashtable. Uses lruhash_lookup. 117b7579f77SDag-Erling Smørgrav * At the end of the function you hold a (read/write)lock on the entry. 118b7579f77SDag-Erling Smørgrav * The LRU is updated for the entry (if found). 119b7579f77SDag-Erling Smørgrav * @param table: hash table. 120b7579f77SDag-Erling Smørgrav * @param hash: hash of key. 121b7579f77SDag-Erling Smørgrav * @param key: what to look for, compared against entries in overflow chain. 122b7579f77SDag-Erling Smørgrav * the hash value must be set, and must work with compare function. 123b7579f77SDag-Erling Smørgrav * @param wr: set to true if you desire a writelock on the entry. 124b7579f77SDag-Erling Smørgrav * with a writelock you can update the data part. 125b7579f77SDag-Erling Smørgrav * @return: pointer to the entry or NULL. The entry is locked. 126b7579f77SDag-Erling Smørgrav * The user must unlock the entry when done. 127b7579f77SDag-Erling Smørgrav */ 128b7579f77SDag-Erling Smørgrav struct lruhash_entry* slabhash_lookup(struct slabhash* table, 1293005e0a3SDag-Erling Smørgrav hashvalue_type hash, void* key, int wr); 130b7579f77SDag-Erling Smørgrav 131b7579f77SDag-Erling Smørgrav /** 132b7579f77SDag-Erling Smørgrav * Remove entry from hashtable. Does nothing if not found in hashtable. 133b7579f77SDag-Erling Smørgrav * Delfunc is called for the entry. Uses lruhash_remove. 134b7579f77SDag-Erling Smørgrav * @param table: hash table. 135b7579f77SDag-Erling Smørgrav * @param hash: hash of key. 136b7579f77SDag-Erling Smørgrav * @param key: what to look for. 137b7579f77SDag-Erling Smørgrav */ 1383005e0a3SDag-Erling Smørgrav void slabhash_remove(struct slabhash* table, hashvalue_type hash, void* key); 139b7579f77SDag-Erling Smørgrav 140b7579f77SDag-Erling Smørgrav /** 141b7579f77SDag-Erling Smørgrav * Output debug info to the log as to state of the hash table. 142b7579f77SDag-Erling Smørgrav * @param table: hash table. 143b7579f77SDag-Erling Smørgrav * @param id: string printed with table to identify the hash table. 144b7579f77SDag-Erling Smørgrav * @param extended: set to true to print statistics on overflow bin lengths. 145b7579f77SDag-Erling Smørgrav */ 146b7579f77SDag-Erling Smørgrav void slabhash_status(struct slabhash* table, const char* id, int extended); 147b7579f77SDag-Erling Smørgrav 148b7579f77SDag-Erling Smørgrav /** 149b7579f77SDag-Erling Smørgrav * Retrieve slab hash total size. 150b7579f77SDag-Erling Smørgrav * @param table: hash table. 151b7579f77SDag-Erling Smørgrav * @return size configured as max. 152b7579f77SDag-Erling Smørgrav */ 153b7579f77SDag-Erling Smørgrav size_t slabhash_get_size(struct slabhash* table); 154b7579f77SDag-Erling Smørgrav 155b7579f77SDag-Erling Smørgrav /** 1564c75e3aaSDag-Erling Smørgrav * See if slabhash is of given (size, slabs) configuration. 1574c75e3aaSDag-Erling Smørgrav * @param table: hash table 1584c75e3aaSDag-Erling Smørgrav * @param size: max size to test for 1594c75e3aaSDag-Erling Smørgrav * @param slabs: slab count to test for. 1604c75e3aaSDag-Erling Smørgrav * @return true if equal 1614c75e3aaSDag-Erling Smørgrav */ 1624c75e3aaSDag-Erling Smørgrav int slabhash_is_size(struct slabhash* table, size_t size, size_t slabs); 1634c75e3aaSDag-Erling Smørgrav 1644c75e3aaSDag-Erling Smørgrav /** 165335c7cdaSCy Schubert * Update the size of an element in the hashtable, uses 166335c7cdaSCy Schubert * lruhash_update_space_used. 167335c7cdaSCy Schubert * 168335c7cdaSCy Schubert * @param table: hash table. 169335c7cdaSCy Schubert * @param hash: hash value. User calculates the hash. 170335c7cdaSCy Schubert * @param cb_override: if not NULL overrides the cb_arg for deletefunc. 171335c7cdaSCy Schubert * @param diff_size: difference in size to the hash table storage. 172335c7cdaSCy Schubert */ 173335c7cdaSCy Schubert void slabhash_update_space_used(struct slabhash* table, hashvalue_type hash, 174335c7cdaSCy Schubert void* cb_override, int diff_size); 175335c7cdaSCy Schubert 176335c7cdaSCy Schubert /** 177b7579f77SDag-Erling Smørgrav * Retrieve slab hash current memory use. 178b7579f77SDag-Erling Smørgrav * @param table: hash table. 179b7579f77SDag-Erling Smørgrav * @return memory in use. 180b7579f77SDag-Erling Smørgrav */ 181b7579f77SDag-Erling Smørgrav size_t slabhash_get_mem(struct slabhash* table); 182b7579f77SDag-Erling Smørgrav 183b7579f77SDag-Erling Smørgrav /** 184b7579f77SDag-Erling Smørgrav * Get lruhash table for a given hash value 185b7579f77SDag-Erling Smørgrav * @param table: slabbed hash table. 186b7579f77SDag-Erling Smørgrav * @param hash: hash value. 187b7579f77SDag-Erling Smørgrav * @return the lru hash table. 188b7579f77SDag-Erling Smørgrav */ 1893005e0a3SDag-Erling Smørgrav struct lruhash* slabhash_gettable(struct slabhash* table, hashvalue_type hash); 190b7579f77SDag-Erling Smørgrav 191b7579f77SDag-Erling Smørgrav /** 192b7579f77SDag-Erling Smørgrav * Set markdel function 193b7579f77SDag-Erling Smørgrav * @param table: slabbed hash table. 194b7579f77SDag-Erling Smørgrav * @param md: markdel function ptr. 195b7579f77SDag-Erling Smørgrav */ 1963005e0a3SDag-Erling Smørgrav void slabhash_setmarkdel(struct slabhash* table, lruhash_markdelfunc_type md); 197b7579f77SDag-Erling Smørgrav 198b7579f77SDag-Erling Smørgrav /** 199b7579f77SDag-Erling Smørgrav * Traverse a slabhash. 200b7579f77SDag-Erling Smørgrav * @param table: slabbed hash table. 201b7579f77SDag-Erling Smørgrav * @param wr: if true, writelock is obtained, otherwise readlock. 202b7579f77SDag-Erling Smørgrav * @param func: function to call for every element. 203b7579f77SDag-Erling Smørgrav * @param arg: user argument to function. 204b7579f77SDag-Erling Smørgrav */ 205b7579f77SDag-Erling Smørgrav void slabhash_traverse(struct slabhash* table, int wr, 206b7579f77SDag-Erling Smørgrav void (*func)(struct lruhash_entry*, void*), void* arg); 207b7579f77SDag-Erling Smørgrav 208ff825849SDag-Erling Smørgrav /* 209ff825849SDag-Erling Smørgrav * Count entries in slabhash. 210ff825849SDag-Erling Smørgrav * @param table: slabbed hash table; 211ff825849SDag-Erling Smørgrav * @return the number of items 212ff825849SDag-Erling Smørgrav */ 213ff825849SDag-Erling Smørgrav size_t count_slabhash_entries(struct slabhash* table); 214ff825849SDag-Erling Smørgrav 2158f76bb7dSCy Schubert /** 2168f76bb7dSCy Schubert * Retrieves number of items in slabhash and the current max collision level 2178f76bb7dSCy Schubert * @param table: slabbed hash table. 2188f76bb7dSCy Schubert * @param entries_count: where to save the current number of elements. 2198f76bb7dSCy Schubert * @param max_collisions: where to save the current max collisions level. 2208f76bb7dSCy Schubert */ 2218f76bb7dSCy Schubert void get_slabhash_stats(struct slabhash* table, 2228f76bb7dSCy Schubert long long* entries_count, long long* max_collisions); 2238f76bb7dSCy Schubert 224*be771a7bSCy Schubert /** 225*be771a7bSCy Schubert * Adjust size of slabhash memory max 226*be771a7bSCy Schubert * @param table: slabbed hash table 227*be771a7bSCy Schubert * @param max: new max memory 228*be771a7bSCy Schubert */ 229*be771a7bSCy Schubert void slabhash_adjust_size(struct slabhash* table, size_t max); 230*be771a7bSCy Schubert 231b7579f77SDag-Erling Smørgrav /* --- test representation --- */ 232b7579f77SDag-Erling Smørgrav /** test structure contains test key */ 233b7579f77SDag-Erling Smørgrav struct slabhash_testkey { 234b7579f77SDag-Erling Smørgrav /** the key id */ 235b7579f77SDag-Erling Smørgrav int id; 236b7579f77SDag-Erling Smørgrav /** the entry */ 237b7579f77SDag-Erling Smørgrav struct lruhash_entry entry; 238b7579f77SDag-Erling Smørgrav }; 239b7579f77SDag-Erling Smørgrav /** test structure contains test data */ 240b7579f77SDag-Erling Smørgrav struct slabhash_testdata { 241b7579f77SDag-Erling Smørgrav /** data value */ 242b7579f77SDag-Erling Smørgrav int data; 243b7579f77SDag-Erling Smørgrav }; 244b7579f77SDag-Erling Smørgrav 245b7579f77SDag-Erling Smørgrav /** test sizefunc for lruhash */ 246b7579f77SDag-Erling Smørgrav size_t test_slabhash_sizefunc(void*, void*); 247b7579f77SDag-Erling Smørgrav /** test comparefunc for lruhash */ 248b7579f77SDag-Erling Smørgrav int test_slabhash_compfunc(void*, void*); 249b7579f77SDag-Erling Smørgrav /** test delkey for lruhash */ 250b7579f77SDag-Erling Smørgrav void test_slabhash_delkey(void*, void*); 251b7579f77SDag-Erling Smørgrav /** test deldata for lruhash */ 252b7579f77SDag-Erling Smørgrav void test_slabhash_deldata(void*, void*); 253b7579f77SDag-Erling Smørgrav /* --- end test representation --- */ 254b7579f77SDag-Erling Smørgrav 255b7579f77SDag-Erling Smørgrav #endif /* UTIL_STORAGE_SLABHASH_H */ 256