added HashMap_pushOrUpdate
This commit is contained in:
parent
57c5942fcc
commit
0a1e87817d
@ -29,6 +29,8 @@ typedef struct HashMap_ {
|
||||
#define HashMap_construct(PTR, T, VALUE_DESTRUCTOR) HashMap_construct_size(PTR, sizeof(T), VALUE_DESTRUCTOR)
|
||||
void HashMap_construct_size(HashMap_* ptr, u32 value_t_size, FreeFunction NULLABLE(value_destructor));
|
||||
void HashMap_destroy(HashMap_* ptr);
|
||||
void* NULLABLE(HashMap_tryGetPtr)(HashMap_* ptr, str key);
|
||||
bool HashMap_tryPush(HashMap_* ptr, str key, void* value_ptr);
|
||||
bool HashMap_tryDelete(HashMap_* ptr, str key);
|
||||
|
||||
bool HashMap_tryPush(HashMap_* ptr, const str key, void* value_ptr);
|
||||
void HashMap_pushOrUpdate(HashMap_* ptr, const str key, void* value_ptr);
|
||||
NULLABLE(void*) HashMap_tryGetPtr(const HashMap_* ptr, const str key);
|
||||
bool HashMap_tryDelete(HashMap_* ptr, const str key);
|
||||
|
||||
@ -62,7 +62,7 @@ typedef struct BucketAndIndex {
|
||||
|
||||
///@returns `HashMapBucket*` for specified key or NULL, if table hasn't been allocated yet;
|
||||
/// Index of existing item with the same key or -1 if no item is present.
|
||||
static BucketAndIndex __HashMap_search(HashMap_* ptr, str key, u32 hash){
|
||||
static BucketAndIndex __HashMap_search(const HashMap_* ptr, const str key, u32 hash){
|
||||
if(ptr->height == 0)
|
||||
return BucketAndIndex_null;
|
||||
|
||||
@ -79,7 +79,7 @@ static BucketAndIndex __HashMap_search(HashMap_* ptr, str key, u32 hash){
|
||||
return r;
|
||||
}
|
||||
|
||||
void* NULLABLE(HashMap_tryGetPtr)(HashMap_* ptr, str key){
|
||||
void* HashMap_tryGetPtr(const HashMap_* ptr, const str key){
|
||||
u32 hash = __HashMap_HASH_FUNC(key);
|
||||
BucketAndIndex r = __HashMap_search(ptr, key, hash);
|
||||
// key not found
|
||||
@ -121,7 +121,7 @@ static void __HashMap_expand(HashMap_* ptr){
|
||||
ptr->height_n = height_expanded_n;
|
||||
}
|
||||
|
||||
bool HashMap_tryPush(HashMap_* ptr, str key, void* value_ptr){
|
||||
bool HashMap_tryPush(HashMap_* ptr, const str key, void* value_ptr){
|
||||
u32 hash = __HashMap_HASH_FUNC(key);
|
||||
BucketAndIndex r = __HashMap_search(ptr, key, hash);
|
||||
// found existing item with the same key
|
||||
@ -140,7 +140,27 @@ bool HashMap_tryPush(HashMap_* ptr, str key, void* value_ptr){
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HashMap_tryDelete(HashMap_* ptr, str key){
|
||||
void HashMap_pushOrUpdate(HashMap_* ptr, const str key, void* value_ptr){
|
||||
u32 hash = __HashMap_HASH_FUNC(key);
|
||||
BucketAndIndex r = __HashMap_search(ptr, key, hash);
|
||||
// found existing item with the same key
|
||||
if(r.i != -1){
|
||||
void* existing_item = ((u8*)r.bu->value_list.data) + r.i * ptr->value_t_size;
|
||||
memcpy(existing_item, value_ptr, ptr->value_t_size);
|
||||
}
|
||||
|
||||
HashMapBucket* bu = r.bu;
|
||||
if(bu == NULL || List_len(&bu->key_hash_list, KeyHash) >= __HashMapBucket_MAX_LEN){
|
||||
__HashMap_expand(ptr);
|
||||
bu = &ptr->table[hash % ptr->height];
|
||||
}
|
||||
|
||||
KeyHash kh = { .key = str_copy(key), .hash = hash };
|
||||
List_push(&bu->key_hash_list, KeyHash, kh);
|
||||
List_push_size(&bu->value_list, value_ptr, ptr->value_t_size);
|
||||
}
|
||||
|
||||
bool HashMap_tryDelete(HashMap_* ptr, const str key){
|
||||
u32 hash = __HashMap_HASH_FUNC(key);
|
||||
BucketAndIndex r = __HashMap_search(ptr, key, hash);
|
||||
// key not found
|
||||
|
||||
Loading…
Reference in New Issue
Block a user