From 0a0559824a4923fc5fbd77c18c2654fb15a14a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Motiejus=20Jak=C5=A1tys?= Date: Tue, 15 Mar 2022 07:47:52 +0200 Subject: [PATCH] Bdz index helper --- src/sections.zig | 68 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/src/sections.zig b/src/sections.zig index 79db780..f1b8ae4 100644 --- a/src/sections.zig +++ b/src/sections.zig @@ -340,6 +340,29 @@ pub fn groupsSection( }; } +// creates a bdz index using packed_mphf. buf[bdz_search(key)] = index(keys, key) +pub fn bdzIdx( + comptime T: type, + allocator: Allocator, + packed_mphf: []const u8, + keys: []const T, +) error{OutOfMemory}![]const u32 { + const search_fn = comptime blk: { + switch (T) { + u32 => break :blk bdz.search_u32, + []const u8 => break :blk bdz.search, + else => unreachable, + } + }; + std.debug.assert(keys.len <= math.maxInt(u32)); + var result = try allocator.alloc(u32, keys.len); + for (keys) |key, i| { + const hash = search_fn(packed_mphf, key); + result[hash] = @intCast(u32, i); + } + return result; +} + // cmpUser compares two users for sorting. By username's utf8 codepoints, ascending. fn cmpUser(_: void, a: User, b: User) bool { var utf8_a = (unicode.Utf8View.init(a.name) catch unreachable).iterator(); @@ -411,6 +434,19 @@ pub const AllSections = struct { mem.sliceAsBytes(shell_sections.blob.constSlice()), ); + var idx_gid2group = try bdzIdx( + u32, + allocator, + bdz_gid, + corpus.groupsm.items(.gid), + ); + var idx_groupname2group = try bdzIdx( + []const u8, + allocator, + bdz_gid, + corpus.groupsm.items(.name), + ); + return AllSections{ .allocator = allocator, .bdz_gid = bdz_gid, @@ -423,8 +459,8 @@ pub const AllSections = struct { .users = users, .group_members = group_members, .groups = groups, - .idx_gid2group = undefined, - .idx_groupname2group = undefined, + .idx_gid2group = idx_gid2group, + .idx_groupname2group = idx_groupname2group, .idx_uid2user = undefined, .idx_name2user = undefined, }; @@ -440,6 +476,8 @@ pub const AllSections = struct { self.users.deinit(self.allocator); self.group_members.deinit(self.allocator); self.groups.deinit(self.allocator); + self.allocator.free(self.idx_gid2group); + self.allocator.free(self.idx_groupname2group); self.* = undefined; } }; @@ -649,3 +687,29 @@ test "users compare function" { try testing.expect(cmpUser({}, b, bb)); try testing.expect(!cmpUser({}, bb, b)); } + +test "bdzIdx" { + const allocator = testing.allocator; + const k_u32 = [_]u32{ 42, 1, 2, 3 }; + const k_str = [_][]const u8{ "42", "1", "2", "3" }; + const mphf_str = try cmph.packStr(allocator, k_str[0..]); + const mphf_u32 = try cmph.packU32(allocator, k_u32[0..]); + defer allocator.free(mphf_str); + defer allocator.free(mphf_u32); + + { + var result = try bdzIdx(u32, allocator, mphf_u32, k_u32[0..]); + defer allocator.free(result); + var used = [_]bool{false} ** 4; + for (result) |elem| used[result[elem]] = true; + for (used) |item| try testing.expect(item); + } + + { + var result = try bdzIdx([]const u8, allocator, mphf_str, k_str[0..]); + defer allocator.free(result); + var used = [_]bool{false} ** 4; + for (result) |elem| used[result[elem]] = true; + for (used) |item| try testing.expect(item); + } +}