summaryrefslogtreecommitdiff
path: root/src/hash-table.cc
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2000-08-20 16:50:54 +0000
committerBruno Haible <bruno@clisp.org>2000-08-20 16:50:54 +0000
commitc0eb5203949ad864470076ec23b6f348639fad2d (patch)
tree5a4e56bf9d9e8d0bc8216efb21e4ce620fe7f50b /src/hash-table.cc
parentcb286153b25bd6c861ad5d849475ec9726f29c82 (diff)
downloadgperf-c0eb5203949ad864470076ec23b6f348639fad2d.tar.gz
Allow the use of embedded NULs in keys.
Diffstat (limited to 'src/hash-table.cc')
-rw-r--r--src/hash-table.cc36
1 files changed, 20 insertions, 16 deletions
diff --git a/src/hash-table.cc b/src/hash-table.cc
index db8d6dd..a147674 100644
--- a/src/hash-table.cc
+++ b/src/hash-table.cc
@@ -1,5 +1,5 @@
/* Hash table for checking keyword links. Implemented using double hashing.
- Copyright (C) 1989-1998 Free Software Foundation, Inc.
+ Copyright (C) 1989-1998, 2000 Free Software Foundation, Inc.
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
This file is part of GNU GPERF.
@@ -26,8 +26,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
#include "options.h"
#include "trace.h"
-#define NIL(TYPE) (TYPE *)0
-
/* The size of the hash table is always the smallest power of 2 >= the size
indicated by the user. This allows several optimizations, including
the use of double hashing and elimination of the mod instruction.
@@ -37,8 +35,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
This compromises information hiding somewhat, but greatly reduces
memory fragmentation, since we can now use alloca! */
-Hash_Table::Hash_Table (List_Node **table_ptr, int s):
- table (table_ptr), size (s), collisions (0)
+Hash_Table::Hash_Table (List_Node **table_ptr, int s, int ignore_len):
+ table (table_ptr), size (s), collisions (0), ignore_length (ignore_len)
{
T (Trace t ("Hash_Table::Hash_Table");)
memset ((char *) table, 0, size * sizeof (*table));
@@ -60,8 +58,10 @@ Hash_Table::~Hash_Table (void)
for (int i = size - 1; i >= 0; i--)
if (table[i])
- fprintf (stderr, "%8d, %*s, %s\n",
- i, field_width, table[i]->char_set, table[i]->key);
+ fprintf (stderr, "%8d, %*.*s, %.*s\n",
+ i,
+ field_width, table[i]->char_set_length, table[i]->char_set,
+ table[i]->key_length, table[i]->key);
fprintf (stderr, "\nend dumping hash table\n\n");
}
@@ -72,20 +72,24 @@ Hash_Table::~Hash_Table (void)
Uses double hashing. */
List_Node *
-Hash_Table::operator() (List_Node *item, int ignore_length)
+Hash_Table::insert (List_Node *item)
{
T (Trace t ("Hash_Table::operator()");)
- unsigned hash_val = hashpjw (item->char_set);
- int probe = hash_val & size - 1;
- int increment = (hash_val ^ item->length | 1) & size - 1;
+ unsigned hash_val = hashpjw (item->char_set, item->char_set_length);
+ int probe = hash_val & (size - 1);
+ int increment = ((hash_val ^ item->key_length) | 1) & (size - 1);
- while (table[probe]
- && (strcmp (table[probe]->char_set, item->char_set)
- || (!ignore_length && table[probe]->length != item->length)))
+ while (table[probe])
{
+ if (table[probe]->char_set_length == item->char_set_length
+ && memcmp (table[probe]->char_set, item->char_set, item->char_set_length) == 0
+ && (ignore_length || table[probe]->key_length == item->key_length))
+ return table[probe];
+
collisions++;
- probe = probe + increment & size - 1;
+ probe = (probe + increment) & (size - 1);
}
- return table[probe] ? table[probe] : (table[probe] = item, NIL (List_Node));
+ table[probe] = item;
+ return (List_Node *) 0;
}