Skip to content

Commit

Permalink
naming
Browse files Browse the repository at this point in the history
  • Loading branch information
gaissmai committed Jan 4, 2025
1 parent e1d123c commit f8f1778
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 60 deletions.
24 changes: 13 additions & 11 deletions node.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,36 +120,38 @@ func (n *node[V]) nodeAndLeafCountRec() (int, int) {
// that collides with a leaf, the compressed leaf is then reinserted
// one depth down in the node trie.
func (n *node[V]) insertAtDepth(pfx netip.Prefix, val V, depth int) (exists bool) {
octets := pfx.Addr().AsSlice()
bits := pfx.Bits()

// 10.0.0.0/8 -> 0
// 10.12.0.0/15 -> 1
// 10.12.0.0/16 -> 1
// 10.12.10.9/32 -> 3
sigOctetIdx := (bits - 1) / strideLen
significantIdx := (bits - 1) / strideLen

// 10.0.0.0/8 -> 8
// 10.12.0.0/15 -> 7
// 10.12.0.0/16 -> 8
// 10.12.10.9/32 -> 8
significantBits := bits - (significantIdx * strideLen)

// 10.0.0.0/8 -> 10
// 10.12.0.0/15 -> 12
// 10.12.0.0/16 -> 12
// 10.12.10.9/32 -> 9
// sigOctet := octets[sigOctetIdx]
// significantOctet := octets[significantIdx]

// 10.0.0.0/8 -> 8
// 10.12.0.0/15 -> 7
// 10.12.0.0/16 -> 8
// 10.12.10.9/32 -> 8
sigOctetBits := bits - (sigOctetIdx * strideLen)
octets := pfx.Addr().AsSlice()
octets = octets[:significantIdx+1]

// find the proper trie node to insert prefix
// start with prefix octet at depth
for ; depth <= sigOctetIdx; depth++ {
for ; depth < len(octets); depth++ {
octet := octets[depth]
addr := uint(octet)

// last significant octet: insert/override prefix/val into node
if depth == sigOctetIdx {
return n.prefixes.InsertAt(pfxToIdx(octet, sigOctetBits), val)
if depth == significantIdx {
return n.prefixes.InsertAt(pfxToIdx(octet, significantBits), val)
}

if !n.children.Test(addr) {
Expand Down
2 changes: 1 addition & 1 deletion node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func TestOverlapsNode(t *testing.T) {
}

gotGold := gold.strideOverlaps(&goldInter)
gotFast := fast.overlapsRec(fastInter, 0)
gotFast := fast.overlaps(fastInter, 0)
if gotGold != gotFast {
t.Fatalf("node.overlaps = %v, want %v", gotFast, gotGold)
}
Expand Down
15 changes: 8 additions & 7 deletions overlaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"github.com/gaissmai/bart/internal/bitset"
)

// overlapsRec returns true if any IP in the nodes n or o overlaps.
func (n *node[V]) overlapsRec(o *node[V], depth int) bool {
// overlaps returns true if any IP in the nodes n or o overlaps.
func (n *node[V]) overlaps(o *node[V], depth int) bool {
nPfxCount := n.prefixes.Len()
oPfxCount := o.prefixes.Len()

Expand Down Expand Up @@ -69,7 +69,7 @@ func (n *node[V]) overlapsRec(o *node[V], depth int) bool {
return false
}

return n.overlapsSameChildrenRec(o, depth)
return n.overlapsSameChildren(o, depth)
}

// overlapsRoutes, test if n overlaps o prefixes and vice versa
Expand Down Expand Up @@ -170,8 +170,8 @@ func (n *node[V]) overlapsChildrenIn(o *node[V]) bool {
return prefixRoutes.IntersectionCardinality(hostRoutes) > 0
}

// overlapsSameChildrenRec, find same octets with bitset intersection.
func (n *node[V]) overlapsSameChildrenRec(o *node[V], depth int) bool {
// overlapsSameChildren, find same octets with bitset intersection.
func (n *node[V]) overlapsSameChildren(o *node[V], depth int) bool {
var nChildrenBitsetCloned bitset.BitSet = make([]uint64, 4)
copy(nChildrenBitsetCloned, n.children.BitSet)

Expand Down Expand Up @@ -207,7 +207,7 @@ func overlapsTwoChilds[V any](nChild, oChild any, depth int) bool {
case *node[V]:
switch oKind := oChild.(type) {
case *node[V]: // node, node
return nKind.overlapsRec(oKind, depth+1) // node, node
return nKind.overlaps(oKind, depth+1) // node, node
case *leaf[V]: // node, leaf
return nKind.overlapsPrefixAtDepth(oKind.prefix, depth) // node, node
}
Expand Down Expand Up @@ -236,8 +236,9 @@ func (n *node[V]) overlapsPrefixAtDepth(pfx netip.Prefix, depth int) bool {
sigOctetBits := bits - (sigOctetIdx * strideLen)

octets := ip.AsSlice()
octets = octets[:sigOctetIdx+1]

for ; depth <= sigOctetIdx; depth++ {
for ; depth < len(octets); depth++ {
octet := octets[depth]
addr := uint(octet)

Expand Down
80 changes: 39 additions & 41 deletions table.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,14 @@ func (t *Table[V]) Update(pfx netip.Prefix, cb func(val V, ok bool) V) (newVal V
n := t.rootNodeByVersion(is4)

octets := ip.AsSlice()
sigOctetIdx := (bits - 1) / strideLen
sigOctetBits := bits - (sigOctetIdx * strideLen)
significantIdx := (bits - 1) / strideLen
significantBits := bits - (significantIdx * strideLen)

// find the proper trie node to update prefix
for depth, octet := range octets {
// last octet from prefix, update/insert prefix into node
if depth == sigOctetIdx {
newVal, exists := n.prefixes.UpdateAt(pfxToIdx(octet, sigOctetBits), cb)
if depth == significantIdx {
newVal, exists := n.prefixes.UpdateAt(pfxToIdx(octet, significantBits), cb)
if !exists {
t.sizeUpdate(is4, 1)
}
Expand Down Expand Up @@ -170,8 +170,8 @@ func (t *Table[V]) getAndDelete(pfx netip.Prefix) (val V, ok bool) {
n := t.rootNodeByVersion(is4)

octets := ip.AsSlice()
sigOctetIdx := (bits - 1) / strideLen
sigOctetBits := bits - (sigOctetIdx * strideLen)
significantIdx := (bits - 1) / strideLen
significantBits := bits - (significantIdx * strideLen)

// record path to deleted node
// needed to purge and/or path compress nodes after deletion
Expand All @@ -184,8 +184,8 @@ LOOP:
stack[depth] = n

// try to delete prefix in trie node
if depth == sigOctetIdx {
if val, ok = n.prefixes.DeleteAt(pfxToIdx(octet, sigOctetBits)); ok {
if depth == significantIdx {
if val, ok = n.prefixes.DeleteAt(pfxToIdx(octet, significantBits)); ok {
t.sizeUpdate(is4, -1)
n.purgeAndCompress(stack[:depth], octets, is4)
return val, ok
Expand Down Expand Up @@ -242,14 +242,14 @@ func (t *Table[V]) Get(pfx netip.Prefix) (val V, ok bool) {
n := t.rootNodeByVersion(is4)

octets := ip.AsSlice()
sigOctetIdx := (bits - 1) / strideLen
sigOctetBits := bits - (sigOctetIdx * strideLen)
significantIdx := (bits - 1) / strideLen
significantBits := bits - (significantIdx * strideLen)

// find the trie node
LOOP:
for depth, octet := range octets {
if depth == sigOctetIdx {
return n.prefixes.Get(pfxToIdx(octet, sigOctetBits))
if depth == significantIdx {
return n.prefixes.Get(pfxToIdx(octet, significantBits))
}

addr := uint(octet)
Expand Down Expand Up @@ -382,8 +382,7 @@ LOOP:

// longest prefix match, skip if node has no prefixes
if n.prefixes.Len() != 0 {
octet = octets[depth]
if _, val, ok = n.lpm(hostIndex(uint(octet))); ok {
if _, val, ok = n.lpm(hostIndex(uint(octets[depth]))); ok {
return val, ok
}
}
Expand Down Expand Up @@ -433,31 +432,30 @@ func (t *Table[V]) lpmPrefix(pfx netip.Prefix) (lpm netip.Prefix, val V, ok bool

n := t.rootNodeByVersion(is4)

// see comment in insertAtDepth()
significantIdx := (bits - 1) / strideLen
significantBits := bits - (significantIdx * strideLen)

// do not allocate
a16 := ip.As16()
octets := a16[:]
if is4 {
octets = octets[12:]
}
octets = octets[:significantIdx+1]

// see comment in Insert()
sigOctetIdx := (bits - 1) / strideLen
sigOctet := octets[sigOctetIdx]
sigOctetBits := bits - (sigOctetIdx * strideLen)
// mask the prefix, pfx.Masked() is too complex and allocates
octets[significantIdx] &= netMask(significantBits)

// mask the prefix
sigOctet &= netMask(sigOctetBits)
octets[sigOctetIdx] = sigOctet
octets = octets[:sigOctetIdx+1]
// record path to leaf node
stack := [maxTreeDepth]*node[V]{}

var depth int
var octet byte
var addr uint

// record path to leaf node
stack := [maxTreeDepth]*node[V]{}

LOOP:
// find the node
// find the last node on the octets path in the trie
for depth, octet = range octets {
addr = uint(octet)

Expand Down Expand Up @@ -485,7 +483,7 @@ LOOP:
}
}

// start backtracking, unwind the stack
// start backtracking, unwind the stack.
for ; depth >= 0; depth-- {
n = stack[depth]

Expand All @@ -496,8 +494,8 @@ LOOP:
// only the lastOctet may have a different prefix len
// all others are just host routes
var idx uint
if depth == sigOctetIdx {
idx = pfxToIdx(octet, sigOctetBits)
if depth == significantIdx {
idx = pfxToIdx(octet, significantBits)
} else {
idx = hostIndex(uint(octet))
}
Expand Down Expand Up @@ -534,11 +532,11 @@ func (t *Table[V]) Supernets(pfx netip.Prefix) func(yield func(netip.Prefix, V)

n := t.rootNodeByVersion(is4)

sigOctetIdx := (bits - 1) / strideLen
sigOctetBits := bits - (sigOctetIdx * strideLen)
significantIdx := (bits - 1) / strideLen
significantBits := bits - (significantIdx * strideLen)

octets := ip.AsSlice()
octets = octets[:sigOctetIdx+1]
octets = octets[:significantIdx+1]

// stack of the traversed nodes for reverse ordering of supernets
stack := [maxTreeDepth]*node[V]{}
Expand Down Expand Up @@ -587,8 +585,8 @@ func (t *Table[V]) Supernets(pfx netip.Prefix) func(yield func(netip.Prefix, V)
// only the lastOctet may have a different prefix len
// all others are just host routes
pfxLen := strideLen
if depth == sigOctetIdx {
pfxLen = sigOctetBits
if depth == significantIdx {
pfxLen = significantBits
}

if !n.eachLookupPrefix(octets, depth, is4, pfxLen, yield) {
Expand Down Expand Up @@ -617,16 +615,16 @@ func (t *Table[V]) Subnets(pfx netip.Prefix) func(yield func(netip.Prefix, V) bo

n := t.rootNodeByVersion(is4)

sigOctetIdx := (bits - 1) / strideLen
sigOctetBits := bits - (sigOctetIdx * strideLen)
significantIdx := (bits - 1) / strideLen
significantBits := bits - (significantIdx * strideLen)

octets := ip.AsSlice()
octets = octets[:sigOctetIdx+1]
octets = octets[:significantIdx+1]

// find the trie node
for depth, octet := range octets {
if depth == sigOctetIdx {
_ = n.eachSubnet(octets, depth, is4, sigOctetBits, yield)
if depth == significantIdx {
_ = n.eachSubnet(octets, depth, is4, significantBits, yield)
return
}

Expand Down Expand Up @@ -677,7 +675,7 @@ func (t *Table[V]) Overlaps4(o *Table[V]) bool {
if t.size4 == 0 || o.size4 == 0 {
return false
}
return t.root4.overlapsRec(&o.root4, 0)
return t.root4.overlaps(&o.root4, 0)
}

// Overlaps6 reports whether any IPv6 in the table matches a route in the
Expand All @@ -686,7 +684,7 @@ func (t *Table[V]) Overlaps6(o *Table[V]) bool {
if t.size6 == 0 || o.size6 == 0 {
return false
}
return t.root6.overlapsRec(&o.root6, 0)
return t.root6.overlaps(&o.root6, 0)
}

// Union combines two tables, changing the receiver table.
Expand Down

0 comments on commit f8f1778

Please sign in to comment.