private void MakeStack(ShaMapInner root, Hash256 index)
        {
            _inners = new LinkedList <ShaMapInner>();
            var top = root;

            while (true)
            {
                _inners.AddLast(top);
                var existing = top.GetBranch(index);
                if (existing == null)
                {
                    break;
                }
                if (existing.IsLeaf)
                {
                    Leaf     = existing.AsLeaf();
                    _matched = Leaf.Index.Equals(index);
                    break;
                }
                if (existing.IsInner)
                {
                    top = existing.AsInner();
                }
            }
        }
        private void CopyInnersToDirtiedArray()
        {
            var ix = 0;

            _dirtied = new ShaMapInner[_inners.Count];
            IEnumerator <ShaMapInner> descending = _inners.GetEnumerator();

            while (descending.MoveNext())
            {
                ShaMapInner next = descending.Current;
                _dirtied[ix++] = next;
                next.Invalidate();
            }
        }
        private void Compare(ShaMapInner a, ShaMapInner b)
        {
            for (var i = 0; i < 16; i++)
            {
                var aChild = a.GetBranch(i);
                var bChild = b.GetBranch(i);

                if (aChild == null && bChild != null)
                {
                    TrackAdded(bChild);
                    // added in B
                }
                else if (aChild != null && bChild == null)
                {
                    TrackRemoved(aChild);
                    // removed from B
                }
                else if (aChild != null && !aChild.Hash().Equals(bChild.Hash()))
                {
                    bool aleaf = aChild.IsLeaf,
                         bLeaf = bChild.IsLeaf;

                    if (aleaf && bLeaf)
                    {
                        var la = aChild.AsLeaf();
                        var lb = bChild.AsLeaf();
                        if (la.Index.Equals(lb.Index))
                        {
                            Modified.Add(la.Index);
                        }
                        else
                        {
                            Deleted.Add(la.Index);
                            Added.Add(lb.Index);
                        }
                    }
                    else if (aleaf)
                    { //&& bInner
                        var la = aChild.AsLeaf();
                        var ib = bChild.AsInner();
                        TrackAdded(ib);

                        if (ib.HasLeaf(la.Index))
                        {
                            // because trackAdded would have added it
                            Added.Remove(la.Index);
                            var leaf = ib.GetLeaf(la.Index);
                            if (!leaf.Hash().Equals(la.Hash()))
                            {
                                Modified.Add(la.Index);
                            }
                        }
                        else
                        {
                            Deleted.Add(la.Index);
                        }
                    }
                    else if (bLeaf)
                    { //&& aInner
                        var lb = bChild.AsLeaf();
                        var ia = aChild.AsInner();
                        TrackRemoved(ia);

                        if (ia.HasLeaf(lb.Index))
                        {
                            // because trackRemoved would have deleted it
                            Deleted.Remove(lb.Index);
                            var leaf = ia.GetLeaf(lb.Index);
                            if (!leaf.Hash().Equals(lb.Hash()))
                            {
                                Modified.Add(lb.Index);
                            }
                        }
                        else
                        {
                            Added.Add(lb.Index);
                        }
                    }
                    else //if (aInner && bInner)
                    {
                        Compare(aChild.AsInner(), bChild.AsInner());
                    }
                }
            }
        }
 public PathToIndex(ShaMapInner root, Hash256 index)
 {
     Index = index;
     MakeStack(root, index);
 }