hashmap: use getOrPut
This commit is contained in:
parent
d9c8e69440
commit
00cf0e4a66
@ -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" {
|
||||||
|
Loading…
Reference in New Issue
Block a user