From ab15dd054b3c30328088c380288ccef479f7538b Mon Sep 17 00:00:00 2001
From: hniksic <devnull@localhost>
Date: Fri, 7 Nov 2003 03:40:08 -0800
Subject: [PATCH] [svn] Allow NULL/0 as hash table keys.

---
 src/ChangeLog |  9 +++++++++
 src/hash.c    | 18 +++++++++++++-----
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index bf5f6ccb..7227bdfb 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,12 @@
+2003-11-07  Hrvoje Niksic  <hniksic@xemacs.org>
+
+	* hash.c (NON_EMPTY): Use the all-bit-set value as the marker that
+	the field is empty.  This allows NULL pointer and 0 value to be
+	used as keys, which is necessary for the connect.c code to work
+	when fd==0.
+	(hash_table_new): Fill mappings with 0xff.
+	(grow_hash_table): Ditto.
+
 2003-11-07  Hrvoje Niksic  <hniksic@xemacs.org>
 
 	* url.c (url_parse): Allow empty ports.
diff --git a/src/hash.c b/src/hash.c
index b72fac71..ed8cac1e 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -175,9 +175,10 @@ struct hash_table {
   struct mapping *mappings;	/* the array of mapping pairs. */
 };
 
-/* We use NULL key to mark a mapping as empty.  It is consequently
-   illegal to store NULL keys.  */
-#define NON_EMPTY(mp) (mp->key != NULL)
+/* We use all-bit-set marker to mean that a mapping is empty.  It is
+   (hopefully) illegal as a pointer, and it allows the users to use
+   NULL (as well as any non-negative integer) as key.  */
+#define NON_EMPTY(mp) (mp->key != (void *)~(unsigned long)0)
 
 /* "Next" mapping is the mapping after MP, but wrapping back to
    MAPPINGS when MP would reach MAPPINGS+SIZE.  */
@@ -284,7 +285,11 @@ hash_table_new (int items,
   ht->resize_threshold = size * HASH_MAX_FULLNESS;
   /*assert (ht->resize_threshold >= items);*/
 
-  ht->mappings = xnew0_array (struct mapping, ht->size);
+  ht->mappings = xnew_array (struct mapping, ht->size);
+  /* Mark mappings as empty.  We use 0xff rather than 0 to mark empty
+     keys because it allows us to store NULL keys to the table.  */
+  memset (ht->mappings, 255, size * sizeof (struct mapping));
+
   ht->count = 0;
 
   return ht;
@@ -384,7 +389,10 @@ grow_hash_table (struct hash_table *ht)
 
   ht->size = newsize;
   ht->resize_threshold = newsize * HASH_MAX_FULLNESS;
-  ht->mappings = mappings = xnew0_array (struct mapping, ht->size);
+
+  mappings = xnew_array (struct mapping, newsize);
+  memset (mappings, 255, newsize * sizeof (struct mapping));
+  ht->mappings = mappings;
 
   for (mp = old_mappings; mp < old_end; mp++)
     if (NON_EMPTY (mp))