add a test for resolving offsets

This commit is contained in:
Motiejus Jakštys 2022-02-16 11:48:53 +02:00 committed by Motiejus Jakštys
parent e55d01ed15
commit 67e8a1d83c

View File

@ -25,41 +25,38 @@ const ShellPopcon = struct {
counts: std.StringHashMap(u32),
allocator: Allocator,
const Self = @This();
const KV = struct {
shell: []const u8,
score: u32,
};
const KV = struct { shell: []const u8, score: u32 };
const ShellSections = struct {
index: BoundedArray(ShellIndex, MaxShells),
blob: BoundedArray(u8, MaxShells * MaxShellLen),
indices: StringHashMap(u10),
offsets: StringHashMap(u10),
// initializes and populates shell sections. All strings are copied, nothing is owned.
pub fn init(allocator: Allocator, shells: BoundedArray([]const u8, MaxShells)) !ShellSections {
// initializes and populates shell sections. All strings are copied,
// nothing is owned.
pub fn init(
allocator: Allocator,
shells: BoundedArray([]const u8, MaxShells),
) !ShellSections {
var self = ShellSections{
.index = try BoundedArray(ShellIndex, MaxShells).init(shells.len),
.blob = try BoundedArray(u8, MaxShells * MaxShellLen).init(0),
.offsets = StringHashMap(u10).init(allocator),
.indices = StringHashMap(u10).init(allocator),
};
var offset: u10 = 0;
var idx: u10 = 0;
while (idx < shells.len) {
//const stderr = std.io.getStdErr().writer();
//try stderr.print("\n", .{});
const len = @intCast(u6, shells.get(idx).len);
try self.blob.appendSlice(shells.get(idx));
const ourShell = self.blob.constSlice()[offset .. offset + len];
try self.offsets.put(ourShell, idx);
try self.indices.put(ourShell, idx);
self.index.set(idx, ShellIndex{
.offset = offset >> 2, // all shells are padded by 4
.offset = offset >> 2,
.len = len,
});
offset += len;
// if offset is not multiple by 4, make it so, and append the offset.
// Padd padding to make offset divisible by 4.
const padding = (offset + 3) & ~@intCast(u10, 3);
offset += padding;
try self.blob.appendNTimes(0, padding);
@ -69,12 +66,12 @@ const ShellPopcon = struct {
}
pub fn deinit(self: *ShellSections) void {
self.offsets.deinit();
self.indices.deinit();
self.* = undefined;
}
pub fn getOffset(self: *ShellSections, shell: []const u8) ?u10 {
return self.offsets.get(shell);
pub fn getIndex(self: *ShellSections, shell: []const u8) ?u10 {
return self.indices.get(shell);
}
};
@ -167,7 +164,21 @@ test "basic shellpopcon" {
defer sections.deinit();
try testing.expectEqual(sections.index.len, 3); // all but "nobody" qualify
try testing.expectEqual(sections.getOffset(long).?, 0);
try testing.expectEqual(sections.getOffset(zsh).?, 1);
try testing.expectEqual(sections.getOffset(bash).?, 2);
// TODO(motiejus): reverse the arguments: first should be "expected".
try testing.expectEqual(sections.getIndex(long).?, 0);
try testing.expectEqual(sections.getIndex(zsh).?, 1);
try testing.expectEqual(sections.getIndex(bash).?, 2);
try testing.expectEqual(sections.getIndex(nobody), null);
const longIndex = sections.getIndex(long).?;
const start = sections.index.get(longIndex).offset << 2;
const end = start + sections.index.get(longIndex).len;
const gotLong = sections.blob.constSlice()[start..end];
const stderr = std.io.getStdErr().writer();
try stderr.print("\n", .{});
try stderr.print("gotLong: {s}\n", .{gotLong});
try stderr.print(" long: {s}\n", .{long});
try testing.expectEqual(gotLong, long);
}