Improve memory safety of hash table

This commit is contained in:
kayomn 2022-10-15 21:08:52 +01:00
parent 2792f27473
commit 98372cc85f
1 changed files with 20 additions and 16 deletions

View File

@ -56,16 +56,18 @@ pub fn Hashed(comptime Key: type, comptime Value: type,
}
///
/// Searches for `key` to delete it, returning the deleted value or `null` if no matching
/// key was found.
/// Searches for `key` and deletes it from `self.
///
pub fn remove(self: Self, key: Key) ?Value {
/// The removed value is returned or `null` if no key matching `key` was found.
///
pub fn remove(self: *Self, key: Key) ?Value {
var bucket = &(self.buckets[@mod(key_context.hash(key), self.buckets.len)]);
if (bucket.maybe_entry) |*entry| if (key_context.equals(entry.key, key)) {
defer entry.value = null;
self.filled -= 1;
defer {
bucket.maybe_entry = null;
self.filled -= 1;
}
return entry.value;
};
@ -74,9 +76,10 @@ pub fn Hashed(comptime Key: type, comptime Value: type,
bucket = &(self.buckets[index]);
if (bucket.maybe_entry) |*entry| if (key_context.equals(entry.key, key)) {
defer entry.value = null;
self.filled -= 1;
defer {
bucket.maybe_entry = null;
self.filled -= 1;
}
return entry.value;
};
@ -129,20 +132,21 @@ pub fn Hashed(comptime Key: type, comptime Value: type,
}
///
/// Searches for a value indexed with `key` in `self`, returning it or `null` if no matching
/// entry was found.
/// Searches for a value indexed with `key` in `self`.
///
pub fn lookup(self: Self, key: Key) ?*Value {
/// The found value is returned or `null` if an key matching `key` failed to be found.
///
pub fn lookup(self: Self, key: Key) ?Value {
var bucket = &(self.buckets[@mod(key_context.hash(key), self.buckets.len)]);
if (bucket.maybe_entry) |*entry|
if (key_context.equals(entry.key, key)) return &entry.value;
if (bucket.maybe_entry) |entry|
if (key_context.equals(entry.key, key)) return entry.value;
while (bucket.maybe_next_index) |index| {
bucket = &(self.buckets[index]);
if (bucket.maybe_entry) |*entry|
if (key_context.equals(entry.key, key)) return &entry.value;
if (bucket.maybe_entry) |entry|
if (key_context.equals(entry.key, key)) return entry.value;
}
return null;