327768f4ad
Use [33]byte for graph vertex representation. Delete unneeded stuff: 1. DeepEqual for graph comparison 2. EdgePath 3. 2-thread BFS 4. Table transfer messages and neighborhood radius 5. Beacons Refactor: 1. Change ID to Vertex 2. Test use table driven approach 3. Add comments 4. Make graph internal representation private 5. Use wire.OutPoint as EdgeId 6. Decouple routing messages from routing implementation 7. Delete Async methods 8. Delete unneeded channels and priority buffer from manager 9. Delete unneeded interfaces in internal graph realisation 10. Renamed ID to Vertex
117 lines
2.2 KiB
Go
117 lines
2.2 KiB
Go
// Copyright (c) 2016 Bitfury Group Limited
|
|
// Distributed under the MIT software license, see the accompanying
|
|
// file LICENSE or http://www.opensource.org/licenses/mit-license.php
|
|
|
|
package prefix_tree
|
|
|
|
import "errors"
|
|
|
|
// Node represents the general interface for node in prefix tree
|
|
type Node interface {
|
|
Name() string
|
|
Len() int
|
|
Child(nextSymbol string) Node
|
|
Childs() map[string]Node
|
|
AddChild(symbol string, child Node) error
|
|
Parent() Node
|
|
PreviousSymbol() string
|
|
IsRoot() bool
|
|
IsLeaf() bool
|
|
IsTerminal() bool
|
|
Terminal()
|
|
Path() (string, error)
|
|
}
|
|
|
|
type node struct {
|
|
name string
|
|
childs map[string]Node
|
|
parent Node
|
|
previousSymbol string
|
|
isTerminal bool
|
|
}
|
|
|
|
// NewNode create new node
|
|
func NewNode(name string, parent Node, previousSymbol string, isTerminal bool) Node {
|
|
return &node{
|
|
name: name,
|
|
childs: make(map[string]Node),
|
|
parent: parent,
|
|
previousSymbol: previousSymbol,
|
|
isTerminal: isTerminal,
|
|
}
|
|
}
|
|
|
|
func (nd *node) Name() string {
|
|
return nd.name
|
|
}
|
|
|
|
func (nd *node) Len() int {
|
|
return len(nd.childs)
|
|
}
|
|
|
|
func (nd *node) Child(nextSymbol string) Node {
|
|
if _, ok := nd.childs[nextSymbol]; !ok {
|
|
return nil
|
|
}
|
|
return nd.childs[nextSymbol]
|
|
}
|
|
|
|
func (nd *node) Childs() map[string]Node {
|
|
return nd.childs
|
|
}
|
|
|
|
func (nd *node) AddChild(symbol string, child Node) error {
|
|
if _, ok := nd.childs[symbol]; ok {
|
|
return errors.New("Node already exists")
|
|
}
|
|
nd.childs[symbol] = child
|
|
return nil
|
|
}
|
|
|
|
func (nd *node) Parent() Node {
|
|
return nd.parent
|
|
}
|
|
|
|
func (nd *node) PreviousSymbol() string {
|
|
return nd.previousSymbol
|
|
}
|
|
|
|
func (nd *node) IsRoot() bool {
|
|
return nd.parent == nil
|
|
}
|
|
|
|
func (nd *node) IsLeaf() bool {
|
|
return len(nd.childs) == 0
|
|
}
|
|
|
|
func (nd *node) IsTerminal() bool {
|
|
return nd.isTerminal
|
|
}
|
|
|
|
func (nd *node) Terminal() {
|
|
nd.isTerminal = true
|
|
}
|
|
|
|
func (nd *node) Path() (path string, err error) {
|
|
var xNode Node = nd
|
|
for {
|
|
if xNode.IsRoot() {
|
|
break
|
|
}
|
|
path += xNode.PreviousSymbol()
|
|
if xNode == xNode.Parent() {
|
|
return "", CyclicDataError
|
|
}
|
|
xNode = xNode.Parent()
|
|
}
|
|
return Reverse(path), nil
|
|
}
|
|
|
|
func Reverse(reversePath string) (path string) {
|
|
length := len(reversePath)
|
|
for i := length - 1; i >= 0; i-- {
|
|
path += string(reversePath[i])
|
|
}
|
|
return path
|
|
}
|