1 /* Copyright (C) 2003, 2004, 2005, 2006, 2013 MORIOKA Tomohiko
2 This file is part of the CONCORD Library.
4 The CONCORD Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The CONCORD Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the CONCORD Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 #include "concord-name.h"
25 concord_make_hash_table (size_t size)
27 CONCORD_HASH_TABLE* hash
28 = (CONCORD_HASH_TABLE*)malloc (sizeof (CONCORD_HASH_TABLE));
34 = (CONCORD_HASH_TABLE_ENTRY*) malloc (sizeof (CONCORD_HASH_TABLE_ENTRY)
36 if (hash->data == NULL)
43 memset (hash->data, 0, sizeof (CONCORD_HASH_TABLE_ENTRY) * size);
48 concord_destroy_hash_table (CONCORD_HASH_TABLE* table)
57 /* derived from hashpjw, Dragon Book P436. */
59 concord_hash_c_string (const unsigned char *ptr)
61 unsigned long hash = 0;
66 hash = (hash << 4) + *ptr++;
67 g = hash & 0xf0000000;
69 hash = (hash ^ (g >> 24)) ^ g;
71 return hash & 07777777777;
76 concord_make_name_table ()
78 return concord_make_hash_table (256);
82 concord_destroy_name_table (CONCORD_NAME_TABLE* table)
86 for (i = 0; i < table->size; i++)
88 CONCORD_NAME_TABLE_ENTRY entry = table->data[i];
90 if (entry.key != NULL)
92 if (entry.value != NULL)
97 concord_destroy_hash_table (table);
101 concord_name_table_put (CONCORD_NAME_TABLE* table,
102 const char *key, void *value)
105 CONCORD_NAME_TABLE_ENTRY* entry;
110 index = concord_hash_c_string ((unsigned char*)key) % table->size;
111 for (i = index; i < table->size; i++)
113 entry = &table->data[i];
114 if (entry->key == NULL)
116 size_t len = strlen (key);
118 entry->key = (unsigned char*)malloc (len + 1);
119 if (entry->key == NULL)
121 strcpy (entry->key, key);
122 entry->value = value;
125 else if (strcmp (entry->key, key) == 0)
127 entry->value = value;
131 if (concord_name_table_grow (table) == 0)
132 return concord_name_table_put (table, key, value);
137 concord_name_table_get (CONCORD_NAME_TABLE* table, const char *key)
140 CONCORD_NAME_TABLE_ENTRY entry;
145 index = concord_hash_c_string ((unsigned char*)key) % table->size;
146 for (i = index; i < table->size; i++)
148 entry = table->data[i];
149 if (entry.key == NULL)
151 else if (strcmp (entry.key, key) == 0)
158 concord_name_table_grow (CONCORD_NAME_TABLE* table)
160 CONCORD_NAME_TABLE *new_table
161 = concord_make_hash_table ( table->size * 2
162 /* - (table->size * 4 / 5) */ );
165 if (new_table == NULL)
168 for (i = 0; i < table->size; i++)
170 CONCORD_NAME_TABLE_ENTRY entry = table->data[i];
171 if ( (entry.key != NULL) && (entry.value != NULL) )
174 = concord_name_table_put (new_table, entry.key, entry.value);
177 concord_destroy_hash_table (new_table);
183 table->size = new_table->size;
184 table->data = new_table->data;