1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
use hash::fnv;
use htab;
type ObjectRegistry = struct {
table: htab::table, // *Object
};
type Object = struct {
name: str,
};
def OBJREG_EMPTY = ObjectRegistry {
table = HTAB_EMPTY,
};
fn newobjreg() ObjectRegistry =
ObjectRegistry {
table = htab::new(0, size(*Object)),
};
fn objreg_eqfunc(ctx: *opaque, entry: *opaque) bool =
return *(ctx: *str) == (entry: **Object).name;
fn objreg_find(reg: *ObjectRegistry, name: str) nullable *opaque = {
const hash = fnv::string64(name);
match (htab::get(®.table, hash,
&objreg_eqfunc, &name, size(*Object))) {
case let entry: *opaque =>
return *(entry: **Object);
case null =>
return null;
};
};
fn objreg_register(reg: *ObjectRegistry, obj: *Object) void = {
assert(objreg_find(reg, obj.name) == null, "already registered");
const hash = fnv::string64(obj.name);
const entry = htab::add(®.table, hash, size(*Object));
*(entry: **Object) = obj;
};
fn objreg_count(reg: *ObjectRegistry) size =
htab::count(®.table);
fn objreg_clear(reg: *ObjectRegistry) void =
htab::clear(®.table, size(*Object));
type ObjectRegistryIterator = struct {
inner: htab::iterator,
};
fn objreg_iter(reg: *ObjectRegistry) ObjectRegistryIterator =
ObjectRegistryIterator {
inner = htab::iter(®.table),
};
fn objreg_next(it: *ObjectRegistryIterator) nullable *Object = {
match (htab::next(&it.inner, size(*Object))) {
case let entry: *opaque =>
return *(entry: **Object);
case null =>
return null;
};
};
|