Skip to content

Commit

Permalink
rethink iterator generators and table init state
Browse files Browse the repository at this point in the history
- don't init uninitialized table
- simplify code
  • Loading branch information
gaissmai committed Aug 29, 2024
1 parent 0f0814d commit 04eabeb
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 45 deletions.
9 changes: 0 additions & 9 deletions node.go
Original file line number Diff line number Diff line change
Expand Up @@ -564,15 +564,6 @@ func (n *node[V]) allRecSorted(path [16]byte, depth int, is4 bool, yield func(ne
return true
}

// numPrefixesRec, calculate the number of prefixes under n.
func (n *node[V]) numPrefixesRec() int {
size := len(n.prefixes) // this node
for _, c := range n.children {
size += c.numPrefixesRec()
}
return size
}

// numNodesRec, calculate the number of nodes under n.
func (n *node[V]) numNodesRec() int {
size := 1 // this node
Expand Down
36 changes: 16 additions & 20 deletions table.go
Original file line number Diff line number Diff line change
Expand Up @@ -531,22 +531,6 @@ func (t *Table[V]) OverlapsPrefix(pfx netip.Prefix) bool {
// Overlaps reports whether any IP in the table is matched by a route in the
// other table or vice versa.
func (t *Table[V]) Overlaps(o *Table[V]) bool {
if t.Size() == 0 || o.Size() == 0 {
return false
}

// t and o are already intialized (size != 0)

// at least one v4 is empty
if t.size4 == 0 || o.size4 == 0 {
return t.Overlaps6(o)
}

// at least one v6 is empty
if t.size6 == 0 || o.size6 == 0 {
return t.Overlaps4(o)
}

return t.Overlaps4(o) || t.Overlaps6(o)
}

Expand All @@ -557,7 +541,7 @@ func (t *Table[V]) Overlaps4(o *Table[V]) bool {
return false
}

// t and o are already intialized (size != 0)
// t and o are already intialized (size4 != 0)
return t.root4.overlapsRec(o.root4)
}

Expand All @@ -568,7 +552,7 @@ func (t *Table[V]) Overlaps6(o *Table[V]) bool {
return false
}

// t and o are already intialized (size != 0)
// t and o are already intialized (size6 != 0)
return t.root6.overlapsRec(o.root6)
}

Expand Down Expand Up @@ -630,11 +614,23 @@ func (t *Table[V]) Size6() int {
return t.size6
}

// nodes, calculates the IPv4 and IPv6 nodes and returns the sum.
// nodes, calculates the nodes.
func (t *Table[V]) nodes() int {
return t.nodes4() + t.nodes6()
}

// nodes4, calculates the IPv4 nodes.
func (t *Table[V]) nodes4() int {
if !t.isInit() {
return 0
}
return t.root4.numNodesRec()
}

return t.root4.numNodesRec() + t.root6.numNodesRec()
// nodes6, calculates the IPv6 nodes.
func (t *Table[V]) nodes6() int {
if !t.isInit() {
return 0
}
return t.root6.numNodesRec()
}
30 changes: 24 additions & 6 deletions table_iter.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,48 +139,66 @@ func (t *Table[V]) Subnets(pfx netip.Prefix) func(yield func(netip.Prefix, V) bo
// is not specified and is not guaranteed to be the same from one call to the
// next.
func (t *Table[V]) All() func(yield func(pfx netip.Prefix, val V) bool) {
t.init()
return func(yield func(netip.Prefix, V) bool) {
if !t.isInit() {
return
}

_ = t.root4.allRec(zeroPath, 0, true, yield) && t.root6.allRec(zeroPath, 0, false, yield)
}
}

// All4, like [Table.All] but only for the v4 routing table.
func (t *Table[V]) All4() func(yield func(pfx netip.Prefix, val V) bool) {
t.init()
return func(yield func(netip.Prefix, V) bool) {
if !t.isInit() {
return
}

_ = t.root4.allRec(zeroPath, 0, true, yield)
}
}

// All6, like [Table.All] but only for the v6 routing table.
func (t *Table[V]) All6() func(yield func(pfx netip.Prefix, val V) bool) {
t.init()
return func(yield func(netip.Prefix, V) bool) {
if !t.isInit() {
return
}

_ = t.root6.allRec(zeroPath, 0, false, yield)
}
}

// AllSorted returns an iterator over key-value pairs from Table in natural CIDR sort order.
func (t *Table[V]) AllSorted() func(yield func(pfx netip.Prefix, val V) bool) {
t.init()
return func(yield func(netip.Prefix, V) bool) {
if !t.isInit() {
return
}

_ = t.root4.allRecSorted(zeroPath, 0, true, yield) && t.root6.allRecSorted(zeroPath, 0, false, yield)
}
}

// AllSorted4, like [Table.AllSorted] but only for the v4 routing table.
func (t *Table[V]) AllSorted4() func(yield func(pfx netip.Prefix, val V) bool) {
t.init()
return func(yield func(netip.Prefix, V) bool) {
if !t.isInit() {
return
}

_ = t.root4.allRecSorted(zeroPath, 0, true, yield)
}
}

// AllSorted6, like [Table.AllSorted] but only for the v6 routing table.
func (t *Table[V]) AllSorted6() func(yield func(pfx netip.Prefix, val V) bool) {
t.init()
return func(yield func(netip.Prefix, V) bool) {
if !t.isInit() {
return
}

_ = t.root6.allRecSorted(zeroPath, 0, false, yield)
}
}
10 changes: 0 additions & 10 deletions table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1726,16 +1726,6 @@ func TestSize(t *testing.T) {
if golden6 != rtbl.Size6() {
t.Errorf("Size6: want: %d, got: %d", golden6, rtbl.Size6())
}

size4Rec := rtbl.root4.numPrefixesRec()
if golden4 != size4Rec {
t.Errorf("size4Rec: want: %d, got: %d", golden4, size4Rec)
}

size6Rec := rtbl.root6.numPrefixesRec()
if golden6 != size6Rec {
t.Errorf("size6Rec: want: %d, got: %d", golden6, size6Rec)
}
}

// ############ benchmarks ################################
Expand Down

0 comments on commit 04eabeb

Please sign in to comment.