*
* (c) 2002--2004 Martin Mares <mj@ucw.cz>
* (c) 2002--2005 Robert Spalek <robert@ucw.cz>
+ * (c) 2010 Pavel Charvat <pchar@ucw.cz>
*
* This software may be freely distributed and used according to the terms
* of the GNU Lesser General Public License.
* will leak pool memory.
* HASH_AUTO_POOL=size Create a pool of the given block size automatically.
* HASH_USE_ELTPOOL=pool Allocate all nodes from given eltpool.
- * Only works for nodes of limited size.
* HASH_AUTO_ELTPOOL=count Create an eltpool of the given number of elements in each chunk.
- * Only works for fixed-sized nodes and zero HASH_GIVE_EXTRA_SIZE.
* HASH_ZERO_FILL New entries should be initialized to all zeroes.
* HASH_TABLE_ALLOC The hash table itself will be allocated and freed using
* the same allocation functions as the nodes instead of
* the default xmalloc().
- * HASH_TABLE_GROW Never decrease the size of the hash table itself
+ * HASH_TABLE_GROWING Never decrease the size of the hash table itself
* HASH_TABLE_DYNAMIC Support multiple hash tables; the first parameter of all
* hash table operations is struct HASH_PREFIX(table) *.
* HASH_TABLE_VARS Extra variables to be defined in table structure
} P(bucket);
struct P(table) {
+#ifdef HASH_TABLE_VARS
+ HASH_TABLE_VARS
+#endif
uns hash_size;
uns hash_count, hash_max, hash_min, hash_hard_max;
P(bucket) **ht;
#ifdef HASH_AUTO_ELTPOOL
struct eltpool *eltpool;
#endif
-#ifdef HASH_TABLE_VARS
- HASH_TABLE_VARS
-#endif
};
#ifdef HASH_TABLE_DYNAMIC
#elif defined(HASH_USE_ELTPOOL)
/* If the caller has requested to use his eltpool, do so */
#include "ucw/eltpool.h"
-static inline void * P(alloc) (TAUC unsigned int size) { ASSERT(size <= (HASH_USE_ELTPOOL)->elt_size); return ep_alloc(HASH_USE_ELTPOOL); }
+static inline void * P(alloc) (TAUC unsigned int size UNUSED) { ASSERT(size <= (HASH_USE_ELTPOOL)->elt_size); return ep_alloc(HASH_USE_ELTPOOL); }
static inline void P(free) (TAUC void *x) { ep_free(HASH_USE_ELTPOOL, x); }
static inline void P(init_alloc) (TAU) { }
static inline void P(cleanup_alloc) (TAU) { }
#elif defined(HASH_AUTO_ELTPOOL)
/* Use our own eltpools */
-#ifdef HASH_GIVE_EXTRA_SIZE
-#error HASH_AUTO_ELTPOOL not supported in combination with variable-sized nodes
-#endif
#include "ucw/eltpool.h"
static inline void * P(alloc) (TAUC unsigned int size UNUSED) { return ep_alloc(T.eltpool); }
static inline void P(free) (TAUC void *x) { ep_free(T.eltpool, x); }
#endif
+#if defined(HASH_USE_ELTPOOL) && defined(HASH_GIVE_EXTRA_SIZE)
+#error Eltpools not supported in combination with variable-sized nodes
+#endif
+
#ifdef HASH_GIVE_TABLE_ALLOC
/* If the caller has requested to use his own allocation functions, do so */
#elif defined(HASH_TABLE_ALLOC)
static inline void P(table_free) (TAUC void *x) { xfree(x); }
#endif
-#if defined(HASH_USE_POOL) && defined(HASH_TABLE_ALLOC) && !defined(HASH_TABLE_GROW)
-#define HASH_TABLE_GROW
+#if defined(HASH_USE_POOL) && defined(HASH_TABLE_ALLOC) && !defined(HASH_TABLE_GROWING)
+#define HASH_TABLE_GROWING
#endif
#ifndef HASH_DEFAULT_SIZE
T.hash_max = 2*T.hash_size;
else
T.hash_max = ~0U;
-#ifndef HASH_TABLE_GROW
+#ifndef HASH_TABLE_GROWING
if (T.hash_size/2 > HASH_DEFAULT_SIZE)
T.hash_min = T.hash_size/4;
else
{
*bb = b->next;
P(free)(TTC b);
-#ifndef HASH_TABLE_GROW
- if (--T.hash_count < T.hash_min)
+ T.hash_count--;
+#ifndef HASH_TABLE_GROWING
+ if (T.hash_count < T.hash_min)
P(rehash)(TTC T.hash_size/2);
#endif
return 1;
ASSERT(b);
*bb = b->next;
P(free)(TTC b);
-#ifndef HASH_TABLE_GROW
- if (--T.hash_count < T.hash_min)
+ T.hash_count--;
+#ifndef HASH_TABLE_GROWING
+ if (T.hash_count < T.hash_min)
P(rehash)(TTC T.hash_size/2);
#endif
}
#undef HASH_WANT_NEW
#undef HASH_WANT_REMOVE
#undef HASH_TABLE_ALLOC
-#undef HASH_TABLE_GROW
+#undef HASH_TABLE_GROWING
#undef HASH_TABLE_DYNAMIC
#undef HASH_TABLE_VARS
#undef HASH_ZERO_FILL