DoxigAlpha

getOrPutAssumeCapacityAdapted

Function parameters

Parameters

#
self:*Self
key:anytype
ctx:anytype

Type definitions in this namespace

Types

#

Functions in this namespace

Functions

#
StringHashMap
Builtin hashmap for strings as keys.
StringHashMapUnmanaged
Key memory is managed by the caller.
HashMap
General purpose hash table.
HashMapUnmanaged
A HashMap based on open addressing and linear probing.

= 80

Values

#

Source

Implementation

#
pub fn getOrPutAssumeCapacityAdapted(self: *Self, key: anytype, ctx: anytype) GetOrPutResult {

    // If you get a compile error on this line, it means that your generic hash
    // function is invalid for these parameters.
    const hash: Hash = ctx.hash(key);

    const mask = self.capacity() - 1;
    const fingerprint = Metadata.takeFingerprint(hash);
    var limit = self.capacity();
    var idx = @as(usize, @truncate(hash & mask));

    var first_tombstone_idx: usize = self.capacity(); // invalid index
    var metadata = self.metadata.? + idx;
    while (!metadata[0].isFree() and limit != 0) {
        if (metadata[0].isUsed() and metadata[0].fingerprint == fingerprint) {
            const test_key = &self.keys()[idx];
            // If you get a compile error on this line, it means that your generic eql
            // function is invalid for these parameters.

            if (ctx.eql(key, test_key.*)) {
                return GetOrPutResult{
                    .key_ptr = test_key,
                    .value_ptr = &self.values()[idx],
                    .found_existing = true,
                };
            }
        } else if (first_tombstone_idx == self.capacity() and metadata[0].isTombstone()) {
            first_tombstone_idx = idx;
        }

        limit -= 1;
        idx = (idx + 1) & mask;
        metadata = self.metadata.? + idx;
    }

    if (first_tombstone_idx < self.capacity()) {
        // Cheap try to lower probing lengths after deletions. Recycle a tombstone.
        idx = first_tombstone_idx;
        metadata = self.metadata.? + idx;
    }
    // We're using a slot previously free or a tombstone.
    self.available -= 1;

    metadata[0].fill(fingerprint);
    const new_key = &self.keys()[idx];
    const new_value = &self.values()[idx];
    new_key.* = undefined;
    new_value.* = undefined;
    self.size += 1;

    return GetOrPutResult{
        .key_ptr = new_key,
        .value_ptr = new_value,
        .found_existing = false,
    };
}