/* * 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;