aboutsummaryrefslogtreecommitdiffstats
path: root/utils/merkletrie/index/node.go
diff options
context:
space:
mode:
Diffstat (limited to 'utils/merkletrie/index/node.go')
-rw-r--r--utils/merkletrie/index/node.go86
1 files changed, 86 insertions, 0 deletions
diff --git a/utils/merkletrie/index/node.go b/utils/merkletrie/index/node.go
new file mode 100644
index 0000000..2c72f6d
--- /dev/null
+++ b/utils/merkletrie/index/node.go
@@ -0,0 +1,86 @@
+package index
+
+import (
+ "path/filepath"
+ "strings"
+
+ "gopkg.in/src-d/go-git.v4/plumbing/format/index"
+ "gopkg.in/src-d/go-git.v4/utils/merkletrie/noder"
+)
+
+// The node represents a index.Entry or a directory inferred from the path
+// of all entries. It implements the interface noder.Noder of merkletrie
+// package.
+//
+// This implementation implements a "standard" hash method being able to be
+// compared with any other noder.Noder implementation inside of go-git
+type node struct {
+ path string
+ entry index.Entry
+ children []noder.Noder
+ isDir bool
+}
+
+// NewRootNode returns the root node of a computed tree from a index.Index,
+func NewRootNode(idx *index.Index) noder.Noder {
+ const rootNode = ""
+
+ m := map[string]*node{rootNode: {isDir: true}}
+
+ for _, e := range idx.Entries {
+ parts := strings.Split(e.Name, string(filepath.Separator))
+
+ var path string
+ for _, part := range parts {
+ parent := path
+ path = filepath.Join(path, part)
+
+ if _, ok := m[path]; ok {
+ continue
+ }
+
+ n := &node{path: path}
+ if path == e.Name {
+ n.entry = e
+ } else {
+ n.isDir = true
+ }
+
+ m[n.path] = n
+ m[parent].children = append(m[parent].children, n)
+ }
+ }
+
+ return m[rootNode]
+}
+
+func (n *node) String() string {
+ return n.path
+}
+
+// Hash the hash of a filesystem is a 24-byte slice, is the result of
+// concatenating the computed plumbing.Hash of the file as a Blob and its
+// plumbing.FileMode; that way the difftree algorithm will detect changes in the
+// contents of files and also in their mode.
+//
+// If the node is computed and not based on a index.Entry the hash is equals
+// to a 24-bytes slices of zero values.
+func (n *node) Hash() []byte {
+ return append(n.entry.Hash[:], n.entry.Mode.Bytes()...)
+}
+
+func (n *node) Name() string {
+ return filepath.Base(n.path)
+}
+
+func (n *node) IsDir() bool {
+ return n.isDir
+}
+
+func (n *node) Children() ([]noder.Noder, error) {
+ return n.children, nil
+}
+
+func (n *node) NumChildren() (int, error) {
+ return len(n.children), nil
+}