@@ -18,52 +18,65 @@ type iterator interface {
18
18
Size () int
19
19
}
20
20
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.
25
30
buffer Set
31
+
32
+ N int
26
33
}
27
34
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 )
32
39
}
33
- return & SetIterator {
34
- i : 0 ,
35
- set : all ,
40
+ return & unionIterator {
41
+ sets : sets ,
36
42
buffer : make (Set , 1 ),
43
+ N : n ,
37
44
}
38
45
}
39
46
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 )
43
55
}
44
56
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 ()
47
59
return si .buffer
48
60
}
49
61
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 ]
52
64
}
53
65
54
- func (si * SetIterator ) Reset () {
55
- si .i = 0
66
+ func (si * unionIterator ) Reset () {
67
+ si .setIdx = 0
68
+ si .offset = 0
56
69
}
57
70
58
- func (si * SetIterator ) ReturnSize () int {
71
+ func (si * unionIterator ) ReturnSize () int {
59
72
return 1
60
73
}
61
74
62
- func (si * SetIterator ) Size () int {
63
- return len ( si .set )
75
+ func (si * unionIterator ) Size () int {
76
+ return si .N
64
77
}
65
78
66
- func (si * SetIterator ) Iterator () iterator {
79
+ func (si * unionIterator ) Iterator () iterator {
67
80
return si
68
81
}
69
82
0 commit comments