]> sjero.net Git - wget/blobdiff - src/hash.c
[svn] Added sanity checks for -k, -p, -r and -N when -O is given. Added fixes for...
[wget] / src / hash.c
index 36a90be82c9cffcc408f5a2846f4b775a12f7954..ccd0997d5f2260c2f37ecf60b5edebe4c16090ac 100644 (file)
@@ -1,5 +1,5 @@
 /* Hash tables.
-   Copyright (C) 2000-2005 Free Software Foundation, Inc.
+   Copyright (C) 2000-2006 Free Software Foundation, Inc.
 
 This file is part of GNU Wget.
 
@@ -50,8 +50,16 @@ so, delete this exception statement from your version.  */
 # define xnew_array(type, x) xmalloc (sizeof (type) * (x))
 # define xmalloc malloc
 # define xfree free
-# define countof(x) (sizeof (x) / sizeof ((x)[0]))
-# define TOLOWER(x) ('A' <= (x) && (x) <= 'Z' ? (x) - 32 : (x))
+# ifndef countof
+#  define countof(x) (sizeof (x) / sizeof ((x)[0]))
+# endif
+# include <ctype.h>
+# define TOLOWER(x) tolower ((unsigned char) (x))
+# if __STDC_VERSION__ >= 199901L
+#  include <stdint.h>  /* for uintptr_t */
+# else
+   typedef unsigned long uintptr_t;
+# endif
 #endif
 
 #include "hash.h"
@@ -170,7 +178,7 @@ struct hash_table {
    -1.  This is acceptable because it still allows the use of
    nonnegative integer keys.  */
 
-#define INVALID_PTR ((void *) ~0UL)
+#define INVALID_PTR ((void *) ~(uintptr_t) 0)
 #ifndef UCHAR_MAX
 # define UCHAR_MAX 0xff
 #endif
@@ -530,8 +538,8 @@ hash_table_for_each (struct hash_table *ht,
       }
 }
 
-/* Initiate iteration over HT.  Get the next entry using
-   hash_table_iter_next.  The typical loop looks like this:
+/* Initiate iteration over HT.  Entries are obtained with
+   hash_table_iter_next, a typical iteration loop looking like this:
 
        hash_table_iterator iter;
        for (hash_table_iterate (ht, &iter); hash_table_iter_next (&iter); )
@@ -553,8 +561,8 @@ hash_table_iterate (struct hash_table *ht, hash_table_iterator *iter)
    ITER->value respectively and 1 is returned.  When there are no more
    entries, 0 is returned.
 
-   The hash table must not be modified between calls to this
-   function.  */
+   If the hash table is modified between calls to this function, the
+   result is undefined.  */
 
 int
 hash_table_iter_next (hash_table_iterator *iter)
@@ -602,7 +610,7 @@ hash_table_count (const struct hash_table *ht)
      a hash function that returns 0 for any given object is a
      perfectly valid (albeit extremely bad) hash function.  A hash
      function that hashes a string by adding up all its characters is
-     another example of a valid (but quite bad) hash function.
+     another example of a valid (but still quite bad) hash function.
 
      It is not hard to make hash and test functions agree about
      equality.  For example, if the test function compares strings
@@ -610,24 +618,25 @@ hash_table_count (const struct hash_table *ht)
      characters when calculating the hash value.  That ensures that
      two strings differing only in case will hash the same.
 
-   - If you care about performance, choose a hash function with as
-     good "spreading" as possible.  A good hash function will use all
-     the bits of the input when calculating the hash, and will react
-     to even small changes in input with a completely different
-     output.  Finally, don't make the hash function itself overly
-     slow, because you'll be incurring a non-negligible overhead to
-     all hash table operations.  */
+   - To prevent performance degradation, choose a hash function with
+     as good "spreading" as possible.  A good hash function will use
+     all the bits of the input when calculating the hash, and will
+     react to even small changes in input with a completely different
+     output.  But don't make the hash function itself overly slow,
+     because you'll be incurring a non-negligible overhead to all hash
+     table operations.  */
 
 /*
  * Support for hash tables whose keys are strings.
  *
  */
    
-/* 31 bit hash function.  Taken from Gnome's glib, modified to use
+/* Base 31 hash function.  Taken from Gnome's glib, modified to use
    standard C types.
 
    We used to use the popular hash function from the Dragon Book, but
-   this one seems to perform much better.  */
+   this one seems to perform much better, both by being faster and by
+   generating less collisions.  */
 
 static unsigned long
 hash_string (const void *key)
@@ -708,7 +717,7 @@ make_nocase_string_hash_table (int items)
 unsigned long
 hash_pointer (const void *ptr)
 {
-  unsigned long key = (unsigned long) ptr;
+  uintptr_t key = (uintptr_t) ptr;
   key += (key << 12);
   key ^= (key >> 22);
   key += (key << 4);
@@ -717,7 +726,7 @@ hash_pointer (const void *ptr)
   key ^= (key >> 2);
   key += (key << 7);
   key ^= (key >> 12);
-#if SIZEOF_LONG > 4
+#if SIZEOF_VOID_P > 4
   key += (key << 44);
   key ^= (key >> 54);
   key += (key << 36);
@@ -727,7 +736,7 @@ hash_pointer (const void *ptr)
   key += (key << 39);
   key ^= (key >> 44);
 #endif
-  return key;
+  return (unsigned long) key;
 }
 
 static int