group_members
This commit is contained in:
parent
4cc655de24
commit
d6ba7bed63
@ -102,17 +102,14 @@ const Corpus = struct {
|
||||
members.len += 1;
|
||||
members[members.len - 1] = user_idx;
|
||||
try user2groups[user_idx].append(allocator, @intCast(u32, i));
|
||||
} else {
|
||||
return error.NotFound;
|
||||
}
|
||||
} else return error.NotFound;
|
||||
}
|
||||
|
||||
group2users[i] = members;
|
||||
}
|
||||
|
||||
for (group2users) |*groupusers| {
|
||||
for (group2users) |*groupusers|
|
||||
sort.sort(u32, groupusers.*, {}, comptime sort.asc(u32));
|
||||
}
|
||||
|
||||
var user2groups_final = try allocator.alloc([]const u32, users.len);
|
||||
user2groups_final.len = users.len;
|
||||
@ -270,6 +267,7 @@ pub fn usersSection(
|
||||
pub const GroupMembers = struct {
|
||||
// group index to it's offset in blob
|
||||
idx2offset: []const u64,
|
||||
// members are delta-varint encoded byte-offsets to the user struct
|
||||
blob: []const u8,
|
||||
|
||||
pub fn deinit(self: *GroupMembers, allocator: Allocator) void {
|
||||
@ -291,8 +289,8 @@ pub fn groupMembers(
|
||||
// zero'th entry is empty, so empty groups can refer to it
|
||||
try compress.appendUvarint(&blob, 0);
|
||||
|
||||
var scratch = try allocator.alloc(u32, 256);
|
||||
defer allocator.free(scratch);
|
||||
var scratch = try ArrayList(u32).initCapacity(allocator, 1024);
|
||||
defer scratch.deinit();
|
||||
|
||||
for (corpus.group2users) |members, group_idx| {
|
||||
if (members.len == 0) {
|
||||
@ -300,16 +298,18 @@ pub fn groupMembers(
|
||||
continue;
|
||||
}
|
||||
|
||||
scratch = try allocator.realloc(scratch, members.len);
|
||||
scratch.len = members.len;
|
||||
mem.copy(u32, scratch, members);
|
||||
idx2offset[group_idx] = blob.items.len;
|
||||
try scratch.ensureTotalCapacity(members.len);
|
||||
scratch.items.len = members.len;
|
||||
for (members) |user_idx, i|
|
||||
scratch.items[i] = user2offset[user_idx];
|
||||
|
||||
compress.deltaCompress(u32, scratch) catch |err| switch (err) {
|
||||
compress.deltaCompress(u32, scratch.items) catch |err| switch (err) {
|
||||
error.NotSorted => unreachable,
|
||||
};
|
||||
try compress.appendUvarint(&blob, members.len);
|
||||
for (scratch) |user_idx|
|
||||
try compress.appendUvarint(&blob, user2offset[user_idx]);
|
||||
for (scratch.items) |elem|
|
||||
try compress.appendUvarint(&blob, elem);
|
||||
}
|
||||
return GroupMembers{
|
||||
.idx2offset = idx2offset,
|
||||
@ -325,9 +325,7 @@ fn cmpUser(_: void, a: User, b: User) bool {
|
||||
if (utf8_b.nextCodepoint()) |codepoint_b| {
|
||||
if (codepoint_a == codepoint_b) {
|
||||
continue;
|
||||
} else {
|
||||
return codepoint_a < codepoint_b;
|
||||
}
|
||||
} else return codepoint_a < codepoint_b;
|
||||
}
|
||||
|
||||
// a is a prefix of b. It is thus shorter.
|
||||
@ -373,11 +371,11 @@ pub const AllSections = struct {
|
||||
&user_gids,
|
||||
&shell_sections,
|
||||
);
|
||||
//const group_members = try groupMembers(
|
||||
// allocator,
|
||||
// corpus,
|
||||
// users.idx2offset,
|
||||
//);
|
||||
const group_members = try groupMembers(
|
||||
allocator,
|
||||
corpus,
|
||||
users.idx2offset,
|
||||
);
|
||||
return AllSections{
|
||||
.allocator = allocator,
|
||||
.bdz_gid = bdz_gid,
|
||||
@ -389,8 +387,7 @@ pub const AllSections = struct {
|
||||
.shell_blob = mem.sliceAsBytes(shell_blob.constSlice()),
|
||||
.user_gids = user_gids,
|
||||
.users = users,
|
||||
//.group_members = group_members,
|
||||
.group_members = undefined,
|
||||
.group_members = group_members,
|
||||
};
|
||||
}
|
||||
|
||||
@ -402,6 +399,7 @@ pub const AllSections = struct {
|
||||
self.shell_sections.deinit();
|
||||
self.user_gids.deinit(self.allocator);
|
||||
self.users.deinit(self.allocator);
|
||||
self.group_members.deinit(self.allocator);
|
||||
self.* = undefined;
|
||||
}
|
||||
};
|
||||
@ -512,13 +510,26 @@ test "test corpus" {
|
||||
try testing.expectEqual(groupsOfVidmantas[2], g_all);
|
||||
}
|
||||
|
||||
test "test sections" {
|
||||
test "test group members" {
|
||||
const allocator = testing.allocator;
|
||||
var corpus = try testCorpus(allocator);
|
||||
defer corpus.deinit();
|
||||
|
||||
var all = try AllSections.init(allocator, &corpus);
|
||||
defer all.deinit();
|
||||
var sections = try AllSections.init(allocator, &corpus);
|
||||
defer sections.deinit();
|
||||
|
||||
const blob = sections.group_members.blob;
|
||||
var group_idx: usize = 0;
|
||||
while (group_idx < corpus.groups.len) : (group_idx += 1) {
|
||||
const offset = sections.group_members.idx2offset[group_idx];
|
||||
var vit = try compress.VarintSliceIterator(blob[offset..]);
|
||||
var it = compress.DeltaDecompressionIterator(&vit);
|
||||
for (corpus.group2users[group_idx]) |user_idx| {
|
||||
const got_user_offset = (try it.next()).?;
|
||||
const want_user_offset = sections.users.idx2offset[user_idx];
|
||||
try testing.expectEqual(got_user_offset, want_user_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test "userGids" {
|
||||
@ -529,9 +540,10 @@ test "userGids" {
|
||||
var user_gids = try userGids(allocator, &corpus);
|
||||
defer user_gids.deinit(allocator);
|
||||
|
||||
for (corpus.users) |_, userIdx| {
|
||||
const groups = corpus.user2groups[userIdx];
|
||||
const offset = user_gids.idx2offset[userIdx];
|
||||
var user_idx: usize = 0;
|
||||
while (user_idx < corpus.users.len) : (user_idx += 1) {
|
||||
const groups = corpus.user2groups[user_idx];
|
||||
const offset = user_gids.idx2offset[user_idx];
|
||||
if (groups.len == 0) {
|
||||
try testing.expect(offset == 0);
|
||||
continue;
|
||||
|
@ -105,9 +105,7 @@ fn packedUser(comptime ShellIndexType: type) type {
|
||||
const name_len = self.nameLen();
|
||||
if (self.name_is_a_suffix) {
|
||||
return self.homeLen() - name_len;
|
||||
} else {
|
||||
return self.homeLen();
|
||||
}
|
||||
} else return self.homeLen();
|
||||
}
|
||||
|
||||
fn nameLen(self: *const Inner) usize {
|
||||
@ -117,9 +115,7 @@ fn packedUser(comptime ShellIndexType: type) type {
|
||||
fn gecosStart(self: *const Inner) usize {
|
||||
if (self.name_is_a_suffix) {
|
||||
return self.homeLen();
|
||||
} else {
|
||||
return self.homeLen() + self.nameLen();
|
||||
}
|
||||
} else return self.homeLen() + self.nameLen();
|
||||
}
|
||||
|
||||
fn gecosLen(self: *const Inner) usize {
|
||||
|
Loading…
Reference in New Issue
Block a user