]> mj.ucw.cz Git - libucw.git/blobdiff - ucw/hashtable.h
Resources: Allow res_free(NULL) and res_detach(NULL)
[libucw.git] / ucw / hashtable.h
index 099ee7bdbadb106d0e0008a33c6acc5bd435e958..622f071aa7a663151ab79bc5d3fee36d6268b7cb 100644 (file)
@@ -3,6 +3,7 @@
  *
  *     (c) 2002--2004 Martin Mares <mj@ucw.cz>
  *     (c) 2002--2005 Robert Spalek <robert@ucw.cz>
  *
  *     (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.
  *
  *     This software may be freely distributed and used according to the terms
  *     of the GNU Lesser General Public License.
@@ -97,9 +98,7 @@
  *                     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.
  *                     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.
  *  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
  *  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
@@ -162,6 +161,9 @@ typedef struct P(bucket) {
 } P(bucket);
 
 struct P(table) {
 } 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;
   uns hash_size;
   uns hash_count, hash_max, hash_min, hash_hard_max;
   P(bucket) **ht;
@@ -171,9 +173,6 @@ struct P(table) {
 #ifdef HASH_AUTO_ELTPOOL
   struct eltpool *eltpool;
 #endif
 #ifdef HASH_AUTO_ELTPOOL
   struct eltpool *eltpool;
 #endif
-#ifdef HASH_TABLE_VARS
-  HASH_TABLE_VARS
-#endif
 };
 
 #ifdef HASH_TABLE_DYNAMIC
 };
 
 #ifdef HASH_TABLE_DYNAMIC
@@ -366,9 +365,6 @@ static inline void P(cleanup_alloc) (TAU) { }
 
 #elif defined(HASH_AUTO_ELTPOOL)
 /* Use our own eltpools */
 
 #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); }
 #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); }
@@ -385,6 +381,10 @@ static inline void P(cleanup_alloc) (TAU) { }
 
 #endif
 
 
 #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)
 #ifdef HASH_GIVE_TABLE_ALLOC
 /* If the caller has requested to use his own allocation functions, do so */
 #elif defined(HASH_TABLE_ALLOC)
@@ -655,8 +655,9 @@ static int HASH_PREFIX(delete)(TAC HASH_KEY_DECL)
        {
          *bb = b->next;
          P(free)(TTC b);
        {
          *bb = b->next;
          P(free)(TTC b);
+         T.hash_count--;
 #ifndef HASH_TABLE_GROWING
 #ifndef HASH_TABLE_GROWING
-         if (--T.hash_count < T.hash_min)
+         if (T.hash_count < T.hash_min)
            P(rehash)(TTC T.hash_size/2);
 #endif
          return 1;
            P(rehash)(TTC T.hash_size/2);
 #endif
          return 1;
@@ -686,8 +687,9 @@ static void HASH_PREFIX(remove)(TAC HASH_NODE *n)
   ASSERT(b);
   *bb = b->next;
   P(free)(TTC b);
   ASSERT(b);
   *bb = b->next;
   P(free)(TTC b);
+  T.hash_count--;
 #ifndef HASH_TABLE_GROWING
 #ifndef HASH_TABLE_GROWING
-  if (--T.hash_count < T.hash_min)
+  if (T.hash_count < T.hash_min)
     P(rehash)(TTC T.hash_size/2);
 #endif
 }
     P(rehash)(TTC T.hash_size/2);
 #endif
 }