Skip to content

Commit

Permalink
cloning nil returns nil
Browse files Browse the repository at this point in the history
  • Loading branch information
gaissmai committed Jan 4, 2025
1 parent abf189b commit 1f51276
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 24 deletions.
25 changes: 10 additions & 15 deletions node.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,10 @@ func (n *node[V]) lpmTest(idx uint) bool {

// cloneRec, clones the node recursive.
func (n *node[V]) cloneRec() *node[V] {
if n == nil {
return nil
}

c := new(node[V])
if n.isEmpty() {
return c
Expand Down Expand Up @@ -308,12 +312,7 @@ func (n *node[V]) cloneRec() *node[V] {
// false value is propagated.
//
// The iteration order is not defined, just the simplest and fastest recursive implementation.
func (n *node[V]) allRec(
path [16]byte,
depth int,
is4 bool,
yield func(netip.Prefix, V) bool,
) bool {
func (n *node[V]) allRec(path [16]byte, depth int, is4 bool, yield func(netip.Prefix, V) bool) bool {
// for all prefixes in this node do ...
allIndices := n.prefixes.AsSlice(make([]uint, 0, maxNodePrefixes))
for _, idx := range allIndices {
Expand Down Expand Up @@ -355,12 +354,7 @@ func (n *node[V]) allRec(
//
// If the yield function returns false the recursion ends prematurely and the
// false value is propagated.
func (n *node[V]) allRecSorted(
path [16]byte,
depth int,
is4 bool,
yield func(netip.Prefix, V) bool,
) bool {
func (n *node[V]) allRecSorted(path [16]byte, depth int, is4 bool, yield func(netip.Prefix, V) bool) bool {
// get slice of all child octets, sorted by addr
allChildAddrs := n.children.AsSlice(make([]uint, 0, maxNodeChildren))

Expand Down Expand Up @@ -538,13 +532,14 @@ LOOP:
// eachLookupPrefix does an all prefix match in the 8-bit (stride) routing table
// at this depth and calls yield() for any matching CIDR.
func (n *node[V]) eachLookupPrefix(octets []byte, depth int, is4 bool, pfxLen int, yield func(netip.Prefix, V) bool) (ok bool) {
var path [16]byte
copy(path[:], octets)

if n.prefixes.Len() == 0 {
return true
}

// octets as array, needed below more than once
var path [16]byte
copy(path[:], octets)

// backtracking the CBT
for idx := pfxToIdx(octets[depth], pfxLen); idx > 0; idx >>= 1 {
if n.prefixes.Test(idx) {
Expand Down
20 changes: 11 additions & 9 deletions table.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,16 +343,17 @@ func (t *Table[V]) Lookup(ip netip.Addr) (val V, ok bool) {
stack := [maxTreeDepth]*node[V]{}

// run variable, used after for loop
var i int
var depth int
var octet byte
var addr uint

LOOP:
// find leaf node
for i, octet = range octets {
addr := uint(octet)
for depth, octet = range octets {
addr = uint(octet)

// push current node on stack for fast backtracking
stack[i] = n
stack[depth] = n

// go down in tight loop to last octet
if !n.children.Test(addr) {
Expand All @@ -376,12 +377,13 @@ LOOP:
}

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

// longest prefix match, skip if node has no prefixes
if n.prefixes.Len() != 0 {
if _, val, ok = n.lpm(hostIndex(uint(octets[depth]))); ok {
octet = octets[depth]
if _, val, ok = n.lpm(hostIndex(uint(octet))); ok {
return val, ok
}
}
Expand Down Expand Up @@ -486,18 +488,18 @@ LOOP:
// start backtracking, unwind the stack
for ; depth >= 0; depth-- {
n = stack[depth]
octet = octets[depth]
addr = uint(octet)

// longest prefix match, skip if node has no prefixes
if n.prefixes.Len() != 0 {
octet = octets[depth]

// 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)
} else {
idx = hostIndex(addr)
idx = hostIndex(uint(octet))
}

if baseIdx, val, ok := n.lpm(idx); ok {
Expand Down

0 comments on commit 1f51276

Please sign in to comment.