diff --git a/src/shellpop.zig b/src/shellpop.zig index ad39c49..c9589b2 100644 --- a/src/shellpop.zig +++ b/src/shellpop.zig @@ -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); }