Пример #1
0
        public static IHashTrieNode?ModifyChildren(
            InternalNode node, byte h, ulong value, IEnumerable <byte[]> childrenHashes, byte[]?valueHash
            )
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }

            var was = node.GetChildByHash(h);

            if (was == value)
            {
                return(node);
            }

            List <byte[]> newHashes;
            var           newNode = new InternalNode();
            var           pos     = (int)BitsUtils.PositionOf(node.ChildrenMask, h);

            if (was == 0)
            {
                if (valueHash is null)
                {
                    throw new ArgumentNullException(nameof(valueHash));
                }
                newNode._children = new ulong[node._children.Length + 1];
                for (var i = 0; i <= node._children.Length; ++i)
                {
                    newNode._children[i] = i < pos ? node._children[i] : (i == pos ? value : node._children[i - 1]);
                }
                newNode.ChildrenMask = node.ChildrenMask | (1u << h);
                newHashes            = childrenHashes.ToList();
                newHashes.Insert(pos, valueHash);
                newNode.UpdateHash(newHashes, GetChildrenLabels(newNode.ChildrenMask));
                return(newNode);
            }

            if (value == 0)
            {
                if (node._children.Length == 1)
                {
                    return(null);
                }
                newNode._children = new ulong[node._children.Length - 1];
                for (var i = 0; i + 1 < node._children.Length; ++i)
                {
                    newNode._children[i] = i < pos ? node._children[i] : node._children[i + 1];
                }
                newNode.ChildrenMask = node.ChildrenMask ^ (1u << h);
                newHashes            = childrenHashes.ToList();
                newHashes.RemoveAt(pos);
                newNode.UpdateHash(newHashes, GetChildrenLabels(newNode.ChildrenMask));
                return(newNode);
            }

            newNode._children      = node._children.ToArray();
            newNode.ChildrenMask   = node.ChildrenMask;
            newNode._children[pos] = value;
            newHashes      = childrenHashes.ToList();
            newHashes[pos] = valueHash ?? throw new ArgumentNullException(nameof(valueHash));
            newNode.UpdateHash(newHashes, GetChildrenLabels(newNode.ChildrenMask));
            return(newNode);
        }
Пример #2
0
 public ulong GetChildByHash(byte h)
 {
     return((ChildrenMask & (1u << h)) == 0 ? 0ul : _children[BitsUtils.PositionOf(ChildrenMask, h)]);
 }