Skip to content

Commit 1f04c01

Browse files
committed
reduce allocations for union sets
1 parent 00a7c3f commit 1f04c01

File tree

1 file changed

+37
-24
lines changed

1 file changed

+37
-24
lines changed

coderd/authz/authztest/iterator.go

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,52 +18,65 @@ type iterator interface {
1818
Size() int
1919
}
2020

21-
// SetIterator is very primitive, just used to hold a place in a set.
22-
type SetIterator struct {
23-
i int
24-
set Set
21+
// unionIterator is very primitive, just used to hold a place in a set.
22+
type unionIterator struct {
23+
// setIdx determines which set the offset is for
24+
setIdx int
25+
// offset is which permission for a given setIdx
26+
offset int
27+
sets []Set
28+
// buffer is used to prevent allocations when `Permissions` is called, as we must
29+
// return a set.
2530
buffer Set
31+
32+
N int
2633
}
2734

28-
func union(sets ...Set) *SetIterator {
29-
all := Set{}
30-
for _, set := range sets {
31-
all = append(all, set...)
35+
func union(sets ...Set) *unionIterator {
36+
var n int
37+
for _, s := range sets {
38+
n += len(s)
3239
}
33-
return &SetIterator{
34-
i: 0,
35-
set: all,
40+
return &unionIterator{
41+
sets: sets,
3642
buffer: make(Set, 1),
43+
N: n,
3744
}
3845
}
3946

40-
func (si *SetIterator) Next() bool {
41-
si.i++
42-
return si.i < len(si.set)
47+
func (si *unionIterator) Next() bool {
48+
si.offset++
49+
if si.offset >= len(si.sets[si.setIdx]) {
50+
si.setIdx++
51+
si.offset = 0
52+
}
53+
54+
return si.setIdx >= len(si.sets)
4355
}
4456

45-
func (si *SetIterator) Permissions() Set {
46-
si.buffer[0] = si.set[si.i]
57+
func (si *unionIterator) Permissions() Set {
58+
si.buffer[0] = si.Permission()
4759
return si.buffer
4860
}
4961

50-
func (si *SetIterator) Permission() *Permission {
51-
return si.set[si.i]
62+
func (si unionIterator) Permission() *Permission {
63+
return si.sets[si.setIdx][si.offset]
5264
}
5365

54-
func (si *SetIterator) Reset() {
55-
si.i = 0
66+
func (si *unionIterator) Reset() {
67+
si.setIdx = 0
68+
si.offset = 0
5669
}
5770

58-
func (si *SetIterator) ReturnSize() int {
71+
func (si *unionIterator) ReturnSize() int {
5972
return 1
6073
}
6174

62-
func (si *SetIterator) Size() int {
63-
return len(si.set)
75+
func (si *unionIterator) Size() int {
76+
return si.N
6477
}
6578

66-
func (si *SetIterator) Iterator() iterator {
79+
func (si *unionIterator) Iterator() iterator {
6780
return si
6881
}
6982

0 commit comments

Comments
 (0)