getOrPut
Returns the backing byte slice and a boolean indicating if we found an existing entry
Parameters
Source
Implementation
pub fn getOrPut(self: *Data, gpa: std.mem.Allocator, key: Key, len: usize, alignment: u8, replace_existing: bool, debug: SavedData.DebugInfo) std.mem.Allocator.Error!struct { []u8, bool } {
const io = dvui.io;
self.mutex.lockUncancelable(io);
defer self.mutex.unlock(io);
if (replace_existing) try self.trash.ensureUnusedCapacity(gpa, 1);
const entry = try self.storage.getOrPut(gpa, key);
errdefer _ = self.storage.remove(key);
const should_trash = replace_existing and entry.found_existing and entry.value_ptr.data.len != len;
if (should_trash) {
// log.debug("dataSet: already had data for id {x} key {s}, freeing previous data\n", .{ id, key });
if (@TypeOf(debug) != void) {
if (!debug.eq(entry.value_ptr.debug)) {
std.debug.panic("Date.getOrPut: stored type {f} doesn't match asked for type {f}", .{ entry.value_ptr.debug, debug });
}
}
self.trash.appendAssumeCapacity(entry.value_ptr.*);
}
if (!entry.found_existing or should_trash) {
entry.value_ptr.* = .{
.alignment = alignment,
.data = if (len == 0) &.{} else if (gpa.rawAlloc(len, .fromByteUnits(alignment), @returnAddress())) |ptr| ptr[0..len] else return std.mem.Allocator.Error.OutOfMemory,
.debug = debug,
};
}
return .{ entry.value_ptr.data, entry.found_existing };
}