From 02074ab52170ffaab21196cb841bb1cfde4d45ba Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 6 Feb 2011 17:19:35 +0100 Subject: [PATCH] remove uhtbl - i don't think we will need it --- CMakeLists.txt | 2 +- uhtbl.c | 340 -------------------------------------------- uhtbl.h | 375 ------------------------------------------------- 3 files changed, 1 insertion(+), 716 deletions(-) delete mode 100644 uhtbl.c delete mode 100644 uhtbl.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ae4ff17..699ae95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ IF(APPLE) LINK_DIRECTORIES(/opt/local/lib) ENDIF() -SET(SOURCES avl.c blob.c blobmsg.c hash.c uhtbl.c uloop.c usock.c) +SET(SOURCES avl.c blob.c blobmsg.c hash.c uloop.c usock.c) ADD_LIBRARY(ubox SHARED ${SOURCES}) ADD_LIBRARY(blobmsg_json SHARED blobmsg_json.c) diff --git a/uhtbl.c b/uhtbl.c deleted file mode 100644 index 9e119b8..0000000 --- a/uhtbl.c +++ /dev/null @@ -1,340 +0,0 @@ -/** - * uhtbl - Generic coalesced hash table implementation - * Copyright (C) 2010 Steven Barth - * Copyright (C) 2010 John Crispin - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#include -#include -#include -#include "uhtbl.h" - -/* Forward static helpers */ -UHTBL_INLINE uhtbl_size_t _uhtbl_address(uhtbl_t *tbl, uhtbl_bucket_t *bucket); -UHTBL_INLINE uhtbl_bucket_t* _uhtbl_bucket(uhtbl_t *tbl, uhtbl_size_t address); -static uhtbl_bucket_t* _uhtbl_allocate(uhtbl_t *tbl); -static uhtbl_bucket_t* _uhtbl_find(uhtbl_t *tbl, const void *key, -long len, uhtbl_bucket_t **previous, uhtbl_size_t *mainaddress); - - - -UHTBL_API int uhtbl_init(uhtbl_t *tbl, uint32_t bucketsize, -uhtbl_size_t sizehint, uhtbl_hash_t *fct_hash, uhtbl_gc_t *fct_gc) { - sizehint = (sizehint) ? sizehint : UHTBL_MINIMUMSIZE; - tbl->bucketsize = bucketsize; - tbl->fct_hash = fct_hash; - tbl->fct_gc = fct_gc; - if (!tbl->fct_hash || tbl->bucketsize < sizeof(uhtbl_bucket_t)) { - return UHTBL_EINVAL; - } - tbl->payload = 0; - tbl->buckets = NULL; - tbl->used = 0; - - return uhtbl_resize(tbl, sizehint); -} - -UHTBL_API void uhtbl_clear(uhtbl_t *tbl) { - for (uhtbl_size_t i = 0; i < tbl->size; i++) { - uhtbl_bucket_t *bucket = _uhtbl_bucket(tbl, i); - if (tbl->fct_gc && bucket->head.flags & UHTBL_FLAG_OCCUPIED) { - tbl->fct_gc(bucket); - } - bucket->head.flags = 0; - } - tbl->used = 0; - tbl->nextfree = tbl->size - 1; -} - -UHTBL_API void* uhtbl_get (uhtbl_t *tbl, const void *key, long len) { - return _uhtbl_find(tbl, key, len, NULL, NULL); -} - -UHTBL_API void* uhtbl_set (uhtbl_t *tbl, void *key, long len) { - int localkey = 0; - uint16_t keysize = len, flags; - if (!key) { /* Check whether key is treated as a pointer */ - key = &len; - keysize = sizeof(len); - localkey = 1; - } - - uhtbl_size_t mainaddr; - uhtbl_bucket_t *resolve, *match, *prev = NULL; - uhtbl_bucket_t *lookup = _uhtbl_find(tbl, key, keysize, &prev, &mainaddr); - - if (lookup) { - match = lookup; - flags = match->head.flags; - if (flags & UHTBL_FLAG_OCCUPIED) { /* We are replacing an entry */ - if (tbl->fct_gc) { - tbl->fct_gc(match); - } - tbl->used--; - } - } else { - match = prev; - flags = match->head.flags; - if ((flags & UHTBL_FLAG_STRANGER) - && _uhtbl_address(tbl, match) == mainaddr) { - /* Mainposition occupied by key with different hash -> move it away */ - - /* Find old prev and update its next pointer */ - if ((flags & UHTBL_FLAG_LOCALKEY)) { - _uhtbl_find(tbl, 0, - match->head.key.handle, &prev, NULL); - } else { - _uhtbl_find(tbl, match->head.key.ptr, - match->head.keysize, &prev, NULL); - } - - if (!(resolve = _uhtbl_allocate(tbl))) { - if (!uhtbl_resize(tbl, tbl->payload * UHTBL_GROWFACTOR)) { - return uhtbl_set(tbl, (localkey) ? NULL : key, len); - } else { - return NULL; - } - } - memcpy(resolve, match, tbl->bucketsize); /* Copy bucket data */ - prev->head.next = _uhtbl_address(tbl, resolve); - flags = 0; - } else if ((flags & UHTBL_FLAG_OCCUPIED) && - (match->head.keysize != keysize || memcmp((flags & UHTBL_FLAG_LOCALKEY) - ? &match->head.key.handle : match->head.key.ptr, key, keysize))) { - /* Mainposition has different key (but same hash) */ - if (!(resolve = _uhtbl_allocate(tbl))) { - if (!uhtbl_resize(tbl, tbl->payload * UHTBL_GROWFACTOR)) { - return uhtbl_set(tbl, (localkey) ? NULL : key, len); - } else { - return NULL; - } - } - - prev = match; - match = resolve; - flags = UHTBL_FLAG_STRANGER; /* We will not be in main position */ - prev->head.flags |= UHTBL_FLAG_WITHNEXT; /* Main now has next */ - prev->head.next = _uhtbl_address(tbl, match); /* main->next = us */ - } - } - - if (localkey) { - match->head.key.handle = len; - flags |= UHTBL_FLAG_LOCALKEY; - } else { - match->head.key.ptr = key; - flags &= ~UHTBL_FLAG_LOCALKEY; - } - match->head.keysize = keysize; - flags |= UHTBL_FLAG_OCCUPIED; - match->head.flags = flags; - - tbl->used++; - return match; -} - -UHTBL_API void* uhtbl_next(uhtbl_t *tbl, uhtbl_size_t *iter) { - for (; *iter < tbl->size; (*iter)++) { - if (_uhtbl_bucket(tbl, *iter)->head.flags & UHTBL_FLAG_OCCUPIED) { - return _uhtbl_bucket(tbl, (*iter)++); - } - } - return NULL; -} - -UHTBL_API int uhtbl_remove(uhtbl_t *tbl, uhtbl_head_t *head) { - void *key; - long len; - uhtbl_key(head, &key, &len); - return uhtbl_unset(tbl, key, len); -} - -UHTBL_API int uhtbl_unset(uhtbl_t *tbl, const void *key, long len) { - uhtbl_bucket_t *prev = NULL; - uhtbl_bucket_t *bucket = _uhtbl_find(tbl, key, len, &prev, NULL); - if (!bucket) { - return UHTBL_ENOENT; - } - - if (tbl->fct_gc) { - tbl->fct_gc(bucket); - } - - bucket->head.flags &= ~UHTBL_FLAG_OCCUPIED; - tbl->used--; - - /* If not in main position, get us out of the next-list */ - if (bucket->head.flags & UHTBL_FLAG_STRANGER) { - if (bucket->head.flags & UHTBL_FLAG_WITHNEXT) {/* We had next buckets */ - prev->head.next = bucket->head.next; /* Give them to out prev */ - } else { - prev->head.flags &= ~UHTBL_FLAG_WITHNEXT;/* We were the only next */ - } - bucket->head.flags = 0; - } - - uhtbl_size_t address = _uhtbl_address(tbl, bucket); - if (address > tbl->nextfree) { - tbl->nextfree = address; - } - - return UHTBL_OK; -} - -UHTBL_API int uhtbl_resize(uhtbl_t *tbl, uhtbl_size_t payload) { - uhtbl_size_t size = payload / UHTBL_PAYLOADFACTOR; - if (size < payload || size < tbl->used) { - return UHTBL_EINVAL; - } - if (payload == tbl->payload) { - return UHTBL_OK; - } - - void *buckets = calloc(size, tbl->bucketsize); - if (!buckets) { - return UHTBL_ENOMEM; - } - - uhtbl_t oldtbl; /* Save essentials of table for rehashing */ - oldtbl.buckets = tbl->buckets; - oldtbl.bucketsize = tbl->bucketsize; - oldtbl.size = tbl->size; - oldtbl.used = tbl->used; - - tbl->buckets = buckets; - tbl->payload = payload; - tbl->size = size; - tbl->used = 0; - tbl->nextfree = size - 1; - - if (oldtbl.used) { /* Rehash if table had entries before */ - uhtbl_size_t iter = 0; - uhtbl_bucket_t *old, *new; - while ((old = uhtbl_next(&oldtbl, &iter))) { - new = uhtbl_set(tbl, (old->head.flags & UHTBL_FLAG_LOCALKEY) - ? NULL : old->head.key.ptr, - (old->head.flags & UHTBL_FLAG_LOCALKEY) - ? old->head.key.handle : old->head.keysize); - new->head.user = old->head.user; - memcpy(((char*)new) + sizeof(uhtbl_head_t), - ((char*)old) + sizeof(uhtbl_head_t), - tbl->bucketsize - sizeof(uhtbl_head_t)); - } - } - - free(oldtbl.buckets); - return UHTBL_OK; -} - -UHTBL_API void uhtbl_finalize(uhtbl_t *tbl) { - uhtbl_clear(tbl); - free(tbl->buckets); - tbl->buckets = NULL; -} - -UHTBL_API void uhtbl_key(uhtbl_head_t *head, void **key, long *len) { - if (key) { - *key = (head->flags & UHTBL_FLAG_LOCALKEY) - ? NULL : head->key.ptr; - } - if (len) { - *len = (head->flags & UHTBL_FLAG_LOCALKEY) - ? head->key.handle : head->keysize; - } -} - -UHTBL_API void uhtbl_gc_key(void *bucket) { - void *key; - uhtbl_key(bucket, &key, NULL); - free(key); -} - - -/* Static auxiliary */ - -UHTBL_INLINE uhtbl_size_t _uhtbl_address(uhtbl_t *tbl, uhtbl_bucket_t *bucket) { - return ((uint8_t*)bucket - (uint8_t*)tbl->buckets) / tbl->bucketsize; -} - -UHTBL_INLINE uhtbl_bucket_t* _uhtbl_bucket(uhtbl_t *tbl, uhtbl_size_t address) { - return (uhtbl_bucket_t*) - ((uint8_t*)tbl->buckets + (address * tbl->bucketsize)); -} - -static uhtbl_bucket_t* _uhtbl_allocate(uhtbl_t *tbl) { - uhtbl_size_t address = tbl->nextfree; - do { - uhtbl_bucket_t *bucket = _uhtbl_bucket(tbl, address); - if (!(bucket->head.flags & UHTBL_FLAG_OCCUPIED)) { - if (bucket->head.flags & UHTBL_FLAG_WITHNEXT) { - /* Empty bucket still has a successor -> swap it with its */ - /* successor and return the old successor-bucket as free */ - uhtbl_bucket_t *old = bucket; - bucket = _uhtbl_bucket(tbl, old->head.next); - memcpy(old, bucket, tbl->bucketsize); - old->head.flags &= ~UHTBL_FLAG_STRANGER; /* sucessor now main */ - } - /* WARN: If set will ever fail in the future we'd take care here */ - tbl->nextfree = (address) ? address - 1 : 0; - return bucket; - } - } while(address--); - return NULL; -} - -static uhtbl_bucket_t* _uhtbl_find(uhtbl_t *tbl, const void *key, -long len, uhtbl_bucket_t **previous, uhtbl_size_t *mainaddress) { - uint16_t keysize = len; - if (!key) { - key = &len; - keysize = sizeof(len); - } - uhtbl_size_t address = tbl->fct_hash(key, keysize) % tbl->payload; - uhtbl_bucket_t *buck = _uhtbl_bucket(tbl, address); - if (mainaddress) { - *mainaddress = address; - if (!(buck->head.flags & UHTBL_FLAG_OCCUPIED)) { - return buck; - } - } - if (buck->head.flags & UHTBL_FLAG_STRANGER) { - if (previous) { - *previous = buck; - } - return NULL; - } - for (;; buck = _uhtbl_bucket(tbl, address)) { - if (buck->head.flags & UHTBL_FLAG_OCCUPIED - && buck->head.keysize == keysize - && !memcmp((buck->head.flags & UHTBL_FLAG_LOCALKEY) - ? &buck->head.key.handle : buck->head.key.ptr, key, keysize)) { - return buck; - } - if (!(buck->head.flags & UHTBL_FLAG_WITHNEXT)) { - if (previous) { - *previous = buck; - } - return NULL; - } - - address = buck->head.next; - if (previous) { - *previous = buck; - } - } -} diff --git a/uhtbl.h b/uhtbl.h deleted file mode 100644 index 55a791e..0000000 --- a/uhtbl.h +++ /dev/null @@ -1,375 +0,0 @@ -/** - * uhtbl - Generic coalesced hash table implementation - * Copyright (C) 2010 Steven Barth - * Copyright (C) 2010 John Crispin - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - * - */ -/** - * uhtbl is a coalesced cellared generic hash table implementation with the aim - * to be both small in code size and heap memory requirements. This hash table - * uses a hybrid approach called coalesced addressing which means that pointers - * to other buckets will be used in the case of a collisions. In this case no - * linked lists have to be used and less allocation calls have to be done. - * To improve performance this hash table carries a cellar for collision - * handling which is an additional address area that lies behind the - * hash-addressable space. - * - * Overhead (on x86 32bit): - * Bookkeeping: 32 Bytes (per hash table) - * Metadata: 12 Bytes including pointer to key and keysize (per bucket) - * - */ - -#ifndef UHTBL_H_ -#define UHTBL_H_ - - -/* compile-time configurables */ - -#ifndef UHTBL_PAYLOADFACTOR - #define UHTBL_PAYLOADFACTOR 0.86 -#endif - -#ifndef UHTBL_GROWFACTOR - #define UHTBL_GROWFACTOR 2 -#endif - -#ifndef UHTBL_MINIMUMSIZE - #define UHTBL_MINIMUMSIZE 16 -#endif - - -#include - -/* Internal flags and values */ -#define UHTBL_FLAG_OCCUPIED 0x01 -#define UHTBL_FLAG_STRANGER 0x02 -#define UHTBL_FLAG_WITHNEXT 0x04 -#define UHTBL_FLAG_LOCALKEY 0x08 -#define UHTBL_MAXIMUMSIZE 2147483648 - -/* Status codes */ -#define UHTBL_OK 0 -#define UHTBL_EINVAL -1 -#define UHTBL_ENOMEM -2 -#define UHTBL_ENOENT -3 - -/* API */ -#if __GNUC__ >= 4 - #ifndef UHTBL_API - #define UHTBL_API - #endif - #define UHTBL_INLINE static inline __attribute__((always_inline)) -#else - #ifndef UHTBL_API - #define UHTBL_API - #endif - #define UHTBL_INLINE static inline -#endif - - -typedef union uhtbl_key uhtbl_key_t; -typedef struct uhtbl_head uhtbl_head_t; -typedef struct uhtbl_bucket uhtbl_bucket_t; -typedef struct uhtbl_config uhtbl_config_t; -typedef struct uhtbl uhtbl_t; -typedef uint32_t uhtbl_size_t; - -typedef uhtbl_size_t(uhtbl_hash_t)(const void*, int len); -typedef void(uhtbl_gc_t)(void *bucket); - -union uhtbl_key { - void *ptr; - long handle; -}; - -struct uhtbl_head { - uint8_t user; - uint8_t flags; - uint16_t keysize; - uhtbl_size_t next; - uhtbl_key_t key; -}; - -struct uhtbl_bucket { - uhtbl_head_t head; -}; - -struct uhtbl { - uint32_t bucketsize; - uhtbl_size_t size; - uhtbl_size_t used; - uhtbl_size_t payload; - uhtbl_size_t nextfree; - uhtbl_hash_t *fct_hash; - uhtbl_gc_t *fct_gc; - void *buckets; -}; - -/** - * uhtbl_init() - Initialize a hash table. - * @tbl: hash table - * @bucketsize: size of a bucket - * @sizehint: estimated maximum of needed buckets (optional) - * @fct_hash: hash function - * @fct_gc: bucket garbage collector (optional) - * - * Initializes a new hash table and preallocates memory. - * - * bucketsize is the size in Bytes each bucket will use but note the following: - * Each bucket needs to begin with a struct uhtbl_head_t that keeps its metadata - * in addition to the payload you want it to carry. You are advised to define a - * bucket struct with the first element being a uhtbl_head_t followed by your - * desired payload and pass the size of this struct to bucketsize. - * - * sizehint is a hint on how many distinct entries will be stored in the hash - * table. This will be used to preallocate space for the buckets and is useful - * if you know how many entries will be stored in the hash table as it avoids - * expensive rehashing cycles. sizehint should be a power of 2. - * - * fct_hash is the hash function used. It takes a constant void pointer and a - * integer as size parameter and returns an unsigned (32bit) int. - * - * fct_gc is the garbage collector for buckets. Every time a bucket gets unset - * or the hash table gets cleared or finalized the garbage collector function - * taking a pointer to a bucket will take care of doing any finalization for - * the buckets' payload and key data. You may use uhtbl_key() to get a reference - * to your key pointer or handle for deallocation or cleaning up any other - * references. There is an optionally selectable garbage collector that will - * take care of free()ing key pointers if your keys point to memory areas. - * You have to pass uhtbl_gc_key as fct_gc parameter to use it. You may also - * call this function in your custom garbage collector. - * - * WARNING: Your garbage collector function must otherwise not change the - * metadata in the uhtbl_head_t structure of the bucket else behaviour will be - * undefined for all subsequent actions. - * - * - * Example: - * struct mybucket { - * uhtbl_head_t head; - * int mypayload1; - * int mypayload2; - * } - * - * uhtbl_t table; - * uhtbl_init(&table, sizeof(struct mybucket), 32, MurmurHash2, NULL); - * - * Returns 0 on success or a negative error code. - */ -UHTBL_API int uhtbl_init(uhtbl_t *tbl, uint32_t bucketsize, -uhtbl_size_t sizehint, uhtbl_hash_t *fct_hash, uhtbl_gc_t *fct_gc); - -/** - * uhtbl_get() - Get a bucket by its key. - * @tbl: hash table - * @key: key - * @len: length of key - * - * Finds and returns the bucket with a given key. - * - * Key can either be: - * 1. A pointer to a memory area then len is its length (must be < 64KB) - * 2. A NULL-pointer then len is a locally stored numerical key - * - * - * Example: - * struct mybucket *bucket; - * bucket = uhtbl_get(table, "foo", sizeof("foo")); - * printf("%i", bucket->mypayload1); - * - * bucket = uhtbl_get(table, NULL, 42); - * printf("%i", bucket->mypayload1); - * - * Returns the bucket or NULL if no bucket with given key was found. - */ -UHTBL_API void* uhtbl_get(uhtbl_t *tbl, const void *key, long len); - -/** - * uhtbl_set() - Sets a bucket for given key. - * @tbl: hash table - * @key: key - * @len: length of key - * - * Sets a new bucket for the given key and returns a pointer to the bucket for - * you to assign your payload data. If there is already a bucket with that key - * it will be unset first. - * - * Key can either be: - * 1. A pointer to a memory area then len is its length (must be < 64KB) - * 2. A NULL-pointer then len is a locally stored numerical key - * - * NOTE: If key is a pointer memory management of it will be your business. - * You might want to use a garbage collection function (see uhtbl_init()) - * - * NOTE: The payload area of your bucket is NOT initialized to zeroes. - * - * WARNING: Note the following side effects when setting previously unset keys: - * 1. A set may trigger several moving actions changing the order of buckets. - * 2. A set may trigger a rehashing cycle if all buckets are occupied. - * Therefore accessing any previously acquired pointers to any bucket results in - * undefined behaviour. In addition iterations which have started before may - * result in unwanted behaviour (e.g. buckets may be skipped or visited twice). - * - * - * Example: - * struct mybucket *bucket; - * bucket = uhtbl_set(table, "foo", sizeof("foo")); - * bucket->mypayload1 = 42: - * - * bucket = uhtbl_set(table, NULL, 42); - * bucket->mypayload1 = 1337; - * - * - * Returns the bucket or NULL if no bucket could be allocated (out of memory). - */ -UHTBL_API void* uhtbl_set(uhtbl_t *tbl, void *key, long len); - -/** - * uhtbl_next() - Iterates over all entries of the hash table. - * @tbl: hash table - * @iter: Iteration counter - * - * Iterates over all entries of the hash table. - * - * iter is a pointer to a numeric variable that should be set to zero before - * the first call and will save the iteration state. - * - * NOTE: You may safely do several iterations in parallel. You may also safely - * unset any buckets of the hashtable or set keys that are currently in the - * hash table. However setting buckets with keys that don't have an assigned - * bucket yet results in undefined behaviour. - * - * Example: - * uint32_t iter = 0; - * struct mybucket *bucket; - * while ((bucket = uhtbl_next(table, &iter))) { - * printf("%i", bucket->mypayload1); - * } - * - * Return the next bucket or NULL if all buckets were already visited. - */ -UHTBL_API void* uhtbl_next(uhtbl_t *tbl, uhtbl_size_t *iter); - -/** - * uhtbl_unset() - Unsets the bucket with given key. - * @tbl: hash table - * @key: key - * @len: length of key (optional) - * - * Unsets the bucket with given key and calls the garbage collector to free - * any payload resources - if any. - * - * Key can either be: - * 1. A pointer to a memory area then len is its length (must be < 64KB) - * 2. A NULL-pointer then len is a locally stored numerical key - * - * Example: - * uhtbl_unset(table, NULL, 42); - * - * Returns 0 on success or a negative error code if there was no matching bucket - */ -UHTBL_API int uhtbl_unset(uhtbl_t *tbl, const void *key, long len); - -/** - * uhtbl_remove() - Unsets a bucket. - * @tbl: hash table - * @head: bucket head - * - * Unsets the bucket with given address and calls the garbage collector to free - * any payload resources - if any. - * - * Example: - * uhtbl_remove(table, &bucket->head); - * - * Returns 0 on success or a negative error code if the bucket was not found - */ -UHTBL_API int uhtbl_remove(uhtbl_t *tbl, uhtbl_head_t *head); - -/** - * uhtbl_clear() - Clears the hashtable without freeing its memory. - * @tbl: hash table - * - * Clears all buckets of the hashtable invoking the garbage collector - if any - * but does not free the memory of the hash table. This is usually more - * efficient than iterating and using unset. - * - * Returns nothing. - */ -UHTBL_API void uhtbl_clear(uhtbl_t *tbl); - -/** - * uhtbl_resize() - Resizes and rehashes the hash table. - * @tbl: hash table - * @payload: Buckets to reserve. - * - * Resizes the hash table and rehashes its entries. - * - * payload is the number of buckets the hashtable should allocate. It must be - * greater or at least equal to the number of buckets currently occupied. - * - * NOTE: Rehashing is an expensive process which should be avoided if possible. - * However resizing will be automatically done if you try to set a new bucket - * but all buckets are already occupied. In this case the payload bucket count - * is usually doubled. There is currently no automatic resizing done when the - * bucket usage count decreases. You have to take care of this by yourself. - * - * Returns 0 on success or a negative error code if out of memory. - */ -UHTBL_API int uhtbl_resize(uhtbl_t *tbl, uhtbl_size_t payload); - -/** - * uhtbl_clear() - Clears the hashtable and frees the bucket memory. - * @tbl: hash table - * - * Clears all buckets of the hashtable invoking the garbage collector - if any - * and frees the memory occupied by the buckets. - * - * Returns nothing. - */ -UHTBL_API void uhtbl_finalize(uhtbl_t *tbl); - -/** - * uhtbl_key() - Returns the key parameters as passed to set. - * @head: Bucket head - * @key: Pointer where key pointer should be stored (optional) - * @len: Pointer where key len should be stored (optional) - * - * This function might be useful to obtain the key parameters of a bucket - * when doing garbage collection. - * - * Returns nothing. - */ -UHTBL_API void uhtbl_key(uhtbl_head_t *head, void **key, long *len); - -/** - * uhtbl_gc_key() - Basic garbage collector that frees key memory. - * @bucket: Bucket - * - * This function is a basic garbage collector that will free any key pointers. - * However it will not touch your payload data. - * - * WARNING: You must not call this function directly on any bucket otherwise - * behaviour will be unspecified. Instead you may pass this function to the - * uhtbl_init function. You may also call this function from inside a custom - * garbage collector. - * - * Returns nothing. - */ -UHTBL_API void uhtbl_gc_key(void *bucket); - -#endif /* UHTBL_H_ */