nctref/examples/MapDQCaLDhS.nct
2025-10-14 16:31:24 +03:00

112 lines
2.4 KiB
Plaintext

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