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. // cmpUser compares two users for sorting. By username's utf8 codepoints, ascending.
fn cmpUser(_: void, a: User, b: User) bool { fn cmpUser(_: void, a: User, b: User) bool {
var utf8_a = (unicode.Utf8View.init(a.name) catch unreachable).iterator(); 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()), 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{ return AllSections{
.allocator = allocator, .allocator = allocator,
.bdz_gid = bdz_gid, .bdz_gid = bdz_gid,
@ -423,8 +459,8 @@ pub const AllSections = struct {
.users = users, .users = users,
.group_members = group_members, .group_members = group_members,
.groups = groups, .groups = groups,
.idx_gid2group = undefined, .idx_gid2group = idx_gid2group,
.idx_groupname2group = undefined, .idx_groupname2group = idx_groupname2group,
.idx_uid2user = undefined, .idx_uid2user = undefined,
.idx_name2user = undefined, .idx_name2user = undefined,
}; };
@ -440,6 +476,8 @@ pub const AllSections = struct {
self.users.deinit(self.allocator); self.users.deinit(self.allocator);
self.group_members.deinit(self.allocator); self.group_members.deinit(self.allocator);
self.groups.deinit(self.allocator); self.groups.deinit(self.allocator);
self.allocator.free(self.idx_gid2group);
self.allocator.free(self.idx_groupname2group);
self.* = undefined; self.* = undefined;
} }
}; };
@ -649,3 +687,29 @@ test "users compare function" {
try testing.expect(cmpUser({}, b, bb)); try testing.expect(cmpUser({}, b, bb));
try testing.expect(!cmpUser({}, bb, b)); 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);
}
}