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