package merkletrie

import (
	
	

	
	
)
Iter is an iterator for merkletries (only the trie part of the merkletrie is relevant here, it does not use the Hasher interface). The iteration is performed in depth-first pre-order. Entries at each depth are traversed in (case-sensitive) alphabetical order. This is the kind of traversal you will expect when listing ordinary files and directories recursively, for example: Trie Traversal order ---- --------------- . / | \ c / | \ d/ d c z ===> d/a / \ d/b b a z This iterator is somewhat especial as you can chose to skip whole "directories" when iterating: - The Step method will iterate normally. - the Next method will not descend deeper into the tree. For example, if the iterator is at `d/`, the Step method will return `d/a` while the Next would have returned `z` instead (skipping `d/` and its descendants). The name of the these two methods are based on the well known "next" and "step" operations, quite common in debuggers, like gdb. The paths returned by the iterator will be relative, if the iterator was created from a single node, or absolute, if the iterator was created from the path to the node (the path will be prefixed to all returned paths).
Tells if the iteration has started.
The top of this stack has the current node and its siblings. The rest of the stack keeps the ancestors of the current node and their corresponding siblings. The current element is always the top element of the top frame. When "step"ping into a node, its children are pushed as a new frame. When "next"ing pass a node, the current element is dropped by popping the top frame.
The base path used to turn the relative paths used internally by the iterator into absolute paths used by external applications. For relative iterator this will be nil.
NewIter returns a new relative iterator using the provider noder as its unnamed root. When iterating, all returned paths will be relative to node.
func ( noder.Noder) (*Iter, error) {
	return newIter(, nil)
}
NewIterFromPath returns a new absolute iterator from the noder at the end of the path p. When iterating, all returned paths will be absolute, using the root of the path p as their root.
func ( noder.Path) (*Iter, error) {
	return newIter(, ) // Path implements Noder
}

func ( noder.Noder,  noder.Path) (*Iter, error) {
	 := &Iter{
		base: ,
	}

	if  == nil {
		return , nil
	}

	,  := frame.New()
	if  != nil {
		return nil, 
	}
	.push()

	return , nil
}

func ( *Iter) () (*frame.Frame, bool) {
	if len(.frameStack) == 0 {
		return nil, false
	}
	 := len(.frameStack) - 1

	return .frameStack[], true
}

func ( *Iter) ( *frame.Frame) {
	.frameStack = append(.frameStack, )
}

const (
	doDescend   = true
	dontDescend = false
)
Next returns the path of the next node without descending deeper into the trie and nil. If there are no more entries in the trie it returns nil and io.EOF. In case of error, it will return nil and the error.
func ( *Iter) () (noder.Path, error) {
	return .advance(dontDescend)
}
Step returns the path to the next node in the trie, descending deeper into it if needed, and nil. If there are no more nodes in the trie, it returns nil and io.EOF. In case of error, it will return nil and the error.
func ( *Iter) () (noder.Path, error) {
	return .advance(doDescend)
}
Advances the iterator in the desired direction: descend or dontDescend. Returns the new current element and a nil error on success. If there are no more elements in the trie below the base, it returns nil, and io.EOF. Returns nil and an error in case of errors.
func ( *Iter) ( bool) (noder.Path, error) {
	,  := .current()
	if  != nil {
		return nil, 
	}
The first time we just return the current node.
	if !.hasStarted {
		.hasStarted = true
		return , nil
	}
Advances means getting a next current node, either its first child or its next sibling, depending if we must descend or not.
	,  := .NumChildren()
	if  != nil {
		return nil, 
	}

	 :=  != 0 && 
descend: add a new frame with the current's children.
		,  := frame.New()
		if  != nil {
			return nil, 
		}
		.push()
don't descend: just drop the current node
		.drop()
	}

	return .current()
}
Returns the path to the current node, adding the base if there was one, and a nil error. If there were no noders left, it returns nil and io.EOF. If an error occurred, it returns nil and the error.
func ( *Iter) () (noder.Path, error) {
	if ,  := .top(); ! {
		return nil, io.EOF
	} else if ,  := .First(); ! {
		return nil, io.EOF
	}

	 := make(noder.Path, 0, len(.base)+len(.frameStack))
concat the base...
... and the current node and all its ancestors
	for ,  := range .frameStack {
		,  := .First()
		if ! {
			panic(fmt.Sprintf("frame %d is empty", ))
		}
		 = append(, )
	}

	return , nil
}
removes the current node if any, and all the frames that become empty as a consequence of this action.
func ( *Iter) () {
	,  := .top()
	if ! {
		return
	}

if the frame is empty, remove it and its parent, recursively
	if .Len() == 0 {
		 := len(.frameStack) - 1
		.frameStack[] = nil
		.frameStack = .frameStack[:]
		.()
	}