diff options
author | Alberto Cortés <alcortesm@gmail.com> | 2016-11-24 15:29:22 +0100 |
---|---|---|
committer | Máximo Cuadros <mcuadros@gmail.com> | 2016-11-24 15:29:22 +0100 |
commit | 8966c042795509ed17730e50d352ad69901c3da8 (patch) | |
tree | 3ce51d49f134d440f73f268ecaaf00bffa980e8c /difftree/internal/merkletrie/frame.go | |
parent | 81c5d2c6c672509ee7f30a346b890f3920ff20c1 (diff) | |
download | go-git-8966c042795509ed17730e50d352ad69901c3da8.tar.gz |
mv difftree/internal/radixmerkle to difftre/internal/merkletrie (#138)
Diffstat (limited to 'difftree/internal/merkletrie/frame.go')
-rw-r--r-- | difftree/internal/merkletrie/frame.go | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/difftree/internal/merkletrie/frame.go b/difftree/internal/merkletrie/frame.go new file mode 100644 index 0000000..a40c6ad --- /dev/null +++ b/difftree/internal/merkletrie/frame.go @@ -0,0 +1,79 @@ +package merkletrie + +import ( + "bytes" + "fmt" +) + +const sep = "/" + +// A frame represents siblings in a trie, along with the path to get to +// them. For example the frame for the node with key `b` in this trie: +// +// a +// / \ +// / \ +// / \ +// b c +// /|\ / \ +// y z x d e +// | +// g +// +// would be: +// +// f := frame{ +// base: "a/b", // path to the siblings +// stack: []Node{z, y, x} // in reverse alphabetical order +// } +type frame struct { + base string // absolute key of their parents + stack []Noder // siblings, sorted in reverse alphabetical order by key +} + +// newFrame returns a frame for the children of a node n. +func newFrame(parentAbsoluteKey string, n Noder) *frame { + return &frame{ + base: parentAbsoluteKey + sep + n.Key(), + stack: n.Children(), + } +} + +func (f *frame) String() string { + var buf bytes.Buffer + _, _ = buf.WriteString(fmt.Sprintf("base=%q, stack=[", f.base)) + + sep := "" + for _, e := range f.stack { + _, _ = buf.WriteString(sep) + sep = ", " + _, _ = buf.WriteString(fmt.Sprintf("%q", e.Key())) + } + + _ = buf.WriteByte(']') + + return buf.String() +} + +func (f *frame) top() (Noder, bool) { + if len(f.stack) == 0 { + return nil, false + } + + top := len(f.stack) - 1 + + return f.stack[top], true +} + +func (f *frame) pop() (Noder, bool) { + if len(f.stack) == 0 { + return nil, false + } + + top := len(f.stack) - 1 + ret := f.stack[top] + f.stack[top] = nil + f.stack = f.stack[:top] + + return ret, true +} |