hashmap: use getOrPut

This commit is contained in:
Motiejus Jakštys 2022-02-17 11:04:32 +02:00 committed by Motiejus Jakštys
parent d9c8e69440
commit 00cf0e4a66

View File

@ -5,6 +5,7 @@ const StringArrayHashMap = std.StringArrayHashMap;
const StringHashMap = std.StringHashMap;
const BoundedArray = std.BoundedArray;
const testing = std.testing;
const StringContext = std.hash_map.StringContext;
// MaxShells is the maximum number of "popular" shells.
const MaxShells = 63;
@ -34,7 +35,7 @@ const ShellReader = struct {
}
// get returns a shell at the given index.
pub fn get(self: *ShellReader, idx: u10) []const u8 {
pub fn get(self: *const ShellReader, idx: u10) []const u8 {
const shellIndex = self.sectionIndex[idx];
const start = shellIndex.offset << 2;
const end = start + shellIndex.len + 1;
@ -88,11 +89,11 @@ const ShellWriter = struct {
return self;
}
pub fn sectionIndex(self: *ShellSections) []const u8 {
pub fn sectionIndex(self: *const ShellSections) []const u8 {
return @bitCast([]const u8, self.index.constSlice());
}
pub fn sectionBlob(self: *ShellSections) []const u8 {
pub fn sectionBlob(self: *const ShellSections) []const u8 {
return self.blob.constSlice();
}
@ -101,7 +102,7 @@ const ShellWriter = struct {
self.* = undefined;
}
pub fn getIndex(self: *ShellSections, shell: []const u8) ?u10 {
pub fn getIndex(self: *const ShellSections, shell: []const u8) ?u10 {
return self.indices.get(shell);
}
};
@ -123,14 +124,16 @@ const ShellWriter = struct {
}
pub fn put(self: *ShellWriter, shell: []const u8) !void {
// TODO getOrPutAdapted may be more elegant, not sure which
// context to pass.
if (self.counts.getPtr(shell)) |ptr| {
ptr.* += 1;
const res = try self.counts.getOrPutAdapted(shell, self.counts.ctx);
if (res.found_existing) {
res.value_ptr.* += 1;
} else {
var ourShell = try self.allocator.alloc(u8, shell.len);
// TODO(motiejus): can we avoid `ourShell` variable here?
const ourShell = try self.allocator.alloc(u8, shell.len);
std.mem.copy(u8, ourShell, shell);
try self.counts.put(ourShell, 1);
res.key_ptr.* = ourShell;
res.value_ptr.* = 1;
}
}
@ -160,7 +163,7 @@ const ShellWriter = struct {
var i: u32 = 0;
while (i < total) {
const elem: []const u8 = deque.removeMax().shell;
const elem = deque.removeMax().shell;
topShells.set(i, elem);
i += 1;
}
@ -206,21 +209,13 @@ test "basic shellpopcon" {
try testing.expectEqual(sections.getIndex(bash).?, 2);
try testing.expectEqual(sections.getIndex(nobody), null);
var shellReader = ShellReader.init(
const shellReader = ShellReader.init(
sections.sectionIndex(),
sections.sectionBlob(),
);
try testing.expectEqualStrings(shellReader.get(0), long);
try testing.expectEqualStrings(shellReader.get(1), zsh);
try testing.expectEqualStrings(shellReader.get(2), bash);
for ([_][]const u8{ long, zsh, bash }) |shell| {
const idx = sections.getIndex(shell).?;
const start = sections.index.get(idx).offset << 2;
const end = start + sections.index.get(idx).len + 1;
const got = sections.blob.constSlice()[start..end];
try testing.expectEqualStrings(got, shell);
}
}
test "padding" {