1// Copyright (c) 2014 The go-patricia AUTHORS
2//
3// Use of this source code is governed by The MIT License
4// that can be found in the LICENSE file.
5
6package patricia
7
8import (
9	"bytes"
10	"errors"
11	"fmt"
12	"io"
13	"strings"
14)
15
16//------------------------------------------------------------------------------
17// Trie
18//------------------------------------------------------------------------------
19
20const (
21	DefaultMaxPrefixPerNode         = 10
22	DefaultMaxChildrenPerSparseNode = 8
23)
24
25type (
26	Prefix      []byte
27	Item        interface{}
28	VisitorFunc func(prefix Prefix, item Item) error
29)
30
31// Trie is a generic patricia trie that allows fast retrieval of items by prefix.
32// and other funky stuff.
33//
34// Trie is not thread-safe.
35type Trie struct {
36	prefix Prefix
37	item   Item
38
39	maxPrefixPerNode         int
40	maxChildrenPerSparseNode int
41
42	children childList
43}
44
45// Public API ------------------------------------------------------------------
46
47type Option func(*Trie)
48
49// Trie constructor.
50func NewTrie(options ...Option) *Trie {
51	trie := &Trie{}
52
53	for _, opt := range options {
54		opt(trie)
55	}
56
57	if trie.maxPrefixPerNode <= 0 {
58		trie.maxPrefixPerNode = DefaultMaxPrefixPerNode
59	}
60	if trie.maxChildrenPerSparseNode <= 0 {
61		trie.maxChildrenPerSparseNode = DefaultMaxChildrenPerSparseNode
62	}
63
64	trie.children = newSparseChildList(trie.maxChildrenPerSparseNode)
65	return trie
66}
67
68func MaxPrefixPerNode(value int) Option {
69	return func(trie *Trie) {
70		trie.maxPrefixPerNode = value
71	}
72}
73
74func MaxChildrenPerSparseNode(value int) Option {
75	return func(trie *Trie) {
76		trie.maxChildrenPerSparseNode = value
77	}
78}
79
80// Clone makes a copy of an existing trie.
81// Items stored in both tries become shared, obviously.
82func (trie *Trie) Clone() *Trie {
83	return &Trie{
84		prefix:                   append(Prefix(nil), trie.prefix...),
85		item:                     trie.item,
86		maxPrefixPerNode:         trie.maxPrefixPerNode,
87		maxChildrenPerSparseNode: trie.maxChildrenPerSparseNode,
88		children:                 trie.children.clone(),
89	}
90}
91
92// Item returns the item stored in the root of this trie.
93func (trie *Trie) Item() Item {
94	return trie.item
95}
96
97// Insert inserts a new item into the trie using the given prefix. Insert does
98// not replace existing items. It returns false if an item was already in place.
99func (trie *Trie) Insert(key Prefix, item Item) (inserted bool) {
100	return trie.put(key, item, false)
101}
102
103// Set works much like Insert, but it always sets the item, possibly replacing
104// the item previously inserted.
105func (trie *Trie) Set(key Prefix, item Item) {
106	trie.put(key, item, true)
107}
108
109// Get returns the item located at key.
110//
111// This method is a bit dangerous, because Get can as well end up in an internal
112// node that is not really representing any user-defined value. So when nil is
113// a valid value being used, it is not possible to tell if the value was inserted
114// into the tree by the user or not. A possible workaround for this is not to use
115// nil interface as a valid value, even using zero value of any type is enough
116// to prevent this bad behaviour.
117func (trie *Trie) Get(key Prefix) (item Item) {
118	_, node, found, leftover := trie.findSubtree(key)
119	if !found || len(leftover) != 0 {
120		return nil
121	}
122	return node.item
123}
124
125// Match returns what Get(prefix) != nil would return. The same warning as for
126// Get applies here as well.
127func (trie *Trie) Match(prefix Prefix) (matchedExactly bool) {
128	return trie.Get(prefix) != nil
129}
130
131// MatchSubtree returns true when there is a subtree representing extensions
132// to key, that is if there are any keys in the tree which have key as prefix.
133func (trie *Trie) MatchSubtree(key Prefix) (matched bool) {
134	_, _, matched, _ = trie.findSubtree(key)
135	return
136}
137
138// Visit calls visitor on every node containing a non-nil item
139// in alphabetical order.
140//
141// If an error is returned from visitor, the function stops visiting the tree
142// and returns that error, unless it is a special error - SkipSubtree. In that
143// case Visit skips the subtree represented by the current node and continues
144// elsewhere.
145func (trie *Trie) Visit(visitor VisitorFunc) error {
146	return trie.walk(nil, visitor)
147}
148
149func (trie *Trie) size() int {
150	n := 0
151
152	trie.walk(nil, func(prefix Prefix, item Item) error {
153		n++
154		return nil
155	})
156
157	return n
158}
159
160func (trie *Trie) total() int {
161	return 1 + trie.children.total()
162}
163
164// VisitSubtree works much like Visit, but it only visits nodes matching prefix.
165func (trie *Trie) VisitSubtree(prefix Prefix, visitor VisitorFunc) error {
166	// Nil prefix not allowed.
167	if prefix == nil {
168		panic(ErrNilPrefix)
169	}
170
171	// Empty trie must be handled explicitly.
172	if trie.prefix == nil {
173		return nil
174	}
175
176	// Locate the relevant subtree.
177	_, root, found, leftover := trie.findSubtree(prefix)
178	if !found {
179		return nil
180	}
181	prefix = append(prefix, leftover...)
182
183	// Visit it.
184	return root.walk(prefix, visitor)
185}
186
187// VisitPrefixes visits only nodes that represent prefixes of key.
188// To say the obvious, returning SkipSubtree from visitor makes no sense here.
189func (trie *Trie) VisitPrefixes(key Prefix, visitor VisitorFunc) error {
190	// Nil key not allowed.
191	if key == nil {
192		panic(ErrNilPrefix)
193	}
194
195	// Empty trie must be handled explicitly.
196	if trie.prefix == nil {
197		return nil
198	}
199
200	// Walk the path matching key prefixes.
201	node := trie
202	prefix := key
203	offset := 0
204	for {
205		// Compute what part of prefix matches.
206		common := node.longestCommonPrefixLength(key)
207		key = key[common:]
208		offset += common
209
210		// Partial match means that there is no subtree matching prefix.
211		if common < len(node.prefix) {
212			return nil
213		}
214
215		// Call the visitor.
216		if item := node.item; item != nil {
217			if err := visitor(prefix[:offset], item); err != nil {
218				return err
219			}
220		}
221
222		if len(key) == 0 {
223			// This node represents key, we are finished.
224			return nil
225		}
226
227		// There is some key suffix left, move to the children.
228		child := node.children.next(key[0])
229		if child == nil {
230			// There is nowhere to continue, return.
231			return nil
232		}
233
234		node = child
235	}
236}
237
238// Delete deletes the item represented by the given prefix.
239//
240// True is returned if the matching node was found and deleted.
241func (trie *Trie) Delete(key Prefix) (deleted bool) {
242	// Nil prefix not allowed.
243	if key == nil {
244		panic(ErrNilPrefix)
245	}
246
247	// Empty trie must be handled explicitly.
248	if trie.prefix == nil {
249		return false
250	}
251
252	// Find the relevant node.
253	path, found, _ := trie.findSubtreePath(key)
254	if !found {
255		return false
256	}
257
258	node := path[len(path)-1]
259	var parent *Trie
260	if len(path) != 1 {
261		parent = path[len(path)-2]
262	}
263
264	// If the item is already set to nil, there is nothing to do.
265	if node.item == nil {
266		return false
267	}
268
269	// Delete the item.
270	node.item = nil
271
272	// Initialise i before goto.
273	// Will be used later in a loop.
274	i := len(path) - 1
275
276	// In case there are some child nodes, we cannot drop the whole subtree.
277	// We can try to compact nodes, though.
278	if node.children.length() != 0 {
279		goto Compact
280	}
281
282	// In case we are at the root, just reset it and we are done.
283	if parent == nil {
284		node.reset()
285		return true
286	}
287
288	// We can drop a subtree.
289	// Find the first ancestor that has its value set or it has 2 or more child nodes.
290	// That will be the node where to drop the subtree at.
291	for ; i >= 0; i-- {
292		if current := path[i]; current.item != nil || current.children.length() >= 2 {
293			break
294		}
295	}
296
297	// Handle the case when there is no such node.
298	// In other words, we can reset the whole tree.
299	if i == -1 {
300		path[0].reset()
301		return true
302	}
303
304	// We can just remove the subtree here.
305	node = path[i]
306	if i == 0 {
307		parent = nil
308	} else {
309		parent = path[i-1]
310	}
311	// i+1 is always a valid index since i is never pointing to the last node.
312	// The loop above skips at least the last node since we are sure that the item
313	// is set to nil and it has no children, othewise we would be compacting instead.
314	node.children.remove(path[i+1].prefix[0])
315
316Compact:
317	// The node is set to the first non-empty ancestor,
318	// so try to compact since that might be possible now.
319	if compacted := node.compact(); compacted != node {
320		if parent == nil {
321			*node = *compacted
322		} else {
323			parent.children.replace(node.prefix[0], compacted)
324			*parent = *parent.compact()
325		}
326	}
327
328	return true
329}
330
331// DeleteSubtree finds the subtree exactly matching prefix and deletes it.
332//
333// True is returned if the subtree was found and deleted.
334func (trie *Trie) DeleteSubtree(prefix Prefix) (deleted bool) {
335	// Nil prefix not allowed.
336	if prefix == nil {
337		panic(ErrNilPrefix)
338	}
339
340	// Empty trie must be handled explicitly.
341	if trie.prefix == nil {
342		return false
343	}
344
345	// Locate the relevant subtree.
346	parent, root, found, _ := trie.findSubtree(prefix)
347	if !found {
348		return false
349	}
350
351	// If we are in the root of the trie, reset the trie.
352	if parent == nil {
353		root.reset()
354		return true
355	}
356
357	// Otherwise remove the root node from its parent.
358	parent.children.remove(root.prefix[0])
359	return true
360}
361
362// Internal helper methods -----------------------------------------------------
363
364func (trie *Trie) empty() bool {
365	return trie.item == nil && trie.children.length() == 0
366}
367
368func (trie *Trie) reset() {
369	trie.prefix = nil
370	trie.children = newSparseChildList(trie.maxPrefixPerNode)
371}
372
373func (trie *Trie) put(key Prefix, item Item, replace bool) (inserted bool) {
374	// Nil prefix not allowed.
375	if key == nil {
376		panic(ErrNilPrefix)
377	}
378
379	var (
380		common int
381		node   *Trie = trie
382		child  *Trie
383	)
384
385	if node.prefix == nil {
386		if len(key) <= trie.maxPrefixPerNode {
387			node.prefix = key
388			goto InsertItem
389		}
390		node.prefix = key[:trie.maxPrefixPerNode]
391		key = key[trie.maxPrefixPerNode:]
392		goto AppendChild
393	}
394
395	for {
396		// Compute the longest common prefix length.
397		common = node.longestCommonPrefixLength(key)
398		key = key[common:]
399
400		// Only a part matches, split.
401		if common < len(node.prefix) {
402			goto SplitPrefix
403		}
404
405		// common == len(node.prefix) since never (common > len(node.prefix))
406		// common == len(former key) <-> 0 == len(key)
407		// -> former key == node.prefix
408		if len(key) == 0 {
409			goto InsertItem
410		}
411
412		// Check children for matching prefix.
413		child = node.children.next(key[0])
414		if child == nil {
415			goto AppendChild
416		}
417		node = child
418	}
419
420SplitPrefix:
421	// Split the prefix if necessary.
422	child = new(Trie)
423	*child = *node
424	*node = *NewTrie()
425	node.prefix = child.prefix[:common]
426	child.prefix = child.prefix[common:]
427	child = child.compact()
428	node.children = node.children.add(child)
429
430AppendChild:
431	// Keep appending children until whole prefix is inserted.
432	// This loop starts with empty node.prefix that needs to be filled.
433	for len(key) != 0 {
434		child := NewTrie()
435		if len(key) <= trie.maxPrefixPerNode {
436			child.prefix = key
437			node.children = node.children.add(child)
438			node = child
439			goto InsertItem
440		} else {
441			child.prefix = key[:trie.maxPrefixPerNode]
442			key = key[trie.maxPrefixPerNode:]
443			node.children = node.children.add(child)
444			node = child
445		}
446	}
447
448InsertItem:
449	// Try to insert the item if possible.
450	if replace || node.item == nil {
451		node.item = item
452		return true
453	}
454	return false
455}
456
457func (trie *Trie) compact() *Trie {
458	// Only a node with a single child can be compacted.
459	if trie.children.length() != 1 {
460		return trie
461	}
462
463	child := trie.children.head()
464
465	// If any item is set, we cannot compact since we want to retain
466	// the ability to do searching by key. This makes compaction less usable,
467	// but that simply cannot be avoided.
468	if trie.item != nil || child.item != nil {
469		return trie
470	}
471
472	// Make sure the combined prefixes fit into a single node.
473	if len(trie.prefix)+len(child.prefix) > trie.maxPrefixPerNode {
474		return trie
475	}
476
477	// Concatenate the prefixes, move the items.
478	child.prefix = append(trie.prefix, child.prefix...)
479	if trie.item != nil {
480		child.item = trie.item
481	}
482
483	return child
484}
485
486func (trie *Trie) findSubtree(prefix Prefix) (parent *Trie, root *Trie, found bool, leftover Prefix) {
487	// Find the subtree matching prefix.
488	root = trie
489	for {
490		// Compute what part of prefix matches.
491		common := root.longestCommonPrefixLength(prefix)
492		prefix = prefix[common:]
493
494		// We used up the whole prefix, subtree found.
495		if len(prefix) == 0 {
496			found = true
497			leftover = root.prefix[common:]
498			return
499		}
500
501		// Partial match means that there is no subtree matching prefix.
502		if common < len(root.prefix) {
503			leftover = root.prefix[common:]
504			return
505		}
506
507		// There is some prefix left, move to the children.
508		child := root.children.next(prefix[0])
509		if child == nil {
510			// There is nowhere to continue, there is no subtree matching prefix.
511			return
512		}
513
514		parent = root
515		root = child
516	}
517}
518
519func (trie *Trie) findSubtreePath(prefix Prefix) (path []*Trie, found bool, leftover Prefix) {
520	// Find the subtree matching prefix.
521	root := trie
522	var subtreePath []*Trie
523	for {
524		// Append the current root to the path.
525		subtreePath = append(subtreePath, root)
526
527		// Compute what part of prefix matches.
528		common := root.longestCommonPrefixLength(prefix)
529		prefix = prefix[common:]
530
531		// We used up the whole prefix, subtree found.
532		if len(prefix) == 0 {
533			path = subtreePath
534			found = true
535			leftover = root.prefix[common:]
536			return
537		}
538
539		// Partial match means that there is no subtree matching prefix.
540		if common < len(root.prefix) {
541			leftover = root.prefix[common:]
542			return
543		}
544
545		// There is some prefix left, move to the children.
546		child := root.children.next(prefix[0])
547		if child == nil {
548			// There is nowhere to continue, there is no subtree matching prefix.
549			return
550		}
551
552		root = child
553	}
554}
555
556func (trie *Trie) walk(actualRootPrefix Prefix, visitor VisitorFunc) error {
557	var prefix Prefix
558	// Allocate a bit more space for prefix at the beginning.
559	if actualRootPrefix == nil {
560		prefix = make(Prefix, 32+len(trie.prefix))
561		copy(prefix, trie.prefix)
562		prefix = prefix[:len(trie.prefix)]
563	} else {
564		prefix = make(Prefix, 32+len(actualRootPrefix))
565		copy(prefix, actualRootPrefix)
566		prefix = prefix[:len(actualRootPrefix)]
567	}
568
569	// Visit the root first. Not that this works for empty trie as well since
570	// in that case item == nil && len(children) == 0.
571	if trie.item != nil {
572		if err := visitor(prefix, trie.item); err != nil {
573			if err == SkipSubtree {
574				return nil
575			}
576			return err
577		}
578	}
579
580	// Then continue to the children.
581	return trie.children.walk(&prefix, visitor)
582}
583
584func (trie *Trie) longestCommonPrefixLength(prefix Prefix) (i int) {
585	for ; i < len(prefix) && i < len(trie.prefix) && prefix[i] == trie.prefix[i]; i++ {
586	}
587	return
588}
589
590func (trie *Trie) dump() string {
591	writer := &bytes.Buffer{}
592	trie.print(writer, 0)
593	return writer.String()
594}
595
596func (trie *Trie) print(writer io.Writer, indent int) {
597	fmt.Fprintf(writer, "%s%s %v\n", strings.Repeat(" ", indent), string(trie.prefix), trie.item)
598	trie.children.print(writer, indent+2)
599}
600
601// Errors ----------------------------------------------------------------------
602
603var (
604	SkipSubtree  = errors.New("Skip this subtree")
605	ErrNilPrefix = errors.New("Nil prefix passed into a method call")
606)
607