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