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:
parent
bbea21a256
commit
dfa4dfe033
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user