sort and use unmanaged ArrayLists

This commit is contained in:
Motiejus Jakštys 2022-03-02 06:02:04 +02:00 committed by Motiejus Jakštys
parent e5870a95fe
commit 321d1f6afd

View File

@ -2,7 +2,7 @@ const std = @import("std");
const unicode = std.unicode; const unicode = std.unicode;
const sort = std.sort; const sort = std.sort;
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const ArrayList = std.ArrayList; const ArrayListUnmanaged = std.ArrayListUnmanaged;
const StringHashMap = std.StringHashMap; const StringHashMap = std.StringHashMap;
const AutoHashMap = std.AutoHashMap; const AutoHashMap = std.AutoHashMap;
const BufSet = std.BufSet; const BufSet = std.BufSet;
@ -26,8 +26,8 @@ const Corpus = struct {
uid2user: AutoHashMap(u32, *const User), uid2user: AutoHashMap(u32, *const User),
name2group: StringHashMap(*const Group), name2group: StringHashMap(*const Group),
gid2group: AutoHashMap(u32, *const Group), gid2group: AutoHashMap(u32, *const Group),
groupname2users: StringHashMap(ArrayList(*const User)), groupname2users: StringHashMap(ArrayListUnmanaged(*const User)),
username2groups: StringHashMap(ArrayList(*const Group)), username2groups: StringHashMap(ArrayListUnmanaged(*const Group)),
pub const initErr = Allocator.Error || pub const initErr = Allocator.Error ||
error{InvalidUtf8} || error{InvalidUtf8} ||
@ -86,10 +86,10 @@ const Corpus = struct {
res2.value_ptr.* = group; res2.value_ptr.* = group;
} }
var groupname2users = StringHashMap(ArrayList(*const User)).init(allocator); var groupname2users = StringHashMap(ArrayListUnmanaged(*const User)).init(allocator);
var username2groups = StringHashMap(ArrayList(*const Group)).init(allocator); var username2groups = StringHashMap(ArrayListUnmanaged(*const Group)).init(allocator);
for (groups) |*group| { for (groups) |*group| {
var members = try ArrayList(*const User).initCapacity( var members = try ArrayListUnmanaged(*const User).initCapacity(
allocator, allocator,
group.members.count(), group.members.count(),
); );
@ -104,9 +104,9 @@ const Corpus = struct {
var groupsOfMember = try username2groups.getOrPut(memberName.*); var groupsOfMember = try username2groups.getOrPut(memberName.*);
if (!groupsOfMember.found_existing) { if (!groupsOfMember.found_existing) {
groupsOfMember.value_ptr.* = ArrayList(*const Group).init(allocator); groupsOfMember.value_ptr.* = ArrayListUnmanaged(*const Group){};
} }
try groupsOfMember.value_ptr.*.append(group); try groupsOfMember.value_ptr.*.append(allocator, group);
} }
var result = try groupname2users.getOrPut(group.name); var result = try groupname2users.getOrPut(group.name);
@ -116,6 +116,20 @@ const Corpus = struct {
result.value_ptr.* = members; result.value_ptr.* = members;
} }
{
var it = groupname2users.valueIterator();
while (it.next()) |groupUsers| {
sort.sort(*const User, groupUsers.items, {}, cmpUserPtr);
}
}
{
var it = username2groups.valueIterator();
while (it.next()) |userGroups| {
sort.sort(*const Group, userGroups.items, {}, cmpGroupPtr);
}
}
return Corpus{ return Corpus{
.arena = arena, .arena = arena,
.users = users, .users = users,
@ -153,10 +167,18 @@ fn cmpUser(_: void, a: User, b: User) bool {
return true; return true;
} }
fn cmpUserPtr(context: void, a: *const User, b: *const User) bool {
return cmpUser(context, a.*, b.*);
}
fn cmpGroup(_: void, a: Group, b: Group) bool { fn cmpGroup(_: void, a: Group, b: Group) bool {
return a.gid < b.gid; return a.gid < b.gid;
} }
fn cmpGroupPtr(context: void, a: *const Group, b: *const Group) bool {
return cmpGroup(context, a.*, b.*);
}
const testing = std.testing; const testing = std.testing;
test "test corpus" { test "test corpus" {
@ -232,11 +254,10 @@ test "test corpus" {
try testing.expectEqual(corpus.gid2group.get(42), null); try testing.expectEqual(corpus.gid2group.get(42), null);
try testing.expectEqual(corpus.gid2group.get(1000).?.gid, 1000); try testing.expectEqual(corpus.gid2group.get(1000).?.gid, 1000);
// TODO: enable once sorted. const membersOfAll = corpus.groupname2users.get("all").?.items;
//const membersOfAll = corpus.groupname2users.get("all").?.items; try testing.expectEqualStrings(membersOfAll[0].name, "Name" ** 8);
//try testing.expectEqualStrings(membersOfAll[0].name, "Name" ** 8); try testing.expectEqualStrings(membersOfAll[1].name, "svc-bar");
//try testing.expectEqualStrings(membersOfAll[1].name, "svc-bar"); try testing.expectEqualStrings(membersOfAll[2].name, "vidmantas");
//try testing.expectEqualStrings(membersOfAll[2].name, "vidmantas");
const groupsOfVidmantas = corpus.username2groups.get("vidmantas").?.items; const groupsOfVidmantas = corpus.username2groups.get("vidmantas").?.items;
try testing.expectEqual(groupsOfVidmantas[0].gid, 1000); try testing.expectEqual(groupsOfVidmantas[0].gid, 1000);