diff --git a/docs/metadesk_reference.md b/docs/metadesk_reference.md index 56746c9..fc3d937 100644 --- a/docs/metadesk_reference.md +++ b/docs/metadesk_reference.md @@ -311,22 +311,20 @@ main: //~ String-To-Node table @send(Map) -@doc("Controls the behavior of routines that write into maps when the written key was already in the map.") -@see(MD_Map) -@see(MD_StringMap_Insert) -@see(MD_PtrMap_Insert) -@enum MD_MapCollisionRule: { - @doc("When the key written was already in the map, a new key value pair is attached to the same chain always. Leaving multiple values associated to the same key.") - Chain, - @doc("When the key written was already in the map, the existing value is replaced with the newly inserted value.") - Overwrite, -} +@doc("An abstraction over the types of keys used in a MD_Map and the work of hashing those keys, can be constructed from an MD_String8 or an void*.") +@struct MD_MapKey: { + @doc("The hash of the key. The hash function used is determined from the key type.") + hash: MD_u64, + @doc("For a non-empty MD_String8, the size of the string data. For a void*, zero.") + size: MD_u64, + @doc("For a non-empty MD_String8, points to the string data of the key. For a void*, the direct pointer value.") + ptr: *void, +}; @send(Map) @doc("A slot containing one (key,value) pair in a MD_Map.") -@see(MD_Map) @struct MD_MapSlot: { - @doc("The next slot in the same bucket of the MD_Map") + @doc("The next slot in the same bucket of the MD_Map.") next: *MD_MapSlot, @doc("For slots with a string key, the hash of the key.") hash: MD_u64, @@ -828,12 +826,6 @@ main: return: MD_f64, }; -@send(Strings) -@func MD_HashString: { - string: MD_String8, - return: MD_u64, -}; - @send(Strings) @func MD_CalculateCStringLength: { cstr: *char, @@ -918,9 +910,79 @@ main: return: MD_String32, }; +//////////////////////////////// +//~ Map Table Data Structure + +@send(Map) +@func MD_HashString: { + string: MD_String8, + return: MD_u64, +}; + +@send(Map) +@func MD_HashPointer: { + p: *void, +}; + +@send(Map) +MD_MapMakeBucketCount: { + bucket_count: MD_u64, + return: MD_Map, +}; + +@send(Map) +MD_MapMake: { + return: MD_Map, +}; + +@send(Map) +MD_MapKeyStr: { + string: MD_String8, + return: MD_MapKey, +}; + +@send(Map) +MD_MapKeyPtr: { + ptr: *void, + return: MD_MapKey, +}; + +@send(Map) +MD_MapLookup: { + map: *MD_Map, + key: MD_MapKey, + return: *MD_MapSlot, +}; + +@send(Map) +MD_MapScan: { + first_slot: *MD_MapSlot, + key: MD_MapKey, + return: *MD_MapSlot, +}; + +@send(Map) +MD_MapInsert: { + map: *MD_Map, + key: MD_MapKey, + val: *void, + return: *MD_MapSlot, +}; + +@send(Map) +MD_MapOverwrite: { + map: *MD_Map, + key: MD_MapKey, + val: *void, + return: *MD_MapSlot, +}; + + //////////////////////////////// //~ String-To-Pointer Table +// TODO(allen): update reference for map + @send(Map) @func MD_StringMap_Lookup: { table: *MD_Map, diff --git a/samples/namespaced_types/namespaced_types.c b/samples/namespaced_types/namespaced_types.c index 54f436f..7929c1b 100644 --- a/samples/namespaced_types/namespaced_types.c +++ b/samples/namespaced_types/namespaced_types.c @@ -6,10 +6,10 @@ static MD_Map MapFromChildren(MD_Node *node) { - MD_Map result = {0}; + MD_Map result = MD_MapMake(); for(MD_EachNodeRef(child, node->first_child)) { - MD_StringMap_Insert(&result, MD_MapCollisionRule_Chain, child->string, child); + MD_MapInsert(&result, MD_MapKeyStr(child->string), child); } return result; } @@ -23,7 +23,7 @@ OutputType_C_LHS_Namespace(FILE *file, MD_Map *user_defined_types, MD_String8 pr { MD_Node *node = type->node; - if(MD_StringMap_Lookup(user_defined_types, type->node->string)) + if(MD_MapLookup(user_defined_types, MD_MapKeyStr(node->string))) { fprintf(file, "%.*s", MD_StringExpand(prefix)); } @@ -156,10 +156,10 @@ static void AppendConversionCode(FILE *f, MD_Map *user_defined_types, MD_Node *n for(MD_EachNode(member, old_element->first_child)) { - MD_MapSlot *slot = MD_StringMap_Lookup(&new_element_map, member->string); + MD_MapSlot *slot = MD_MapLookup(&new_element_map, MD_MapKeyStr(member->string)); if(slot) { - AppendConversionCode(f, user_defined_types, member, slot->value, extended_member_path); + AppendConversionCode(f, user_defined_types, member, slot->val, extended_member_path); } else { @@ -177,7 +177,7 @@ static void AppendConversionCode(FILE *f, MD_Map *user_defined_types, MD_Node *n MD_String8 extended_member_path = MD_PushStringF("%.*s.%.*s", MD_StringExpand(member_path), MD_StringExpand(old_element->string)); - if(MD_StringMap_Lookup(user_defined_types, type_name)) + if(MD_MapLookup(user_defined_types, MD_MapKeyStr(type_name))) { fprintf(f, " result%.*s = %.*sFromV1(v%.*s);\n", MD_StringExpand(extended_member_path), MD_StringExpand(type_name), @@ -236,7 +236,7 @@ int main(int argument_count, char **arguments) // NOTE(mal): Old types get "v1_" as a prefix fprintf(f, "// V1\n"); - MD_Node *v1 = MD_StringMap_Lookup(&ns_map, MD_S8Lit("v1"))->value; + MD_Node *v1 = MD_MapLookup(&ns_map, MD_MapKeyStr(MD_S8Lit("v1")))->val; MD_Map v1_map = MapFromChildren(v1); for(MD_EachNodeRef(node, v1->first_child)) { @@ -247,7 +247,7 @@ int main(int argument_count, char **arguments) fprintf(f, "// V2\n"); MD_Map empty_map = {0}; - MD_Node *v2 = MD_StringMap_Lookup(&ns_map, MD_S8Lit("v2"))->value; + MD_Node *v2 = MD_MapLookup(&ns_map, MD_MapKeyStr(MD_S8Lit("v2")))->val; for(MD_EachNodeRef(node, v2->first_child)) { OutputPrefixedType(f, &empty_map, MD_S8Lit(""), node, 0); @@ -258,8 +258,8 @@ int main(int argument_count, char **arguments) MD_Map v2_map = MapFromChildren(v2); for(MD_EachNodeRef(node, v1->first_child)) { - MD_MapSlot *slot = MD_StringMap_Lookup(&v2_map, node->string); - MD_Node *v2_type = slot->value; + MD_MapSlot *slot = MD_MapLookup(&v2_map, MD_MapKeyStr(node->string)); + MD_Node *v2_type = slot->val; MD_Map children_map = MapFromChildren(v2_type); fprintf(f, "static %.*s %.*sFromV1(v1_%.*s v)\n{\n", @@ -274,10 +274,10 @@ int main(int argument_count, char **arguments) { fprintf(f, " case v1_%.*s_%.*s: ", MD_StringExpand(node->string), MD_StringExpand(enumerand->string)); - MD_MapSlot *slot = MD_StringMap_Lookup(&children_map, enumerand->string); + MD_MapSlot *slot = MD_MapLookup(&children_map, MD_MapKeyStr(enumerand->string)); if(slot) { - MD_Node *v2_enumerand = slot->value; + MD_Node *v2_enumerand = slot->val; fprintf(f, "result = %.*s_%.*s; break;\n", MD_StringExpand(node->string), MD_StringExpand(v2_enumerand->string)); } @@ -305,7 +305,7 @@ int main(int argument_count, char **arguments) { fprintf(f, " if(v & v1_%.*s_%.*s) ", MD_StringExpand(singular_flag_type_name), MD_StringExpand(flag->string)); - MD_MapSlot *slot = MD_StringMap_Lookup(&children_map, flag->string); + MD_MapSlot *slot = MD_MapLookup(&children_map, MD_MapKeyStr(flag->string)); if(slot) { fprintf(f, "result |= %.*s_%.*s;\n", @@ -332,10 +332,10 @@ int main(int argument_count, char **arguments) } MD_Map v1_children_map = MapFromChildren(node); - MD_MapSlot *v1_member_slot = MD_StringMap_Lookup(&v1_children_map, authoritative_member->string); + MD_MapSlot *v1_member_slot = MD_MapLookup(&v1_children_map, MD_MapKeyStr(authoritative_member->string)); if(v1_member_slot) { - AppendConversionCode(f, &v2_map, authoritative_member, v1_member_slot->value, MD_S8Lit("")); + AppendConversionCode(f, &v2_map, authoritative_member, v1_member_slot->val, MD_S8Lit("")); } else { @@ -348,10 +348,10 @@ int main(int argument_count, char **arguments) MD_Map v1_children_map = MapFromChildren(node); for(MD_EachNode(member, v2_type->first_child)) { - MD_MapSlot *v1_member_slot = MD_StringMap_Lookup(&v1_children_map, member->string); + MD_MapSlot *v1_member_slot = MD_MapLookup(&v1_children_map, MD_MapKeyStr(member->string)); if(v1_member_slot) { - AppendConversionCode(f, &v2_map, member, v1_member_slot->value, MD_S8Lit("")); + AppendConversionCode(f, &v2_map, member, v1_member_slot->val, MD_S8Lit("")); } else { diff --git a/samples/static_site_generator/example_site/generated/blog_main.html b/samples/static_site_generator/example_site/generated/blog_main.html index 82e9b84..f3cb731 100644 --- a/samples/static_site_generator/example_site/generated/blog_main.html +++ b/samples/static_site_generator/example_site/generated/blog_main.html @@ -25,36 +25,6 @@

Blog

diff --git a/samples/static_site_generator/static_site_generator.c b/samples/static_site_generator/static_site_generator.c index bf14ce2..c8de4f8 100644 --- a/samples/static_site_generator/static_site_generator.c +++ b/samples/static_site_generator/static_site_generator.c @@ -92,7 +92,7 @@ int main(int argument_count, char **arguments) { for(MD_EachNode(index_string, node->first_child)) { - MD_StringMap_Insert(&index_table, MD_MapCollisionRule_Chain, index_string->string, root); + MD_MapInsert(&index_table, MD_MapKeyStr(index_string->string), root); } goto end_index_build; } @@ -515,14 +515,15 @@ GeneratePageContent(MD_Map *index_table, SiteInfo *site_info, PageInfo *page_inf MD_Node *index_string = 0; for(MD_u64 idx = 0; !MD_NodeIsNil(index_string = MD_ChildFromIndex(node, idx)); idx += 1) { - for(MD_MapSlot *slot = MD_StringMap_Lookup(index_table, index_string->string); + for(MD_MapSlot *slot = MD_MapLookup(index_table, MD_MapKeyStr(index_string->string)); slot; slot = slot->next) { - if(slot->value) + if(slot->val) { - PageInfo info = ParsePageInfo((MD_Node *)slot->value); + MD_Node *node = slot->val; + PageInfo info = ParsePageInfo(node); - MD_String8 filename = ((MD_Node *)slot->value)->filename; + MD_String8 filename = node->filename; MD_String8 filename_no_ext = MD_ChopExtension(MD_SkipFolder(filename)); MD_String8 link = MD_PushStringF("%.*s.html", MD_StringExpand(filename_no_ext)); MD_String8 name = info.title->string; diff --git a/samples/toy_language/toy_language.c b/samples/toy_language/toy_language.c index 379cdb5..74159a2 100644 --- a/samples/toy_language/toy_language.c +++ b/samples/toy_language/toy_language.c @@ -49,7 +49,7 @@ InsertValueToNamespace(NamespaceNode *ns, MD_String8 string, Value v) { Value *v_store = malloc(sizeof(*v_store)); *v_store = v; - MD_StringMap_Insert(&ns->symbol_map, MD_MapCollisionRule_Overwrite, string, v_store); + MD_MapInsert(&ns->symbol_map, MD_MapKeyStr(string), v_store); } static Value @@ -58,10 +58,10 @@ ValueFromString(NamespaceNode *ns, MD_String8 string) Value v = {0}; for(NamespaceNode *n = ns; n; n = n->parent) { - MD_MapSlot *slot = MD_StringMap_Lookup(&n->symbol_map, string); - if(slot && slot->value) + MD_MapSlot *slot = MD_MapLookup(&n->symbol_map, MD_MapKeyStr(string)); + if(slot && slot->val) { - v = *(Value *)slot->value; + v = *(Value *)slot->val; break; } } diff --git a/source/md.h b/source/md.h index 34d8b52..b109b78 100644 --- a/source/md.h +++ b/source/md.h @@ -382,20 +382,20 @@ struct MD_CodeLoc //~ String-To-Ptr and Ptr-To-Ptr tables -typedef enum MD_MapCollisionRule +typedef struct MD_MapKey MD_MapKey; +struct MD_MapKey { - MD_MapCollisionRule_Chain, - MD_MapCollisionRule_Overwrite, -} -MD_MapCollisionRule; + MD_u64 hash; + MD_u64 size; + void *ptr; +}; typedef struct MD_MapSlot MD_MapSlot; struct MD_MapSlot { MD_MapSlot *next; - MD_u64 hash; - void *key; - void *value; + MD_MapKey key; + void *val; }; typedef struct MD_Map MD_Map; @@ -627,7 +627,6 @@ MD_FUNCTION MD_String8List MD_SplitString(MD_String8 string, int split_count, MD MD_FUNCTION MD_String8 MD_JoinStringList(MD_String8List list, MD_String8 separator); MD_FUNCTION MD_i64 MD_I64FromString(MD_String8 string, MD_u32 radix); MD_FUNCTION MD_f64 MD_F64FromString(MD_String8 string); -MD_FUNCTION MD_u64 MD_HashString(MD_String8 string); MD_FUNCTION MD_u64 MD_CalculateCStringLength(char *cstr); MD_FUNCTION MD_String8 MD_StyledStringFromString(MD_String8 string, MD_WordStyle word_style, MD_String8 separator); @@ -646,30 +645,18 @@ MD_FUNCTION MD_String16 MD_S16FromS8(MD_String8 str); MD_FUNCTION MD_String8 MD_S8FromS32(MD_String32 str); MD_FUNCTION MD_String32 MD_S32FromS8(MD_String8 str); -//~ Allen's Map Proposoal -#if 0 -MD_FUNCTION void MD_MapInit(MD_Map *map); -MD_FUNCTION MD_MapSlot* MD_MapLookupString(MD_Map *map, MD_String8 key); -MD_FUNCTION MD_MapSlot* MD_MapLookupPtr(MD_Map *map, void *key); -MD_FUNCTION MD_b32 MD_MapInsertString(MD_Map *map, MD_String8 key, void *val); -MD_FUNCTION MD_b32 MD_MapInsertPtr(MD_Map *map, void *key, void *val); -MD_FUNCTION MD_MapSlot* MD_MapNextString(MD_MapSlot *slot, MD_String8 key); -MD_FUNCTION MD_MapSlot* MD_MapNextPtr(MD_MapSlot *slot, void *key); -#endif - - //~ Map Table Data Structure - +MD_FUNCTION MD_u64 MD_HashString(MD_String8 string); MD_FUNCTION MD_u64 MD_HashPointer(void *p); -//- String-To-Pointer Table -MD_FUNCTION MD_MapSlot * MD_StringMap_Lookup(MD_Map *table, MD_String8 string); -MD_FUNCTION MD_b32 MD_StringMap_Insert(MD_Map *table, MD_MapCollisionRule collision_rule, MD_String8 string, void *value); -MD_FUNCTION MD_MapSlot * MD_StringMap_Next(MD_MapSlot *slot, MD_String8 key); - -//- Pointer-To-Pointer Table -MD_FUNCTION MD_MapSlot *MD_PtrMap_Lookup(MD_Map *map, void *key); -MD_FUNCTION MD_b32 MD_PtrMap_Insert(MD_Map *map, MD_MapCollisionRule collision_rule, void *key, void *value); +MD_FUNCTION MD_Map MD_MapMakeBucketCount(MD_u64 bucket_count); +MD_FUNCTION MD_Map MD_MapMake(void); +MD_FUNCTION MD_MapKey MD_MapKeyStr(MD_String8 string); +MD_FUNCTION MD_MapKey MD_MapKeyPtr(void *ptr); +MD_FUNCTION MD_MapSlot* MD_MapLookup(MD_Map *map, MD_MapKey key); +MD_FUNCTION MD_MapSlot* MD_MapScan(MD_MapSlot *first_slot, MD_MapKey key); +MD_FUNCTION MD_MapSlot* MD_MapInsert(MD_Map *map, MD_MapKey key, void *val); +MD_FUNCTION MD_MapSlot* MD_MapOverwrite(MD_Map *map, MD_MapKey key, void *val); //~ Parsing diff --git a/source/md_impl.c b/source/md_impl.c index 050c0e2..25f0047 100644 --- a/source/md_impl.c +++ b/source/md_impl.c @@ -489,17 +489,6 @@ MD_F64FromString(MD_String8 string) return(atof(str)); } -MD_FUNCTION_IMPL MD_u64 -MD_HashString(MD_String8 string) -{ - MD_u64 result = 5381; - for(MD_u64 i = 0; i < string.size; i += 1) - { - result = ((result << 5) + result) + string.str[i]; - } - return result; -} - MD_FUNCTION_IMPL MD_u64 MD_CalculateCStringLength(char *cstr) { @@ -926,14 +915,15 @@ MD_S32FromS8(MD_String8 in) //~ Map Table Data Structure -MD_PRIVATE_FUNCTION_IMPL void -_MD_Map_Initialize(MD_Map *map) +MD_FUNCTION_IMPL MD_u64 +MD_HashString(MD_String8 string) { - if(map->table_size == 0) + MD_u64 result = 5381; + for(MD_u64 i = 0; i < string.size; i += 1) { - map->table_size = 4096; - map->table = MD_PushArray(MD_MapSlot *, map->table_size); + result = ((result << 5) + result) + string.str[i]; } + return result; } // NOTE(mal): Generic 64-bit hash function (https://nullprogram.com/blog/2018/07/31/) @@ -948,169 +938,115 @@ MD_HashPointer(void *p) return h; } -//- String-To-Pointer Table - -MD_FUNCTION_IMPL MD_MapSlot * -MD_StringMap_Lookup(MD_Map *map, MD_String8 string) -{ - _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_Map +MD_MapMakeBucketCount(MD_u64 bucket_count){ + // TODO(allen): permanent arena? scratch arena? -- would really + // make most sense with a parameter + MD_Map result = {0}; + result.table_size = bucket_count; + // TODO(allen): push array zero + result.table = MD_PushArray(MD_MapSlot*, bucket_count); + memset(result.table, 0, sizeof(*result.table)*bucket_count); + return(result); } -MD_FUNCTION_IMPL MD_b32 -MD_StringMap_Insert(MD_Map *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; +MD_FUNCTION_IMPL MD_Map +MD_MapMake(void){ + MD_Map result = MD_MapMakeBucketCount(4093); + return(result); +} + +MD_FUNCTION MD_MapKey +MD_MapKeyStr(MD_String8 string){ + MD_MapKey result = {0}; + if (string.size != 0){ + result.hash = MD_HashString(string); + result.size = string.size; + if (string.size > 0){ + result.ptr = string.str; } } - - if(slot == 0 || (slot != 0 && collision_rule == MD_MapCollisionRule_Chain)) - { - slot = MD_PushArray(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; + return(result); +} + +MD_FUNCTION MD_MapKey +MD_MapKeyPtr(void *ptr){ + MD_MapKey result = {0}; + if (ptr != 0){ + result.hash = MD_HashPointer(ptr); + result.size = 0; + result.ptr = ptr; + } + return(result); +} + +MD_FUNCTION_IMPL MD_MapSlot* +MD_MapLookup(MD_Map *map, MD_MapKey key){ + MD_MapSlot *result = 0; + if (map->table_size > 0){ + MD_u64 index = key.hash%map->table_size; + result = MD_MapScan(map->table[index], key); + } + return(result); +} + +MD_FUNCTION_IMPL MD_MapSlot* +MD_MapScan(MD_MapSlot *first_slot, MD_MapKey key){ + MD_MapSlot *result = 0; + if (first_slot != 0){ + MD_b32 ptr_kind = (key.size == 0); + MD_String8 key_string = MD_S8((MD_u8*)key.ptr, key.size); + for (MD_MapSlot *slot = first_slot; + slot != 0; + slot = slot->next){ + if (slot->key.hash == key.hash){ + if (ptr_kind){ + if (slot->key.size == 0 && slot->key.ptr == key.ptr){ + result = slot; + break; + } + } + else{ + MD_String8 slot_string = MD_S8((MD_u8*)slot->key.ptr, slot->key.size); + if (MD_StringMatch(slot_string, key_string, 0)){ + result = slot; break; } } } - else - { - map->table[index] = slot; - } } } - - if(slot) - { - slot->value = value; - slot->hash = hash; - MD_String8 *string_copy = MD_PushArray(MD_String8, 1); - *string_copy = MD_PushStringCopy(string); - slot->key = string_copy; - } - - return !!slot; + return(result); } -MD_FUNCTION_IMPL MD_MapSlot * -MD_StringMap_Next(MD_MapSlot *slot, MD_String8 key) -{ - MD_MapSlot *next = 0; - if(slot) - { - for(MD_MapSlot *candidate = slot->next; candidate; candidate = candidate->next) - { - if(MD_StringMatch(*(MD_String8 *)candidate->key, key, 0)) - { - next = candidate; - break; - } - } +MD_FUNCTION_IMPL MD_MapSlot* +MD_MapInsert(MD_Map *map, MD_MapKey key, void *val){ + MD_MapSlot *result = 0; + if (map->table_size > 0){ + MD_u64 index = key.hash%map->table_size; + // TODO(allen): again, memory? permanent arena? scratch arena? + // should definitely match the table's memory "object" + MD_MapSlot *slot = MD_PushArray(MD_MapSlot, 1); + // TODO(allen): queue push + slot->next = map->table[index]; + map->table[index] = slot; + slot->key = key; + slot->val = val; + result = slot; } - return next; + return(result); } -//- Pointer-To-Pointer Table - -MD_FUNCTION_IMPL MD_MapSlot * -MD_PtrMap_Lookup(MD_Map *map, void *key) -{ - _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) - { - if(candidate->hash == hash) - { - slot = candidate; - break; - } +MD_FUNCTION_IMPL MD_MapSlot* +MD_MapOverwrite(MD_Map *map, MD_MapKey key, void *val){ + MD_MapSlot *result = MD_MapLookup(map, key); + if (result != 0){ + result->val = val; } - - return slot; -} - -MD_FUNCTION_IMPL MD_b32 -MD_PtrMap_Insert(MD_Map *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) - { - if(candidate->hash == hash) - { - slot = candidate; - break; - } + else{ + result = MD_MapInsert(map, key, val); } - - if(slot == 0 || (slot != 0 && collision_rule == MD_MapCollisionRule_Chain)) - { - slot = MD_PushArray(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; - } - - return !!slot; + return(result); } //~ Parsing @@ -2066,16 +2002,17 @@ MD_ParseWholeString(MD_String8 filename, MD_String8 contents) // NOTE(allen): setup namespace structure MD_Node *namespaces = _MD_MakeNode_Ctx(&ctx, MD_NodeKind_List, MD_S8Lit(""), MD_S8Lit(""), ctx.at); - MD_Node *default_namespace = _MD_MakeNode_Ctx(&ctx, MD_NodeKind_List, - MD_S8Lit(""), MD_S8Lit(""), ctx.at); - MD_PushChild(namespaces, default_namespace); + MD_Map namespace_table = MD_MapMake(); - MD_Map namespace_table = {0}; - MD_StringMap_Insert(&namespace_table, MD_MapCollisionRule_Overwrite, default_namespace->string, default_namespace); + // NOTE(allen): setup default namespace + MD_Node *default_ns = _MD_MakeNode_Ctx(&ctx, MD_NodeKind_List, + MD_S8Lit(""), MD_S8Lit(""), ctx.at); + MD_PushChild(namespaces, default_ns); + MD_MapInsert(&namespace_table, MD_MapKeyStr(default_ns->string), default_ns); - // NOTE(allen): setup namespace + // NOTE(allen): parse loop MD_NodeFlags next_child_flags = 0; - MD_Node *selected_namespace = default_namespace; + MD_Node *selected_namespace = default_ns; for(;;) { // TODO(allen): I don't get it... this can only happen once between @@ -2115,20 +2052,19 @@ MD_ParseWholeString(MD_String8 filename, MD_String8 contents) MD_Token token = MD_ZERO_STRUCT; if(MD_Parse_RequireKind(&ctx, MD_TokenKind_Identifier, &token)) { - MD_MapSlot *existing_namespace_slot = MD_StringMap_Lookup(&namespace_table, token.string); - if(existing_namespace_slot == 0) - { + MD_MapKey ns_key = MD_MapKeyStr(token.string); + MD_MapSlot *ns_slot = MD_MapLookup(&namespace_table, ns_key); + if (ns_slot == 0){ MD_Node *ns = _MD_MakeNode_Ctx(&ctx, MD_NodeKind_List, token.string, token.string, token.outer_string.str); - MD_StringMap_Insert(&namespace_table, MD_MapCollisionRule_Overwrite, token.string, ns); - existing_namespace_slot = MD_StringMap_Lookup(&namespace_table, token.string); MD_PushChild(namespaces, ns); + ns_slot = MD_MapInsert(&namespace_table, ns_key, ns); } - selected_namespace = (MD_Node *)existing_namespace_slot->value; + selected_namespace = (MD_Node *)ns_slot->val; } else { - selected_namespace = default_namespace; + selected_namespace = default_ns; } } // NOTE(rjf): Not a valid hash thing diff --git a/tests/grammar.c b/tests/grammar.c index 6fbf939..de5a5ba 100644 --- a/tests/grammar.c +++ b/tests/grammar.c @@ -82,8 +82,8 @@ static MD_Node * NewChild(MD_Node *parent) #define OPTIONAL_TAG "optional" -#define GET_DEPTH(depth_map, node) ((MD_u64)MD_PtrMap_Lookup(depth_map, node)->value) -#define SET_DEPTH(depth_map, node, depth) MD_PtrMap_Insert(depth_map, MD_MapCollisionRule_Overwrite, node, (void *)(depth)) +#define GET_DEPTH(depth_map, node) ((MD_u64)MD_MapLookup(depth_map, MD_MapKeyPtr(node))->val) +#define SET_DEPTH(depth_map, node, depth) MD_MapOverwrite(depth_map, MD_MapKeyPtr(node), (void *)(depth)) static void PrintRule(MD_Map *depth_map, MD_Node *rule) { MD_b32 is_literal_char = rule->flags & MD_NodeFlag_CharLiteral; @@ -252,7 +252,7 @@ static void ExpandRule(MD_Node *rule, MD_String8List *out_strings, MD_Node *cur_ } else // NOTE(mal): Non-terminal production { - MD_Node * production = MD_StringMap_Lookup(globals.production_table, rule_element->string)->value; + MD_Node * production = MD_MapLookup(globals.production_table, MD_MapKeyStr(rule_element->string))->val; MD_Assert(production); ExpandProduction(production, out_strings, cur_node, op_flags, depth_map, max_depth, depth+1); } @@ -293,13 +293,13 @@ static MD_Node * FindNonTerminalProduction(MD_Node *node, MD_Map *visited) MD_b32 should_visit = 1; if(!MD_NodeIsNil(node->first_child) && node->string.size) { - if(MD_StringMap_Lookup(visited, node->string)) + if(MD_MapLookup(visited, MD_MapKeyStr(node->string))) { should_visit = 0; } else { - MD_b32 inserted = MD_StringMap_Insert(visited, MD_MapCollisionRule_Overwrite, node->string, node); + void *inserted = MD_MapOverwrite(visited, MD_MapKeyStr(node->string), node); MD_Assert(inserted); } } @@ -313,10 +313,10 @@ static MD_Node * FindNonTerminalProduction(MD_Node *node, MD_Map *visited) } else { - MD_MapSlot *slot = MD_StringMap_Lookup(globals.production_table, node->string); + MD_MapSlot *slot = MD_MapLookup(globals.production_table, MD_MapKeyStr(node->string)); if(slot) { - MD_Node *production = slot->value; + MD_Node *production = slot->val; result = FindNonTerminalProduction(production, visited); } else @@ -431,7 +431,7 @@ static void ComputeElementDepth(MD_Map *depth_map, MD_Node *re) } else { - MD_Node * production = MD_StringMap_Lookup(globals.production_table, re->string)->value; + MD_Node * production = MD_MapLookup(globals.production_table, MD_MapKeyStr(re->string))->val; result = GET_DEPTH(depth_map, production)+1; } } @@ -576,29 +576,29 @@ int main(int argument_count, char **arguments) } // NOTE(mal): Build production hash table - MD_Map production_table_ = {0}; + MD_Map production_table_ = MD_MapMake(); globals.production_table = &production_table_; for(MD_EachNode(production, productions->first_child)) { - MD_b32 inserted = MD_StringMap_Insert(globals.production_table, MD_MapCollisionRule_Overwrite, - production->string, production); + void *inserted = MD_MapOverwrite(globals.production_table, + MD_MapKeyStr(production->string), production); MD_Assert(inserted); } // NOTE(mal): Check for root production MD_Node* file_production = 0; { - MD_MapSlot *file_production_slot = MD_StringMap_Lookup(globals.production_table, MD_S8Lit("file")); + MD_MapSlot *file_production_slot = MD_MapLookup(globals.production_table, MD_MapKeyStr(MD_S8Lit("file"))); if(!file_production_slot) { fprintf(stderr, "Error: Grammar file does not specify \"file\" production\n"); goto error; } - file_production = file_production_slot->value; + file_production = file_production_slot->val; } // NOTE(mal): Check that all branches lead to terminal nodes - MD_Map visited_productions = {0}; + MD_Map visited_productions = MD_MapMake(); for(MD_EachNode(production, productions->first_child)) { @@ -613,7 +613,7 @@ int main(int argument_count, char **arguments) // NOTE(mal): Check that all productions are reachable for(MD_EachNode(production, productions->first_child)) { - MD_MapSlot *slot = MD_StringMap_Lookup(&visited_productions, production->string); + MD_MapSlot *slot = MD_MapLookup(&visited_productions, MD_MapKeyStr(production->string)); if(!slot) { fprintf(stderr, "Warning: Unreachable production \"%.*s\"\n", MD_StringExpand(production->string)); @@ -623,7 +623,7 @@ int main(int argument_count, char **arguments) // NOTE(mal): Compute depth of productions, rules, rule elements // NOTE(mal): Init all MD_Node depths to 0 - MD_Map depth_map_ = {0}; + MD_Map depth_map_ = MD_MapMake(); MD_Map *depth_map = &depth_map_; for(MD_EachNode(production, productions->first_child)) { @@ -660,7 +660,7 @@ int main(int argument_count, char **arguments) MD_Assert(MD_NodeIsNil(rule_element->first_child)); if(!(rule_element->flags & MD_NodeFlag_CharLiteral)) { - MD_Node * production = MD_StringMap_Lookup(globals.production_table, rule_element->string)->value; + MD_Node * production = MD_MapLookup(globals.production_table, MD_MapKeyStr(rule_element->string))->val; depth = GET_DEPTH(depth_map, production); } depth += 1; @@ -713,7 +713,7 @@ int main(int argument_count, char **arguments) RandomSeries random_series = rand_seed(0, 0); // NOTE(mal): Reproduceable globals.random_series = &random_series; - MD_Node* file_production_node = MD_StringMap_Lookup(globals.production_table, MD_S8Lit("file"))->value; + MD_Node* file_production_node = MD_MapLookup(globals.production_table, MD_MapKeyStr(MD_S8Lit("file")))->val; // NOTE(mal): Generate test_count unique tests, sorted by complexity MD_u32 test_count = 1000; diff --git a/tests/sanity_tests.c b/tests/sanity_tests.c index 8c5dc28..0b2f85d 100644 --- a/tests/sanity_tests.c +++ b/tests/sanity_tests.c @@ -500,53 +500,36 @@ int main(void) Test("Hash maps") { - MD_String8 keys[] = + MD_String8 key_strings[] = { MD_S8Lit("\xed\x80\x73\x71\x78\xba\xff\xd6\x87\x83\xcd\x20\x28\xf7\x1c\xc1\x5f\xca\x98\x9c\x5a\xab\x0c\xae\x9a\x60\x57\x03\xeb\x1f\xde\x99"), MD_S8Lit("\x4c\x80\xb7\x8b\xbf\x65\x5a\x4b\xc1\x2a\xc3\x5f\xe1\x66\xfb\x0d\x72\x83\x1c\x63\xba\xb5\x97\x02\x3f\x6a\xe0\x2a\x1b\x82\x07\x76"), MD_S8Lit("\xd8\xfd\x11\x4b\x04\xdf\xe5\x20\x5b\xd6\x4f\x87\x00\x70\x6a\xc8\xde\xed\xc7\x79\xdb\x87\x24\x36\xa8\x7a\x31\x41\x00\x57\xbd\x8d"), }; - // NOTE(mal): True for MD_HashString is djb2 - { - TestResult(MD_HashString(keys[0]) == 1 && MD_HashString(keys[1]) == 1 && MD_HashString(keys[2]) == 3); + MD_MapKey keys[MD_ArrayCount(key_strings)*2]; + for (MD_u64 i = 0; i < MD_ArrayCount(key_strings); i += 1){ + keys[i] = MD_MapKeyStr(key_strings[i]); + } + for (MD_u64 i = MD_ArrayCount(key_strings); i < MD_ArrayCount(keys); i += 1){ + keys[i] = MD_MapKeyPtr((void *)i); } { - MD_MapCollisionRule rules[] = { MD_MapCollisionRule_Chain, MD_MapCollisionRule_Overwrite }; - for(int i_rule = 0; i_rule < MD_ArrayCount(rules); ++i_rule) - { - MD_Map map = {0}; - MD_StringMap_Insert(&map, rules[i_rule], keys[0], (void *)0); - MD_StringMap_Insert(&map, rules[i_rule], keys[1], (void *)1); - MD_StringMap_Insert(&map, rules[i_rule], keys[2], (void *)2); - - MD_MapSlot *slot0 = MD_StringMap_Lookup(&map, keys[0]); - MD_MapSlot *slot1 = MD_StringMap_Lookup(&map, keys[1]); - MD_MapSlot *slot2 = MD_StringMap_Lookup(&map, keys[2]); - - TestResult(slot0 && slot0->value == (void *)0 && - slot1 && slot1->value == (void *)1 && - slot2 && slot2->value == (void *)2); + MD_Map map = MD_MapMake(); + for (MD_u64 i = 0; i < MD_ArrayCount(keys); i += 1){ + MD_MapInsert(&map, keys[i], (void *)i); } - } - - { - MD_MapCollisionRule rules[] = { MD_MapCollisionRule_Chain, MD_MapCollisionRule_Overwrite }; - for(int i_rule = 0; i_rule < MD_ArrayCount(rules); ++i_rule) - { - MD_Map map = {0}; - MD_PtrMap_Insert(&map, rules[i_rule], (void *)0, (void *)0); - MD_PtrMap_Insert(&map, rules[i_rule], (void *)1, (void *)1); - MD_PtrMap_Insert(&map, rules[i_rule], (void *)2, (void *)2); - - MD_MapSlot *slot0 = MD_PtrMap_Lookup(&map, (void *)0); - MD_MapSlot *slot1 = MD_PtrMap_Lookup(&map, (void *)1); - MD_MapSlot *slot2 = MD_PtrMap_Lookup(&map, (void *)2); - - TestResult(slot0 && slot0->value == (void *) 0 && - slot1 && slot1->value == (void *) 1 && - slot2 && slot2->value == (void *) 2); + for (MD_u64 i = 0; i < MD_ArrayCount(keys); i += 1){ + MD_MapSlot *slot = MD_MapLookup(&map, keys[i]); + TestResult(slot && slot->val == (void *)i); + } + for (MD_u64 i = 0; i < MD_ArrayCount(keys); i += 1){ + MD_MapOverwrite(&map, keys[i], (void *)(i + 10)); + } + for (MD_u64 i = 0; i < MD_ArrayCount(keys); i += 1){ + MD_MapSlot *slot = MD_MapLookup(&map, keys[i]); + TestResult(slot && slot->val == (void *)(i + 10)); } } }