mirror of
https://github.com/Ed94/metadesk.git
synced 2026-08-02 20:58:14 +00:00
Test and avoid MD_StringMap collisions.
This commit is contained in:
@@ -398,6 +398,7 @@ struct MD_MapSlot
|
||||
{
|
||||
MD_MapSlot *next;
|
||||
MD_u64 hash;
|
||||
void *key;
|
||||
void *value;
|
||||
};
|
||||
|
||||
|
||||
+101
-52
@@ -959,12 +959,109 @@ _MD_Map_Initialize(MD_Map *map)
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//~ NOTE(mal): MD_StringMap
|
||||
MD_FUNCTION_IMPL MD_MapSlot *
|
||||
_MD_Map_Lookup(MD_Map *map, MD_u64 hash)
|
||||
MD_StringMap_Lookup(MD_StringMap *map, MD_String8 string) // NOTE(mal): Or MD_PtrFromString
|
||||
{
|
||||
_MD_Map_Initialize(map);
|
||||
|
||||
MD_MapSlot *slot = 0;
|
||||
MD_u64 hash = MD_HashString(string);
|
||||
MD_u64 index = hash % map->table_size;
|
||||
for(MD_MapSlot *candidate = map->table[index]; candidate; candidate = candidate->next)
|
||||
{
|
||||
if(candidate->hash == hash && MD_StringMatch(*((MD_String8 *)candidate->key), string, 0))
|
||||
{
|
||||
slot = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_b32
|
||||
MD_StringMap_Insert(MD_StringMap *map, MD_MapCollisionRule collision_rule, MD_String8 string, void *value)
|
||||
{
|
||||
_MD_Map_Initialize(map);
|
||||
|
||||
MD_MapSlot *slot = 0;
|
||||
MD_u64 hash = MD_HashString(string);
|
||||
MD_u64 index = hash % map->table_size;
|
||||
|
||||
for(MD_MapSlot *candidate = map->table[index]; candidate; candidate = candidate->next)
|
||||
{
|
||||
if(candidate->hash == hash && MD_StringMatch(*((MD_String8 *)candidate->key), string, 0))
|
||||
{
|
||||
slot = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(slot == 0 || (slot != 0 && collision_rule == MD_MapCollisionRule_Chain))
|
||||
{
|
||||
slot = _MD_PushArray(_MD_GetCtx(), MD_MapSlot, 1);
|
||||
if(slot)
|
||||
{
|
||||
slot->next = 0;
|
||||
if(map->table[index])
|
||||
{
|
||||
for(MD_MapSlot *old_slot = map->table[index]; old_slot; old_slot = old_slot->next)
|
||||
{
|
||||
if(old_slot->next == 0)
|
||||
{
|
||||
old_slot->next = slot;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
map->table[index] = slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(slot)
|
||||
{
|
||||
slot->value = value;
|
||||
slot->hash = hash;
|
||||
MD_String8 *string_copy = _MD_PushArray(_MD_GetCtx(), MD_String8, 1);
|
||||
*string_copy = MD_PushStringCopy(string);
|
||||
slot->key = string_copy;
|
||||
}
|
||||
|
||||
return !!slot;
|
||||
}
|
||||
|
||||
// NOTE(mal): Original MD_NodeTable interface
|
||||
#define MD_NodeTable_Lookup(map, string) MD_StringMap_Lookup(map, string)
|
||||
#define MD_NodeTable_Insert(map, collision_rule, string, node) MD_StringMap_Insert(map, collision_rule, string, (void *) node)
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//~ NOTE(mal): MD_PtrMap
|
||||
|
||||
// NOTE(mal): Generic 64-bit hash function (https://nullprogram.com/blog/2018/07/31/)
|
||||
// Reversible, so no collisions. Assumes all bits of the pointer matter.
|
||||
MD_FUNCTION_IMPL MD_u64
|
||||
MD_HashPointer(void *p)
|
||||
{
|
||||
MD_u64 h = (MD_u64)p;
|
||||
h = (h ^ (h >> 30)) * UINT64_C(0xbf58476d1ce4e5b9);
|
||||
h = (h ^ (h >> 27)) * UINT64_C(0x94d049bb133111eb);
|
||||
h = h ^ (h >> 31);
|
||||
return h;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_MapSlot *
|
||||
MD_PtrMap_Lookup(MD_PtrMap *map, void *key) // NOTE(mal): Or MD_PtrFromPtr
|
||||
{
|
||||
_MD_Map_Initialize(map);
|
||||
|
||||
MD_MapSlot *slot = 0;
|
||||
|
||||
MD_u64 hash = MD_HashPointer(key);
|
||||
MD_u64 index = hash % map->table_size;
|
||||
for(MD_MapSlot *candidate = map->table[index]; candidate; candidate = candidate->next)
|
||||
{
|
||||
@@ -974,15 +1071,17 @@ _MD_Map_Lookup(MD_Map *map, MD_u64 hash)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_b32
|
||||
_MD_Map_Insert(MD_StringMap *map, MD_MapCollisionRule collision_rule, MD_u64 hash, void *value)
|
||||
MD_PtrMap_Insert(MD_PtrMap *map, MD_MapCollisionRule collision_rule, void *key, void *value)
|
||||
{
|
||||
_MD_Map_Initialize(map);
|
||||
|
||||
MD_MapSlot *slot = 0;
|
||||
MD_u64 hash = MD_HashPointer(key);
|
||||
MD_u64 index = hash % map->table_size;
|
||||
|
||||
for(MD_MapSlot *candidate = map->table[index]; candidate; candidate = candidate->next)
|
||||
@@ -1027,56 +1126,6 @@ _MD_Map_Insert(MD_StringMap *map, MD_MapCollisionRule collision_rule, MD_u64 has
|
||||
return !!slot;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//~ NOTE(mal): MD_StringMap
|
||||
MD_FUNCTION_IMPL MD_MapSlot *
|
||||
MD_StringMap_Lookup(MD_StringMap *map, MD_String8 string) // NOTE(mal): Or MD_PtrFromString
|
||||
{
|
||||
MD_MapSlot *slot = _MD_Map_Lookup(map, MD_HashString(string));
|
||||
return slot;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_b32
|
||||
MD_StringMap_Insert(MD_StringMap *map, MD_MapCollisionRule collision_rule, MD_String8 string, void *value)
|
||||
{
|
||||
MD_b32 result = _MD_Map_Insert(map, collision_rule, MD_HashString(string), value);
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE(mal): Original MD_NodeTable interface
|
||||
#define MD_NodeTable_Lookup(map, string) MD_StringMap_Lookup(map, string)
|
||||
#define MD_NodeTable_Insert(map, collision_rule, string, node) MD_StringMap_Insert(map, collision_rule, string, (void *) node)
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//~ NOTE(mal): MD_PtrMap
|
||||
|
||||
// NOTE(mal): Generic 64-bit hash function (https://nullprogram.com/blog/2018/07/31/)
|
||||
// Assumes all bits of the pointer matter and that there's a b
|
||||
MD_FUNCTION_IMPL MD_u64
|
||||
MD_HashPointer(void *p)
|
||||
{
|
||||
MD_u64 h = (MD_u64)p;
|
||||
h = (h ^ (h >> 30)) * UINT64_C(0xbf58476d1ce4e5b9);
|
||||
h = (h ^ (h >> 27)) * UINT64_C(0x94d049bb133111eb);
|
||||
h = h ^ (h >> 31);
|
||||
return h;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_MapSlot *
|
||||
MD_PtrMap_Lookup(MD_PtrMap *map, void *key) // NOTE(mal): Or MD_PtrFromPtr
|
||||
{
|
||||
MD_MapSlot *slot = _MD_Map_Lookup(map, MD_HashPointer(key));
|
||||
return slot;
|
||||
}
|
||||
|
||||
// TODO(mal): Remove collision_rule parameter and assume MD_MapCollisionRule_Overwrite?
|
||||
MD_FUNCTION_IMPL MD_b32
|
||||
MD_PtrMap_Insert(MD_PtrMap *map, MD_MapCollisionRule collision_rule, void *key, void *value)
|
||||
{
|
||||
MD_b32 result = _MD_Map_Insert(map, collision_rule, MD_HashPointer(key), value);
|
||||
return result;
|
||||
}
|
||||
|
||||
MD_FUNCTION_IMPL MD_b32
|
||||
MD_TokenKindIsWhitespace(MD_TokenKind kind)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user