packing shell sections
This commit is contained in:
@@ -7,11 +7,22 @@ const StringHashMap = std.StringHashMap;
|
||||
const BoundedArray = std.BoundedArray;
|
||||
const StringContext = std.hash_map.StringContext;
|
||||
|
||||
// MaxShells is the maximum number of "popular" shells.
|
||||
pub const MaxShells = 63;
|
||||
pub const MaxShellLen = 64;
|
||||
// maxShells is the maximum number of "popular" shells.
|
||||
pub const max_shells = 63;
|
||||
pub const max_shell_len = 64;
|
||||
const ShellAlignment = 2; // bits
|
||||
|
||||
// ShellIndex is an index to the shell strings. As shell can be up to 64 bytes
|
||||
// (1<<6), maximum number of shells is 63 (1<<6-1), the maximum location offset
|
||||
// is 1<<12. To make location resolvable in 10 bits, all shells will be padded
|
||||
// to 4 bytes.
|
||||
// The actual shell length is len+1: we don't allow empty shells, and the real
|
||||
// length of the shell is 1-64 bytes.
|
||||
const ShellIndex = packed struct {
|
||||
offset: u10,
|
||||
len: u6,
|
||||
};
|
||||
|
||||
// ShellReader interprets "Shell Index" and "Shell Blob" sections.
|
||||
pub const ShellReader = struct {
|
||||
sectionIndex: []const ShellIndex,
|
||||
@@ -44,19 +55,20 @@ pub const ShellWriter = struct {
|
||||
};
|
||||
|
||||
const ShellSections = struct {
|
||||
index: BoundedArray(ShellIndex, MaxShells),
|
||||
blob: BoundedArray(u8, MaxShells * MaxShellLen),
|
||||
index: BoundedArray(ShellIndex, max_shells),
|
||||
blob: BoundedArray(u8, max_shells * max_shell_len),
|
||||
indices: StringHashMap(u6),
|
||||
|
||||
// initializes and populates shell sections. All strings are copied,
|
||||
// nothing is owned.
|
||||
pub const initErr = Allocator.Error || error{Overflow};
|
||||
pub fn init(
|
||||
allocator: Allocator,
|
||||
shells: BoundedArray([]const u8, MaxShells),
|
||||
) !ShellSections {
|
||||
shells: BoundedArray([]const u8, max_shells),
|
||||
) initErr!ShellSections {
|
||||
var self = ShellSections{
|
||||
.index = try BoundedArray(ShellIndex, MaxShells).init(shells.len),
|
||||
.blob = try BoundedArray(u8, MaxShells * MaxShellLen).init(0),
|
||||
.index = try BoundedArray(ShellIndex, max_shells).init(shells.len),
|
||||
.blob = try BoundedArray(u8, max_shells * max_shell_len).init(0),
|
||||
.indices = StringHashMap(u6).init(allocator),
|
||||
};
|
||||
var fullOffset: u12 = 0;
|
||||
@@ -132,7 +144,8 @@ pub const ShellWriter = struct {
|
||||
// toOwnedSections returns the analyzed ShellSections. Resets the shell
|
||||
// popularity contest. ShellSections memory is allocated by the ShellWriter
|
||||
// allocator, and must be deInit'ed by the caller.
|
||||
pub fn toOwnedSections(self: *ShellWriter, limit: u10) !ShellSections {
|
||||
const toOwnedSectionsErr = Allocator.Error || error{Overflow};
|
||||
pub fn toOwnedSections(self: *ShellWriter, limit: u10) toOwnedSectionsErr!ShellSections {
|
||||
var deque = PriorityDequeue(KV, void, cmpShells).init(self.allocator, {});
|
||||
defer deque.deinit();
|
||||
|
||||
@@ -145,7 +158,7 @@ pub const ShellWriter = struct {
|
||||
}
|
||||
|
||||
const total = std.math.min(deque.count(), limit);
|
||||
var topShells = try BoundedArray([]const u8, MaxShells).init(total);
|
||||
var topShells = try BoundedArray([]const u8, max_shells).init(total);
|
||||
|
||||
var i: u32 = 0;
|
||||
while (i < total) : (i += 1) {
|
||||
@@ -161,17 +174,6 @@ pub const ShellWriter = struct {
|
||||
}
|
||||
};
|
||||
|
||||
// ShellIndex is an index to the shell strings. As shell can be up to 64 bytes
|
||||
// (1<<6), maximum number of shells is 63 (1<<6-1), the maximum location offset
|
||||
// is 1<<12. To make location resolvable in 10 bits, all shells will be padded
|
||||
// to 4 bytes.
|
||||
// The actual shell length is len+1: we don't allow empty shells, and the real
|
||||
// length of the shell is 1-64 bytes.
|
||||
const ShellIndex = packed struct {
|
||||
offset: u10,
|
||||
len: u6,
|
||||
};
|
||||
|
||||
const testing = std.testing;
|
||||
|
||||
test "basic shellpopcon" {
|
||||
@@ -192,7 +194,7 @@ test "basic shellpopcon" {
|
||||
try popcon.put(shell);
|
||||
}
|
||||
|
||||
var sections = try popcon.toOwnedSections(MaxShells);
|
||||
var sections = try popcon.toOwnedSections(max_shells);
|
||||
defer sections.deinit();
|
||||
try testing.expectEqual(sections.index.len, 3); // all but "nobody" qualify
|
||||
|
||||
|
||||
Reference in New Issue
Block a user