From c04c1a97c94a33558f4f9cec2b15d6106bd541cc Mon Sep 17 00:00:00 2001 From: Mid <> Date: Tue, 14 Oct 2025 16:31:24 +0300 Subject: [PATCH] MapDQCaLDhS for the standard library --- examples/MapDQCaLDhS.nct | 112 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 examples/MapDQCaLDhS.nct diff --git a/examples/MapDQCaLDhS.nct b/examples/MapDQCaLDhS.nct new file mode 100644 index 0000000..5675067 --- /dev/null +++ b/examples/MapDQCaLDhS.nct @@ -0,0 +1,112 @@ +/* + * MapDQCOaLDhS: Dynamically-allocated, Quadratic growth, C allocator, Interleaved KV values, Open-addressing, Linear probing, Dynamic hash, Flag tombstones + */ + +extern u8*(u8*, ugpr) calloc; + +record KVPair[K, V] { + K key; + V value; +} + +record MapDQCOaLDhS[K, V, S] { + S(K*)* hash; + + S capacity; + KVPair[K, V][?]* data; + u8[?]* occupied; +} + +MapDQCOaLDhS_try_add: [K, V, S]u1(MapDQCOaLDhS[K, V, S]* this, K* key, V* value) -> { + if(this.capacity == 0) { + this.capacity = 64; + this.data = calloc(this.capacity, @sizeof KVPair[K, V]); + this.occupied = calloc(this.capacity, @sizeof((*this.occupied)[0])); + } + + S capacity = this.capacity; + + S start = this.hash(key); + start = start & (capacity - 1); + + S index = start; + loop { + KVPair[K, V]* pair = &(*this.data)[index]; + if(pair.key == *key || (*this.occupied)[index] == 0) { + pair.key = *key; + pair.value = *value; + (*this.occupied)[index] = 1; + return 1; + } + index = (index + 1) & (capacity - 1); + if(index == start) { + return 0; + } + } +}; + +MapDQCOaLDhS_expand: [K, V, S]u1(MapDQCOaLDhS[K, V, S]* this) -> { + /* Unimplemented. */ + return 0; +}; + +MapDQCOaLDhS_add: [K, V, S]u1(MapDQCOaLDhS[K, V, S]* this, K* key, V* value) -> { + loop { + if(MapDQCOaLDhS_try_add[K, V, S](this, key, value) != 0) { + return 1; + } + if(MapDQCOaLDhS_expand[K, V, S](this) == 0) { + return 0; + } + } +}; + +MapDQCOaLDhS_get: [K, V, S]V*(MapDQCOaLDhS[K, V, S]* this, K* key) -> { + S capacity = this.capacity; + + if(capacity == 0) { + return null; + } + + S start = this.hash(key); + start = start & (capacity - 1); + + S index = start; + loop { + KVPair[K, V]* pair = &((*this.data)[index]); + if(pair.key == *key) { + if((*this.occupied)[index] == 0) { + return null; + } + return &pair.value; + } + index = (index + 1) & (capacity - 1); + if(index == start) { + return null; + } + } +}; + +zero_hash: ugpr(ugpr* val) -> { + return 0; +}; + +@instantiate MapDQCOaLDhS_try_add[ugpr, ugpr, ugpr]; +@instantiate MapDQCOaLDhS_expand[ugpr, ugpr, ugpr]; +@instantiate MapDQCOaLDhS_add[ugpr, ugpr, ugpr]; +@instantiate MapDQCOaLDhS_get[ugpr, ugpr, ugpr]; + +main: u0() -> { + map.hash = &zero_hash; + + ugpr test_key = 5; + MapDQCOaLDhS_get[ugpr, ugpr, ugpr](&map, &test_key); + MapDQCOaLDhS_add[ugpr, ugpr, ugpr](&map, &test_key, &test_value); + MapDQCOaLDhS_get[ugpr, ugpr, ugpr](&map, &test_key); +}; + +loop {} + +@section(".data"); +MapDQCOaLDhS[ugpr, ugpr, ugpr; 32] map:; +ugpr test_value: 10; \ No newline at end of file