Bdz index helper

This commit is contained in:
Motiejus Jakštys 2022-03-15 07:47:52 +02:00 committed by Motiejus Jakštys
parent 92ee170d54
commit 0a0559824a

View File

@ -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);
}
}