2
2
mirror of https://github.com/octoleo/restic.git synced 2024-05-28 14:40:49 +00:00
restic/internal/restic/tree.go

101 lines
2.0 KiB
Go
Raw Normal View History

2014-12-05 20:45:49 +00:00
package restic
2014-04-21 21:25:31 +00:00
import (
2014-08-11 20:47:24 +00:00
"fmt"
2014-11-30 21:34:21 +00:00
"sort"
2014-09-18 20:41:24 +00:00
2017-07-23 12:21:03 +00:00
"github.com/restic/restic/internal/errors"
2017-07-23 12:21:03 +00:00
"github.com/restic/restic/internal/debug"
2014-04-21 21:25:31 +00:00
)
2016-09-01 20:08:45 +00:00
// Tree is an ordered list of nodes.
type Tree struct {
Nodes []*Node `json:"nodes"`
}
2014-04-21 21:25:31 +00:00
2016-09-01 20:08:45 +00:00
// NewTree creates a new tree object.
func NewTree() *Tree {
return &Tree{
Nodes: []*Node{},
}
}
2018-01-04 19:44:53 +00:00
func (t *Tree) String() string {
return fmt.Sprintf("Tree<%d nodes>", len(t.Nodes))
}
2014-11-30 21:34:21 +00:00
// Equals returns true if t and other have exactly the same nodes.
2018-01-04 19:44:53 +00:00
func (t *Tree) Equals(other *Tree) bool {
if len(t.Nodes) != len(other.Nodes) {
2016-09-27 20:35:08 +00:00
debug.Log("tree.Equals(): trees have different number of nodes")
return false
}
for i := 0; i < len(t.Nodes); i++ {
if !t.Nodes[i].Equals(*other.Nodes[i]) {
2016-09-27 20:35:08 +00:00
debug.Log("tree.Equals(): node %d is different:", i)
debug.Log(" %#v", t.Nodes[i])
debug.Log(" %#v", other.Nodes[i])
return false
}
}
return true
2014-11-30 21:34:21 +00:00
}
2016-09-01 20:08:45 +00:00
// Insert adds a new node at the correct place in the tree.
2014-11-30 21:34:21 +00:00
func (t *Tree) Insert(node *Node) error {
2018-01-04 19:44:53 +00:00
pos, found := t.find(node.Name)
if found != nil {
return errors.Errorf("node %q already present", node.Name)
2014-11-30 21:34:21 +00:00
}
2015-02-15 13:44:54 +00:00
// https://code.google.com/p/go-wiki/wiki/SliceTricks
t.Nodes = append(t.Nodes, &Node{})
copy(t.Nodes[pos+1:], t.Nodes[pos:])
t.Nodes[pos] = node
2014-11-30 21:34:21 +00:00
return nil
}
2018-01-04 19:44:53 +00:00
func (t *Tree) find(name string) (int, *Node) {
pos := sort.Search(len(t.Nodes), func(i int) bool {
return t.Nodes[i].Name >= name
2014-11-30 21:34:21 +00:00
})
if pos < len(t.Nodes) && t.Nodes[pos].Name == name {
2018-01-04 19:44:53 +00:00
return pos, t.Nodes[pos]
2014-11-30 21:34:21 +00:00
}
2018-01-04 19:44:53 +00:00
return pos, nil
}
// Find returns a node with the given name, or nil if none could be found.
func (t *Tree) Find(name string) *Node {
if t == nil {
return nil
}
_, node := t.find(name)
return node
2014-11-30 21:34:21 +00:00
}
2017-06-10 20:55:12 +00:00
// Sort sorts the nodes by name.
func (t *Tree) Sort() {
list := Nodes(t.Nodes)
sort.Sort(list)
t.Nodes = list
}
// Subtrees returns a slice of all subtree IDs of the tree.
2018-01-04 19:44:53 +00:00
func (t *Tree) Subtrees() (trees IDs) {
for _, node := range t.Nodes {
2016-09-01 19:20:03 +00:00
if node.Type == "dir" && node.Subtree != nil {
trees = append(trees, *node.Subtree)
}
}
return trees
}