fix non-resizable hashtable

This commit is contained in:
Meredith L. Patterson 2014-04-20 21:00:50 +02:00
parent eb04842d85
commit bab376cab7
2 changed files with 46 additions and 11 deletions

View file

@ -39,8 +39,6 @@ if 'DESTDIR' in env:
env['libpath'] = calcInstallPath("$prefix", "lib")
if env['PLATFORM'] != 'darwin' and platform.machine()[-2:] == '64':
env['libpath'] += '64'
env['incpath'] = calcInstallPath("$prefix", "include", "hammer")
env['parsersincpath'] = calcInstallPath("$prefix", "include", "hammer", "parsers")
env['backendsincpath'] = calcInstallPath("$prefix", "include", "hammer", "backends")

View file

@ -157,30 +157,67 @@ void* h_hashtable_get(const HHashTable* ht, const void* key) {
for (hte = &ht->contents[hashval & (ht->capacity - 1)];
hte != NULL;
hte = hte->next) {
if (hte->key == NULL)
if (hte->key == NULL) {
continue;
if (hte->hashval != hashval)
}
if (hte->hashval != hashval) {
continue;
if (ht->equalFunc(key, hte->key))
}
if (ht->equalFunc(key, hte->key)) {
return hte->value;
}
}
return NULL;
}
void h_hashtable_put_raw(HHashTable* ht, HHashTableEntry* new_entry);
void h_hashtable_ensure_capacity(HHashTable* ht, size_t n) {
bool do_resize = false;
size_t old_capacity = ht->capacity;
while (n * 1.3 > ht->capacity) {
ht->capacity *= 2;
do_resize = true;
}
if (!do_resize)
return;
HHashTableEntry *old_contents = ht->contents;
HHashTableEntry *new_contents = h_arena_malloc(ht->arena, sizeof(HHashTableEntry) * ht->capacity);
ht->contents = new_contents;
ht->used = 0;
memset(new_contents, 0, sizeof(HHashTableEntry) * ht->capacity);
for (size_t i = 0; i < old_capacity; ++i)
for (HHashTableEntry *entry = &old_contents[i];
entry;
entry = entry->next)
if (entry->key)
h_hashtable_put_raw(ht, entry);
//h_arena_free(ht->arena, old_contents);
}
void h_hashtable_put(HHashTable* ht, const void* key, void* value) {
// # Start with a rebalancing
//h_hashtable_ensure_capacity(ht, ht->used + 1);
h_hashtable_ensure_capacity(ht, ht->used + 1);
HHashValue hashval = ht->hashFunc(key);
HHashTableEntry entry = {
.key = key,
.value = value,
.hashval = hashval
};
h_hashtable_put_raw(ht, &entry);
}
void h_hashtable_put_raw(HHashTable* ht, HHashTableEntry *new_entry) {
#ifdef CONSISTENCY_CHECK
assert((ht->capacity & (ht->capacity - 1)) == 0); // capacity is a power of 2
#endif
HHashTableEntry *hte = &ht->contents[hashval & (ht->capacity - 1)];
HHashTableEntry *hte = &ht->contents[new_entry->hashval & (ht->capacity - 1)];
if (hte->key != NULL) {
for(;;) {
// check each link, stay on last if not found
if (hte->hashval == hashval && ht->equalFunc(key, hte->key))
if (hte->hashval == new_entry->hashval && ht->equalFunc(new_entry->key, hte->key))
goto insert_here;
if (hte->next == NULL)
break;
@ -196,9 +233,9 @@ void h_hashtable_put(HHashTable* ht, const void* key, void* value) {
ht->used++;
insert_here:
hte->key = key;
hte->value = value;
hte->hashval = hashval;
hte->key = new_entry->key;
hte->value = new_entry->value;
hte->hashval = new_entry->hashval;
}
void h_hashtable_update(HHashTable *dst, const HHashTable *src) {