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