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