mirror of
				https://github.com/minio/minio.git
				synced 2025-10-26 22:01:30 +01:00 
			
		
		
		
	This change brings a change which was done for the 'mc' package to allow for clean repo and have a cleaner github drop in experience.
		
			
				
	
	
		
			113 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| /*
 | |
|  * Minio Cloud Storage, (C) 2015 Minio, Inc.
 | |
|  *
 | |
|  * Licensed under the Apache License, Version 2.0 (the "License");
 | |
|  * you may not use this file except in compliance with the License.
 | |
|  * You may obtain a copy of the License at
 | |
|  *
 | |
|  *     http://www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an "AS IS" BASIS,
 | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  */
 | |
| 
 | |
| package cmd
 | |
| 
 | |
| // This package borrows idea from - https://godoc.org/golang.org/x/text/internal/triegen
 | |
| 
 | |
| // Trie trie container
 | |
| type Trie struct {
 | |
| 	root *trieNode
 | |
| 	size int
 | |
| }
 | |
| 
 | |
| // newTrie get new trie
 | |
| func newTrie() *Trie {
 | |
| 	return &Trie{
 | |
| 		root: newTrieNode(),
 | |
| 		size: 0,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // trieNode trie tree node container carries value and children
 | |
| type trieNode struct {
 | |
| 	exists bool
 | |
| 	value  interface{}
 | |
| 	child  map[rune]*trieNode // runes as child
 | |
| }
 | |
| 
 | |
| func newTrieNode() *trieNode {
 | |
| 	return &trieNode{
 | |
| 		exists: false,
 | |
| 		value:  nil,
 | |
| 		child:  make(map[rune]*trieNode),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Insert insert a key
 | |
| func (t *Trie) Insert(key string) {
 | |
| 	curNode := t.root
 | |
| 	for _, v := range key {
 | |
| 		if curNode.child[v] == nil {
 | |
| 			curNode.child[v] = newTrieNode()
 | |
| 		}
 | |
| 		curNode = curNode.child[v]
 | |
| 	}
 | |
| 
 | |
| 	if !curNode.exists {
 | |
| 		// increment when new rune child is added
 | |
| 		t.size++
 | |
| 		curNode.exists = true
 | |
| 	}
 | |
| 	// value is stored for retrieval in future
 | |
| 	curNode.value = key
 | |
| }
 | |
| 
 | |
| // PrefixMatch - prefix match
 | |
| func (t *Trie) PrefixMatch(key string) []interface{} {
 | |
| 	node, _ := t.findNode(key)
 | |
| 	if node != nil {
 | |
| 		return t.walk(node)
 | |
| 	}
 | |
| 	return []interface{}{}
 | |
| }
 | |
| 
 | |
| // walk the tree
 | |
| func (t *Trie) walk(node *trieNode) (ret []interface{}) {
 | |
| 	if node.exists {
 | |
| 		ret = append(ret, node.value)
 | |
| 	}
 | |
| 	for _, v := range node.child {
 | |
| 		ret = append(ret, t.walk(v)...)
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| // find nodes corresponding to key
 | |
| func (t *Trie) findNode(key string) (node *trieNode, index int) {
 | |
| 	curNode := t.root
 | |
| 	f := false
 | |
| 	for k, v := range key {
 | |
| 		if f {
 | |
| 			index = k
 | |
| 			f = false
 | |
| 		}
 | |
| 		if curNode.child[v] == nil {
 | |
| 			return nil, index
 | |
| 		}
 | |
| 		curNode = curNode.child[v]
 | |
| 		if curNode.exists {
 | |
| 			f = true
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if curNode.exists {
 | |
| 		index = len(key)
 | |
| 	}
 | |
| 
 | |
| 	return curNode, index
 | |
| }
 |