Something else that has been laying around for some time. Implemented hash_grow() that can grow a hash table to a new table size. Automatic growing is commented out in hash_insert() since there needs to be a way to disallow growing in certain cases (i.e. where no allocations can be made). This is detailed in the ToDo at the top of the file.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23074 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2007-12-06 21:58:06 +00:00
parent bbea21a256
commit dfa4dfe033
2 changed files with 49 additions and 2 deletions

View File

@ -28,6 +28,7 @@ struct hash_table *hash_init(uint32 table_size, int next_ptr_offset,
int compare_func(void *element, const void *key),
uint32 hash_func(void *element, const void *key, uint32 range));
int hash_uninit(struct hash_table *table);
status_t hash_grow(struct hash_table *table, uint32 newSize);
status_t hash_insert(struct hash_table *table, void *_element);
status_t hash_remove(struct hash_table *table, void *_element);
void hash_remove_current(struct hash_table *table, struct hash_iterator *iterator);

View File

@ -126,13 +126,55 @@ hash_uninit(struct hash_table *table)
}
status_t
hash_grow(struct hash_table *table, uint32 newSize)
{
struct hash_element **newTable;
uint32 index;
void *start;
bool status;
if (table->table_size >= newSize)
return B_OK;
newTable = (struct hash_element **)malloc(sizeof(void *) * newSize);
if (newTable == NULL)
return B_NO_MEMORY;
for (index = 0; index < newSize; index++)
newTable[index] = NULL;
// rehash all the entries and add them to the new table
for (index = 0; index < table->table_size; index++) {
void *element;
void *next;
for (element = table->table[index]; element != NULL; element = next) {
uint32 hash = table->hash_func(element, NULL, newSize);
next = NEXT(table, element);
PUT_IN_NEXT(table, element, newTable[hash]);
newTable[hash] = (struct hash_element *)element;
}
}
free(table->table);
table->table = newTable;
table->table_size = newSize;
TRACE(("hash_grow: grown table %p, new size %lu\n", table, newSize));
return B_OK;
}
status_t
hash_insert(struct hash_table *table, void *element)
{
uint32 hash;
ASSERT(table != NULL && element != NULL);
TRACE(("hash_insert: table 0x%x, element 0x%x\n", table, element));
TRACE(("hash_insert: table %p, element %p\n", table, element));
hash = table->hash_func(element, NULL, table->table_size);
PUT_IN_NEXT(table, element, table->table[hash]);
@ -140,8 +182,12 @@ hash_insert(struct hash_table *table, void *element)
table->num_elements++;
// ToDo: resize hash table if it's grown too much!
/*if ((uint32)table->num_elements > table->table_size * 4) {
dprintf("hash_insert: table has grown too much: %d in %d\n", table->num_elements, (int)table->table_size);
hash_grow(table, (uint32)table->num_elements);
}*/
return 0;
return B_OK;
}