func (h *HamtFunctional) Stats() *Stats {
	return h.hamtBase.Stats()
}
Stats walks the Hamt in a pre-order traversal and populates a Stats data
struture which it returns.
package hamt32
type HamtFunctional struct {
	hamtBase
}
func NewFunctional(tblOpt int) *HamtFunctional {
	var h = new(HamtFunctional)
	h.hamtBase.init(tblOpt)
	return h
}
func (h *HamtFunctional) IsEmpty() bool {
	return h.hamtBase.IsEmpty()
}
func (h *HamtFunctional) Nentries() uint {
	return h.hamtBase.Nentries()
}
func (h *HamtFunctional) ToFunctional() Hamt {
	return h
}
func (h *HamtFunctional) ToTransient() Hamt {
	var nh = (*HamtTransient)(h)
	return nh
}
func (h *HamtFunctional) DeepCopy() Hamt {
	var nh = new(HamtFunctional)
	nh.root = *h.root.deepCopy().(*fixedTable)
	nh.nentries = h.nentries
	nh.nograde = h.nograde
	nh.startFixed = h.startFixed
	return nh
}
func (h *HamtFunctional) persist(oldTable, newTable tableI, path tableStack) {
	_ = assertOn && assert(path.len() != 0,
		"path.len()==0; This case should be handled directly in Put & Del.")
	var depth = uint(path.len())  
	var parentDepth = depth - 1
	var parentIdx = oldTable.Hash().Index(parentDepth)
	var oldParent = path.pop()
	var newParent tableI
	if path.len() == 0 {
		h.root = *oldParent.(*fixedTable)
		newParent = &h.root
	} else {
		newParent = oldParent.copy()
	}
	if newTable == nil {
		newParent.remove(parentIdx)
	} else {
		newParent.replace(parentIdx, newTable)
	}
	if path.len() > 0 {
		h.persist(oldParent, newParent, path)
	}
	return
}
func (h *HamtFunctional) Get(key KeyI) (interface{}, bool) {
	return h.hamtBase.Get(key)
}
func (h *HamtFunctional) Put(key KeyI, val interface{}) (Hamt, bool) {
	var nh = new(HamtFunctional)
	*nh = *h
	var hv = key.Hash()
	var path, leaf, idx = h.find(hv)
	var curTable = path.pop()
	var depth = uint(path.len())
	var added bool
	if curTable == &h.root {
		if leaf == nil {
			nh.root.insert(idx, newFlatLeaf(key, val))
			added = true
		} else {
			var node nodeI
			if leaf.Hash() == hv {
				node, added = leaf.put(key, val)
			} else {
				node = nh.createTable(depth+1, leaf, newFlatLeaf(key, val))
				added = true
			}
			nh.root.replace(idx, node)
		}
	} else {
		var newTable tableI
		if leaf == nil {
			if !nh.nograde && (curTable.nentries()+1) == UpgradeThreshold {
				newTable = upgradeToFixedTable(
					curTable.Hash(), depth, curTable.entries())
			} else {
				newTable = curTable.copy()
			}
			newTable.insert(idx, newFlatLeaf(key, val))
			added = true
		} else {
			newTable = curTable.copy()
			var node nodeI
			if leaf.Hash() == hv {
				node, added = leaf.put(key, val)
			} else {
				node = nh.createTable(depth+1, leaf, newFlatLeaf(key, val))
				added = true
			}
			newTable.replace(idx, node)
		}
		nh.persist(curTable, newTable, path)
	}
	if added {
		nh.nentries++
	}
	return nh, added
}
func (h *HamtFunctional) Del(key KeyI) (Hamt, interface{}, bool) {
	if h.IsEmpty() {
		return h, nil, false
	}
	var hv = key.Hash()
	var path, leaf, idx = h.find(hv)
	if leaf == nil {
		return h, nil, false
	}
	var newLeaf, val, deleted = leaf.del(key)
	if !deleted {
		return h, nil, false
	}
	var curTable = path.pop()
	var depth = uint(path.len())
	var nh = new(HamtFunctional)
	*nh = *h
	nh.nentries--
	if curTable == &h.root {
		if newLeaf == nil {  
			nh.root.remove(idx)
		} else {  
			nh.root.replace(idx, newLeaf)
		}
	} else {
		var newTable = curTable.copy()
		if newLeaf == nil {  
			newTable.remove(idx)
			var nents = newTable.nentries()
			switch {
			case nents == 0:
				newTable = nil
			case !h.nograde && nents == DowngradeThreshold:
				newTable = downgradeToSparseTable(
					newTable.Hash(), depth, newTable.entries())
			}
		} else {  
			newTable.replace(idx, newLeaf)
		}
		nh.persist(curTable, newTable, path)
	}
	return nh, val, deleted
}
func (h *HamtFunctional) String() string {
	return "HamtFunctional{" + h.hamtBase.String() + "}"
}
func (h *HamtFunctional) LongString(indent string) string {
	return "HamtFunctional{\n" + indent + h.hamtBase.LongString(indent) + "\n}"
}
func (h *HamtFunctional) walk(fn visitFn) bool {
	return h.hamtBase.walk(fn)
}
func (h *HamtFunctional) Range(fn func(KeyI, interface{}) bool) {
	h.hamtBase.Range(fn)
}