diff --git a/radixdb.go b/radixdb.go index 90f61c3..85695b6 100644 --- a/radixdb.go +++ b/radixdb.go @@ -38,6 +38,21 @@ func (rdb *RadixDB) Len() uint64 { return rdb.numNodes } +// findCompatibleChild searches through the child nodes of the receiver node. +// It returns the first child node that shares a common prefix. If no child is +// found, the function returns nil. +func (node node) findCompatibleChild(key []byte) *node { + for _, child := range node.children { + prefix := longestCommonPrefix(child.key, key) + + if len(prefix) > 0 { + return child + } + } + + return nil +} + // longestCommonPrefix compares the two given byte slices, and returns the // longest common prefix. It ensures memory-safety by establishing an index // boundary based on the length of the shorter byte slice. diff --git a/radixdb_test.go b/radixdb_test.go index 6843603..e5fc4d4 100644 --- a/radixdb_test.go +++ b/radixdb_test.go @@ -30,3 +30,32 @@ func TestLongestCommonPrefix(t *testing.T) { } } } + +func TestFindCompatibleChild(t *testing.T) { + root := &node{ + children: []*node{ + {key: []byte("apple")}, + {key: []byte("banana")}, + {key: []byte("citron")}, + }, + } + + tests := []struct { + key []byte + expected []byte + }{ + {[]byte("apple"), []byte("apple")}, + {[]byte("applet"), []byte("apple")}, + {[]byte("bandage"), []byte("banana")}, + {[]byte("coconut"), []byte("citron")}, + {[]byte("durian"), nil}, + {[]byte("orange"), nil}, + } + + for _, test := range tests { + child := root.findCompatibleChild([]byte(test.key)) + if (child == nil && test.expected != nil) || (child != nil && !bytes.Equal(child.key, test.expected)) { + t.Errorf("findCompatibleChild(%q): got:%q, want:%q", test.key, child.key, test.expected) + } + } +}