📄 hash-table.cc
字号:
/* Hash table for checking keyword links. Implemented using double hashing. Copyright (C) 1989 Free Software Foundation, Inc. written by Douglas C. Schmidt (schmidt@ics.uci.edu)This file is part of GNU GPERF.GNU GPERF is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 1, or (at your option)any later version.GNU GPERF is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU GPERF; see the file COPYING. If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */#include <stdio.h>#include <std.h>#include <builtin.h>#include "hash-table.h"#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. Note that the size had better be larger than the number of items in the hash table, else there's trouble!!! Note that the memory for the hash table is allocated *outside* the intialization routine. 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): collisions (0), size (s), table (table_ptr){ T (Trace t ("Hash_Table::Hash_Table");) memset ((char *) table, 0, size * sizeof *table);}Hash_Table::~Hash_Table (void) { T (Trace t ("Hash_Table::~Hash_Table");) if (option[DEBUG]) { int field_width = option.get_max_keysig_size (); fprintf (stderr, "\ndumping the hash table\ntotal available table slots = %d, total bytes = %d, total collisions = %d\n" "location, %*s, keyword\n", size, size * sizeof *table, collisions, field_width, "keysig"); 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, "\nend dumping hash table\n\n", collisions); }}/* If the ITEM is already in the hash table return the item found in the table. Otherwise inserts the ITEM, and returns FALSE. Uses double hashing. */List_Node *Hash_Table::operator() (List_Node *item, int ignore_length) { 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; while (table[probe] && (strcmp (table[probe]->char_set, item->char_set) || (!ignore_length && table[probe]->length != item->length))) { collisions++; probe = probe + increment & size - 1; } return table[probe] ? /* Elided! */ : (table[probe] = item, NIL (List_Node));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -