refactor: apply project style guidelines
This commit is contained in:
+8
-10
@@ -11,6 +11,8 @@ Entry proc($K, $V type) type {
|
||||
}
|
||||
}
|
||||
|
||||
#! owns entry storage and retains its allocator; release storage with deinit.
|
||||
#! keys and values are stored by value; any resources they reference remain caller-owned.
|
||||
HashMap proc(
|
||||
$K, $V type,
|
||||
$hash_key proc(key K) usize,
|
||||
@@ -27,6 +29,7 @@ StringHashMap proc($V type) type {
|
||||
return HashMap([]u8, V, str_hash, str_eql)
|
||||
}
|
||||
|
||||
#! retain allocator for later growth and cleanup; this call does not allocate.
|
||||
init proc(
|
||||
$K, $V type,
|
||||
$hash_key proc(key K) usize,
|
||||
@@ -40,7 +43,7 @@ init proc(
|
||||
}
|
||||
}
|
||||
|
||||
#! free the entries in the hash map.
|
||||
#! free owned entry storage using the retained allocator, not resources referenced by keys or values.
|
||||
#! note: this operation invalidates the map.
|
||||
deinit proc(
|
||||
$K, $V type,
|
||||
@@ -81,21 +84,17 @@ put proc(
|
||||
key K,
|
||||
value V,
|
||||
) void ! (PutError | mem.AllocError) {
|
||||
# check grow
|
||||
threshold :: map.entries.len - divtrunc!(map.entries.len, 4)
|
||||
if (map.entries.len == 0 or map.count + 1 > threshold) {
|
||||
old_entries :: map.entries
|
||||
new_size :: if (old_entries.len > 0) old_entries.len * 2 else 8
|
||||
new_entries :: try mem.alloc(Entry(K, V), map.allocator, new_size)
|
||||
|
||||
# zero new entries
|
||||
for (0..new_entries.len) |i| new_entries[i].hash = 0
|
||||
|
||||
# move old entries
|
||||
for old_entries |entry| {
|
||||
if (entry.hash == 0) continue
|
||||
|
||||
# find an empty slot
|
||||
idx := entry.hash & (new_entries.len - 1)
|
||||
while new_entries[idx].hash != 0 {
|
||||
idx = (idx + 1) & (new_entries.len - 1)
|
||||
@@ -108,7 +107,6 @@ put proc(
|
||||
mem.free(map.allocator, old_entries)
|
||||
}
|
||||
|
||||
# put new entry
|
||||
hash :: normalize(hash_key(key))
|
||||
idx := hash & (map.entries.len - 1)
|
||||
|
||||
@@ -132,7 +130,7 @@ put proc(
|
||||
}
|
||||
}
|
||||
|
||||
@hide
|
||||
@hide:file
|
||||
normalize proc(hash usize) usize {
|
||||
# mapping both 0 and 1 to 1 is safe because equality resolves
|
||||
# collisions (since hash and key must both be equal).
|
||||
@@ -142,10 +140,10 @@ normalize proc(hash usize) usize {
|
||||
|
||||
#! FNV-1a hash implementation.
|
||||
#! note: vulnerable to collision attacks.
|
||||
@hide
|
||||
@hide:file
|
||||
str_hash proc(key []u8) usize {
|
||||
hash u32 := 2166136261 # offset basis
|
||||
prime u32 := 16777619
|
||||
prime u32 :: 16777619
|
||||
|
||||
for key |byte| {
|
||||
product u64 :: u64(hash xor u32(byte)) * prime
|
||||
@@ -155,5 +153,5 @@ str_hash proc(key []u8) usize {
|
||||
return usize(hash)
|
||||
}
|
||||
|
||||
@hide
|
||||
@hide:file
|
||||
str_eql proc(a, b []u8) bool { return mem.eql(a, b) }
|
||||
|
||||
Reference in New Issue
Block a user