@@ -25,43 +25,44 @@ var (
2525 ErrPrefixAmbiguous = errors .New ("prefixtree: prefix ambiguous" )
2626)
2727
28- // A KeyValue type encapsulates a key string and its associated value.
29- type KeyValue struct {
28+ // A KeyValue type encapsulates a key string and its associated value of type
29+ // V.
30+ type KeyValue [V any ] struct {
3031 Key string
31- Value any
32+ Value V
3233}
3334
3435// A Tree represents a prefix tree containing strings and their associated
35- // value data. The tree is implemented as a trie and can be searched
36+ // value data of type V . The tree is implemented as a trie and can be searched
3637// efficiently for unique prefix matches.
37- type Tree struct {
38+ type Tree [ V any ] struct {
3839 key string
39- value any
40- links []link
40+ value V
41+ links []link [ V ]
4142 descendants int
4243}
4344
44- type link struct {
45+ type link [ V any ] struct {
4546 keyseg string
46- tree * Tree
47+ tree * Tree [ V ]
4748}
4849
49- // New returns an empty prefix tree.
50- func New () * Tree {
51- return new (Tree )
50+ // New returns an empty prefix tree with a value type of V .
51+ func New [ V any ] () * Tree [ V ] {
52+ return new (Tree [ V ] )
5253}
5354
5455// isTerminal returns true if the tree is a terminal subtree in the
5556// prefix tree.
56- func (t * Tree ) isTerminal () bool {
57+ func (t * Tree [ V ] ) isTerminal () bool {
5758 return t .key != ""
5859}
5960
6061// FindKey searches the prefix tree for a key string that uniquely matches the
6162// prefix. If found, the full matching key is returned. If not found,
6263// ErrPrefixNotFound is returned. If the prefix matches more than one key in
6364// the tree, ErrPrefixAmbiguous is returned.
64- func (t * Tree ) FindKey (prefix string ) (key string , err error ) {
65+ func (t * Tree [ V ] ) FindKey (prefix string ) (key string , err error ) {
6566 st , err := t .findSubtree (prefix )
6667 if err != nil {
6768 return "" , err
@@ -74,17 +75,17 @@ func (t *Tree) FindKey(prefix string) (key string, err error) {
7475// value is returned. If not found, ErrPrefixNotFound is returned. If the
7576// prefix matches more than one key in the tree, ErrPrefixAmbiguous is
7677// returned.
77- func (t * Tree ) FindKeyValue (prefix string ) (kv KeyValue , err error ) {
78+ func (t * Tree [ V ] ) FindKeyValue (prefix string ) (kv KeyValue [ V ] , err error ) {
7879 st , err := t .findSubtree (prefix )
7980 if err != nil {
80- return KeyValue {}, err
81+ return KeyValue [ V ] {}, err
8182 }
82- return KeyValue {st .key , st .value }, nil
83+ return KeyValue [ V ] {st .key , st .value }, nil
8384}
8485
8586// FindKeys searches the prefix tree for all key strings prefixed by the
8687// provided prefix and returns them.
87- func (t * Tree ) FindKeys (prefix string ) (keys []string ) {
88+ func (t * Tree [ V ] ) FindKeys (prefix string ) (keys []string ) {
8889 st , err := t .findSubtree (prefix )
8990 if err == ErrPrefixNotFound {
9091 return []string {}
@@ -99,43 +100,44 @@ func (t *Tree) FindKeys(prefix string) (keys []string) {
99100// the prefix. If found, the value associated with the key is returned. If not
100101// found, ErrPrefixNotFound is returned. If the prefix matches more than one
101102// key in the tree, ErrPrefixAmbiguous is returned.
102- func (t * Tree ) FindValue (prefix string ) (value any , err error ) {
103+ func (t * Tree [ V ] ) FindValue (prefix string ) (value V , err error ) {
103104 st , err := t .findSubtree (prefix )
104105 if err != nil {
105- return nil , err
106+ var empty V
107+ return empty , err
106108 }
107109 return st .value , nil
108110}
109111
110112// FindKeyValues searches the prefix tree for all key strings prefixed by the
111113// provided prefix. All discovered keys and their values are returned.
112- func (t * Tree ) FindKeyValues (prefix string ) (values []KeyValue ) {
114+ func (t * Tree [ V ] ) FindKeyValues (prefix string ) (values []KeyValue [ V ] ) {
113115 st , err := t .findSubtree (prefix )
114116 if err == ErrPrefixNotFound {
115- return []KeyValue {}
117+ return []KeyValue [ V ] {}
116118 }
117119 if st .isTerminal () && err != ErrPrefixAmbiguous {
118- return []KeyValue {{st .key , st .value }}
120+ return []KeyValue [ V ] {{st .key , st .value }}
119121 }
120122 return appendDescendantKeyValues (st , nil )
121123}
122124
123125// FindValues searches the prefix tree for all key strings prefixed by the
124126// provided prefix. All associated values are returned.
125- func (t * Tree ) FindValues (prefix string ) (values []any ) {
127+ func (t * Tree [ V ] ) FindValues (prefix string ) (values []V ) {
126128 st , err := t .findSubtree (prefix )
127129 if err == ErrPrefixNotFound {
128- return []any {}
130+ return []V {}
129131 }
130132 if st .isTerminal () && err != ErrPrefixAmbiguous {
131- return []any {st .value }
133+ return []V {st .value }
132134 }
133135 return appendDescendantValues (st , nil )
134136}
135137
136138// findSubtree searches the prefix tree for the deepest subtree matching
137139// the prefix.
138- func (t * Tree ) findSubtree (prefix string ) (* Tree , error ) {
140+ func (t * Tree [ V ] ) findSubtree (prefix string ) (* Tree [ V ] , error ) {
139141outerLoop:
140142 for {
141143 // Ran out of prefix?
@@ -201,7 +203,7 @@ func matchingChars(s1, s2 string) int {
201203
202204// appendDescendantKeys recursively appends a tree's descendant keys
203205// to an array of keys.
204- func appendDescendantKeys (t * Tree , keys []string ) []string {
206+ func appendDescendantKeys [ V any ] (t * Tree [ V ] , keys []string ) []string {
205207 if t .isTerminal () {
206208 keys = append (keys , t .key )
207209 }
@@ -213,9 +215,9 @@ func appendDescendantKeys(t *Tree, keys []string) []string {
213215
214216// appendDescendantKeyValues recursively appends a tree's descendant keys
215217// to an array of key/value pairs.
216- func appendDescendantKeyValues (t * Tree , kv []KeyValue ) []KeyValue {
218+ func appendDescendantKeyValues [ V any ] (t * Tree [ V ] , kv []KeyValue [ V ] ) []KeyValue [ V ] {
217219 if t .isTerminal () {
218- kv = append (kv , KeyValue {t .key , t .value })
220+ kv = append (kv , KeyValue [ V ] {t .key , t .value })
219221 }
220222 for i := 0 ; i < len (t .links ); i ++ {
221223 kv = appendDescendantKeyValues (t .links [i ].tree , kv )
@@ -225,7 +227,7 @@ func appendDescendantKeyValues(t *Tree, kv []KeyValue) []KeyValue {
225227
226228// appendDescendantValues recursively appends a tree's descendant values
227229// to an array of values.
228- func appendDescendantValues (t * Tree , values []any ) []any {
230+ func appendDescendantValues [ V any ] (t * Tree [ V ] , values []V ) []V {
229231 if t .isTerminal () {
230232 values = append (values , t .value )
231233 }
@@ -236,7 +238,7 @@ func appendDescendantValues(t *Tree, values []any) []any {
236238}
237239
238240// Add a key string and its associated value data to the prefix tree.
239- func (t * Tree ) Add (key string , value any ) {
241+ func (t * Tree [ V ] ) Add (key string , value V ) {
240242 k := key
241243outerLoop:
242244 for {
@@ -255,7 +257,7 @@ outerLoop:
255257
256258 // Check the links before and after the insertion point for a matching
257259 // prefix to see if we need to split one of them.
258- var splitLink * link
260+ var splitLink * link [ V ]
259261 var splitIndex int
260262 innerLoop:
261263 for li , lm := max (ix - 1 , 0 ), min (ix , len (t .links )- 1 ); li <= lm ; li ++ {
@@ -275,24 +277,25 @@ outerLoop:
275277
276278 // No split necessary, so insert a new link and subtree.
277279 if splitLink == nil {
278- child := & Tree {
280+ child := & Tree [ V ] {
279281 key : key ,
280282 value : value ,
281283 links : nil ,
282284 descendants : 1 ,
283285 }
284286 t .links = append (t .links [:ix ],
285- append ([]link {{k , child }}, t .links [ix :]... )... )
287+ append ([]link [ V ] {{k , child }}, t .links [ix :]... )... )
286288 break outerLoop
287289 }
288290
289291 // A split is necessary, so split the current link's string and insert
290292 // a child tree.
291293 k1 , k2 := splitLink .keyseg [:splitIndex ], splitLink .keyseg [splitIndex :]
292- child := & Tree {
294+ var empty V
295+ child := & Tree [V ]{
293296 key : "" ,
294- value : nil ,
295- links : []link {{k2 , splitLink .tree }},
297+ value : empty ,
298+ links : []link [ V ] {{k2 , splitLink .tree }},
296299 descendants : splitLink .tree .descendants ,
297300 }
298301 splitLink .keyseg , splitLink .tree = k1 , child
@@ -302,11 +305,11 @@ outerLoop:
302305
303306// Output the structure of the tree to stdout. This function exists for
304307// debugging purposes.
305- func (t * Tree ) Output () {
308+ func (t * Tree [ V ] ) Output () {
306309 t .outputNode (0 )
307310}
308311
309- func (t * Tree ) outputNode (level int ) {
312+ func (t * Tree [ V ] ) outputNode (level int ) {
310313 fmt .Printf ("%sNode: key=\" %s\" term=%v desc=%d value=%v\n " ,
311314 strings .Repeat (" " , level ), t .key , t .isTerminal (), t .descendants , t .value )
312315 for i , l := range t .links {
0 commit comments