From 4f2a8a1a07388897c0876380fe5402eeb9ed6999 Mon Sep 17 00:00:00 2001 From: Toru Maesaka Date: Thu, 3 Oct 2024 15:43:08 -0700 Subject: [PATCH] radixdb: add longestCommonPrefix() --- radixdb.go | 25 +++++++++++++++++++++++++ radixdb_test.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 radixdb_test.go diff --git a/radixdb.go b/radixdb.go index 38f81b8..90f61c3 100644 --- a/radixdb.go +++ b/radixdb.go @@ -37,3 +37,28 @@ func (rdb *RadixDB) Len() uint64 { return rdb.numNodes } + +// 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. +func longestCommonPrefix(a, b []byte) []byte { + minLen := len(a) + + if len(b) < minLen { + minLen = len(b) + } + + var i int + + for i = 0; i < minLen; i++ { + if a[i] != b[i] { + break + } + } + + if i == 0 { + return nil + } + + return a[:i] +} diff --git a/radixdb_test.go b/radixdb_test.go new file mode 100644 index 0000000..0482625 --- /dev/null +++ b/radixdb_test.go @@ -0,0 +1,29 @@ +package radixdb + +import "testing" + +func TestLongestCommonPrefix(t *testing.T) { + tests := []struct { + a, b []byte + expected []byte + }{ + // Basic cases. + {[]byte("apple"), []byte("app"), []byte("app")}, + {[]byte("banana"), []byte("band"), []byte("ban")}, + {[]byte("cat"), []byte("candy"), []byte("ca")}, + {[]byte("no"), []byte("match"), nil}, + {[]byte("match"), []byte("match"), []byte("match")}, + + // Edge cases. + {[]byte(""), []byte(""), nil}, + {nil, nil, nil}, + } + + for _, test := range tests { + subject := longestCommonPrefix(test.a, test.b) + + if string(subject) != string(test.expected) { + t.Errorf("(%q,%q): got:%q, want:%q", test.a, test.b, subject, test.expected) + } + } +}