|
@@ -5,12 +5,14 @@ import (
|
|
|
"math/bits"
|
|
"math/bits"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
-// ruleSet is a set of rule ids, stored as a bitset. s[i] holds ids i*64 through i*64+63, one per bit.
|
|
|
|
|
-type ruleSet []uint64
|
|
|
|
|
|
|
+// ruleSet is a set of rule ids, stored as a bitset. s[i] holds ids i*8 through i*8+7, one per bit.
|
|
|
|
|
+// Bytes rather than words keep a set to the size the rule count needs, which matters when there is a set for
|
|
|
|
|
+// every port number.
|
|
|
|
|
+type ruleSet []uint8
|
|
|
|
|
|
|
|
// ruleSetLen returns the length of a ruleSet that can hold ids below n.
|
|
// ruleSetLen returns the length of a ruleSet that can hold ids below n.
|
|
|
func ruleSetLen(n int) int {
|
|
func ruleSetLen(n int) int {
|
|
|
- return (n + 63) / 64
|
|
|
|
|
|
|
+ return (n + 7) / 8
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// newRuleSet returns an empty set that can hold ids below idLimit.
|
|
// newRuleSet returns an empty set that can hold ids below idLimit.
|
|
@@ -20,21 +22,21 @@ func newRuleSet(idLimit int) ruleSet {
|
|
|
|
|
|
|
|
// add puts id in s.
|
|
// add puts id in s.
|
|
|
func (s ruleSet) add(id int) {
|
|
func (s ruleSet) add(id int) {
|
|
|
- s[id/64] |= 1 << (id % 64)
|
|
|
|
|
|
|
+ s[id/8] |= 1 << (id % 8)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// ruleSets holds several ruleSet objects of the same length in a single allocation.
|
|
// ruleSets holds several ruleSet objects of the same length in a single allocation.
|
|
|
type ruleSets struct {
|
|
type ruleSets struct {
|
|
|
- // setLen is the amount of uint64s needed to represent a full set
|
|
|
|
|
|
|
+ // setLen is the number of bytes needed to represent one set
|
|
|
setLen int
|
|
setLen int
|
|
|
// bits holds the sets in order. Set i starts at i*setLen.
|
|
// bits holds the sets in order. Set i starts at i*setLen.
|
|
|
- bits []uint64
|
|
|
|
|
|
|
+ bits []uint8
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// newRuleSets returns n empty sets, each of which can hold ids below idLimit.
|
|
// newRuleSets returns n empty sets, each of which can hold ids below idLimit.
|
|
|
func newRuleSets(n, idLimit int) ruleSets {
|
|
func newRuleSets(n, idLimit int) ruleSets {
|
|
|
setLen := ruleSetLen(idLimit)
|
|
setLen := ruleSetLen(idLimit)
|
|
|
- return ruleSets{setLen: setLen, bits: make([]uint64, n*setLen)}
|
|
|
|
|
|
|
+ return ruleSets{setLen: setLen, bits: make([]uint8, n*setLen)}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// at returns set i.
|
|
// at returns set i.
|
|
@@ -50,7 +52,7 @@ func (s ruleSets) at(i int) ruleSet {
|
|
|
func (s ruleSet) any(pred func(id int) bool) bool {
|
|
func (s ruleSet) any(pred func(id int) bool) bool {
|
|
|
for i, ids := range s {
|
|
for i, ids := range s {
|
|
|
for ids != 0 {
|
|
for ids != 0 {
|
|
|
- id := i*64 + bits.TrailingZeros64(ids)
|
|
|
|
|
|
|
+ id := i*8 + bits.TrailingZeros8(ids)
|
|
|
ids &= ids - 1 // Clear the lowest set bit, which is id's.
|
|
ids &= ids - 1 // Clear the lowest set bit, which is id's.
|
|
|
if pred(id) {
|
|
if pred(id) {
|
|
|
return true
|
|
return true
|
|
@@ -65,7 +67,7 @@ func (s ruleSet) all() iter.Seq[int] {
|
|
|
return func(yield func(int) bool) {
|
|
return func(yield func(int) bool) {
|
|
|
for i, ids := range s {
|
|
for i, ids := range s {
|
|
|
for ids != 0 {
|
|
for ids != 0 {
|
|
|
- id := i*64 + bits.TrailingZeros64(ids)
|
|
|
|
|
|
|
+ id := i*8 + bits.TrailingZeros8(ids)
|
|
|
ids &= ids - 1 // Clear the lowest set bit, which is id's.
|
|
ids &= ids - 1 // Clear the lowest set bit, which is id's.
|
|
|
if !yield(id) {
|
|
if !yield(id) {
|
|
|
return
|
|
return
|