Change HM to use overflow and individual buckets
This commit is contained in:
parent
645a109ecf
commit
6800caf68a
2 changed files with 74 additions and 18 deletions
|
@ -15,7 +15,8 @@ UDPC_HashMap* UDPC_HashMap_init(uint32_t capacity, uint32_t unitSize)
|
||||||
m->size = 0;
|
m->size = 0;
|
||||||
m->capacity = (capacity > 10 ? capacity : 10);
|
m->capacity = (capacity > 10 ? capacity : 10);
|
||||||
m->unitSize = unitSize;
|
m->unitSize = unitSize;
|
||||||
m->buckets = malloc(sizeof(UDPC_Deque) * m->capacity);
|
|
||||||
|
m->buckets = malloc(sizeof(UDPC_Deque*) * m->capacity);
|
||||||
if(!m->buckets)
|
if(!m->buckets)
|
||||||
{
|
{
|
||||||
free(m);
|
free(m);
|
||||||
|
@ -26,14 +27,11 @@ UDPC_HashMap* UDPC_HashMap_init(uint32_t capacity, uint32_t unitSize)
|
||||||
{
|
{
|
||||||
if(fail != 0)
|
if(fail != 0)
|
||||||
{
|
{
|
||||||
(&m->buckets[x])->buf = NULL;
|
m->buckets[x] = NULL;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
m->buckets[x] = UDPC_Deque_init(unitSize * UDPC_HASHMAP_BUCKET_SIZE);
|
||||||
UDPC_Deque_clear(m->buckets + x);
|
if(!m->buckets[x])
|
||||||
(m->buckets + x)->alloc_size = 8 * (sizeof(uint32_t) + unitSize);
|
|
||||||
(m->buckets + x)->buf = malloc(8 * (sizeof(uint32_t) + unitSize));
|
|
||||||
if(!(m->buckets + x)->buf)
|
|
||||||
{
|
{
|
||||||
fail = 1;
|
fail = 1;
|
||||||
}
|
}
|
||||||
|
@ -43,9 +41,24 @@ UDPC_HashMap* UDPC_HashMap_init(uint32_t capacity, uint32_t unitSize)
|
||||||
{
|
{
|
||||||
for(int x = 0; x < m->capacity; ++x)
|
for(int x = 0; x < m->capacity; ++x)
|
||||||
{
|
{
|
||||||
if((m->buckets + x)->buf)
|
if(m->buckets[x])
|
||||||
{
|
{
|
||||||
free((m->buckets + x)->buf);
|
UDPC_Deque_destroy(m->buckets[x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(m->buckets);
|
||||||
|
free(m);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
m->overflow = UDPC_Deque_init(unitSize * UDPC_HASHMAP_BUCKET_SIZE);
|
||||||
|
if(!m->overflow)
|
||||||
|
{
|
||||||
|
for(int x = 0; x < m->capacity; ++x)
|
||||||
|
{
|
||||||
|
if(m->buckets[x])
|
||||||
|
{
|
||||||
|
UDPC_Deque_destroy(m->buckets[x]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(m->buckets);
|
free(m->buckets);
|
||||||
|
@ -60,7 +73,7 @@ void UDPC_HashMap_destroy(UDPC_HashMap *hashMap)
|
||||||
{
|
{
|
||||||
for(int x = 0; x < hashMap->capacity; ++x)
|
for(int x = 0; x < hashMap->capacity; ++x)
|
||||||
{
|
{
|
||||||
free((hashMap->buckets + x)->buf);
|
UDPC_Deque_destroy(hashMap->buckets[x]);
|
||||||
}
|
}
|
||||||
free(hashMap->buckets);
|
free(hashMap->buckets);
|
||||||
free(hashMap);
|
free(hashMap);
|
||||||
|
@ -74,7 +87,15 @@ void* UDPC_HashMap_insert(UDPC_HashMap *hm, uint32_t key, void *data)
|
||||||
memcpy(temp, &key, sizeof(uint32_t));
|
memcpy(temp, &key, sizeof(uint32_t));
|
||||||
memcpy(temp + sizeof(uint32_t), data, hm->unitSize);
|
memcpy(temp + sizeof(uint32_t), data, hm->unitSize);
|
||||||
|
|
||||||
if(UDPC_Deque_push_back(hm->buckets + hash, temp, sizeof(uint32_t) + hm->unitSize) == 0)
|
if(UDPC_Deque_get_available(hm->buckets[hash]) == 0)
|
||||||
|
{
|
||||||
|
if(UDPC_Deque_push_back(hm->overflow, temp, sizeof(uint32_t) + hm->unitSize) == 0)
|
||||||
|
{
|
||||||
|
free(temp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(UDPC_Deque_push_back(hm->buckets[hash], temp, sizeof(uint32_t) + hm->unitSize) == 0)
|
||||||
{
|
{
|
||||||
free(temp);
|
free(temp);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -82,7 +103,7 @@ void* UDPC_HashMap_insert(UDPC_HashMap *hm, uint32_t key, void *data)
|
||||||
|
|
||||||
free(temp);
|
free(temp);
|
||||||
++hm->size;
|
++hm->size;
|
||||||
temp = UDPC_Deque_get_back_ptr(hm->buckets + hash, sizeof(uint32_t) + hm->unitSize);
|
temp = UDPC_Deque_get_back_ptr(hm->buckets[hash], sizeof(uint32_t) + hm->unitSize);
|
||||||
return temp + sizeof(uint32_t);
|
return temp + sizeof(uint32_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,14 +116,34 @@ int UDPC_HashMap_remove(UDPC_HashMap *hm, uint32_t key)
|
||||||
|
|
||||||
uint32_t hash = UDPC_HASH32(key) % hm->capacity;
|
uint32_t hash = UDPC_HASH32(key) % hm->capacity;
|
||||||
|
|
||||||
for(int x = 0; x * (sizeof(uint32_t) + hm->unitSize) < (hm->buckets + hash)->size; ++x)
|
for(int x = 0; x * (sizeof(uint32_t) + hm->unitSize) < hm->buckets[hash]->size; ++x)
|
||||||
{
|
{
|
||||||
if(memcmp(
|
if(memcmp(
|
||||||
UDPC_Deque_index_ptr(hm->buckets + hash, sizeof(uint32_t) + hm->unitSize, x),
|
UDPC_Deque_index_ptr(hm->buckets[hash], sizeof(uint32_t) + hm->unitSize, x),
|
||||||
&key,
|
&key,
|
||||||
sizeof(uint32_t)) == 0)
|
sizeof(uint32_t)) == 0)
|
||||||
{
|
{
|
||||||
int result = UDPC_Deque_remove(hm->buckets + hash, sizeof(uint32_t) + hm->unitSize, x);
|
int result = UDPC_Deque_remove(hm->buckets[hash], sizeof(uint32_t) + hm->unitSize, x);
|
||||||
|
if(result != 0)
|
||||||
|
{
|
||||||
|
--hm->size;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int x = 0; x * (sizeof(uint32_t) + hm->unitSize) < hm->overflow->size; ++x)
|
||||||
|
{
|
||||||
|
if(memcmp(
|
||||||
|
UDPC_Deque_index_ptr(hm->overflow, sizeof(uint32_t) + hm->unitSize, x),
|
||||||
|
&key,
|
||||||
|
sizeof(uint32_t)) == 0)
|
||||||
|
{
|
||||||
|
int result = UDPC_Deque_remove(hm->overflow, sizeof(uint32_t) + hm->unitSize, x);
|
||||||
if(result != 0)
|
if(result != 0)
|
||||||
{
|
{
|
||||||
--hm->size;
|
--hm->size;
|
||||||
|
@ -127,9 +168,21 @@ void* UDPC_HashMap_get(UDPC_HashMap *hm, uint32_t key)
|
||||||
|
|
||||||
uint32_t hash = UDPC_HASH32(key) % hm->capacity;
|
uint32_t hash = UDPC_HASH32(key) % hm->capacity;
|
||||||
|
|
||||||
for(int x = 0; x * (sizeof(uint32_t) + hm->unitSize) < (hm->buckets + hash)->size; ++x)
|
for(int x = 0; x * (sizeof(uint32_t) + hm->unitSize) < hm->buckets[hash]->size; ++x)
|
||||||
{
|
{
|
||||||
char *ptr = UDPC_Deque_index_ptr(hm->buckets + hash, sizeof(uint32_t) + hm->unitSize, x);
|
char *ptr = UDPC_Deque_index_ptr(hm->buckets[hash], sizeof(uint32_t) + hm->unitSize, x);
|
||||||
|
if(memcmp(
|
||||||
|
ptr,
|
||||||
|
&key,
|
||||||
|
sizeof(uint32_t)) == 0)
|
||||||
|
{
|
||||||
|
return ptr + sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int x = 0; x * (sizeof(uint32_t) + hm->unitSize) < hm->overflow->size; ++x)
|
||||||
|
{
|
||||||
|
char *ptr = UDPC_Deque_index_ptr(hm->overflow, sizeof(uint32_t) + hm->unitSize, x);
|
||||||
if(memcmp(
|
if(memcmp(
|
||||||
ptr,
|
ptr,
|
||||||
&key,
|
&key,
|
||||||
|
|
|
@ -15,13 +15,16 @@
|
||||||
) ^ 0x96969696 \
|
) ^ 0x96969696 \
|
||||||
)
|
)
|
||||||
|
|
||||||
|
#define UDPC_HASHMAP_BUCKET_SIZE 4
|
||||||
|
|
||||||
#include "UDPC_Deque.h"
|
#include "UDPC_Deque.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint32_t capacity;
|
uint32_t capacity;
|
||||||
uint32_t unitSize;
|
uint32_t unitSize;
|
||||||
UDPC_Deque *buckets;
|
UDPC_Deque **buckets;
|
||||||
|
UDPC_Deque *overflow;
|
||||||
} UDPC_HashMap;
|
} UDPC_HashMap;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
Loading…
Reference in a new issue