Exemplo n.º 1
0
        private INode InsertShortNode(
            ShortNode shortNode,
            ImmutableArray <byte> prefix,
            ImmutableArray <byte> key,
            INode value)
        {
            int CommonPrefixLen(ImmutableArray <byte> a, ImmutableArray <byte> b)
            {
                var length = Math.Min(a.Length, b.Length);

                foreach (var i in Enumerable.Range(0, length))
                {
                    if (a[i] != b[i])
                    {
                        return(i);
                    }
                }

                return(length);
            }

            int commonPrefixLength = CommonPrefixLen(shortNode.Key, key);

            if (commonPrefixLength == shortNode.Key.Length)
            {
                var nn = Insert(
                    shortNode.Value,
                    prefix.AddRange(key.Take(commonPrefixLength)),
                    key.Skip(commonPrefixLength).ToImmutableArray(),
                    value);
                return(new ShortNode(shortNode.Key, nn));
            }

            var branch = new FullNode();

            branch = branch.SetChild(
                key[commonPrefixLength],
                Insert(
                    null,
                    prefix.AddRange(key.Take(commonPrefixLength + 1)),
                    key.Skip(commonPrefixLength + 1).ToImmutableArray(),
                    value));
            branch = branch.SetChild(
                shortNode.Key[commonPrefixLength],
                Insert(
                    null,
                    prefix.AddRange(shortNode.Key.Take(commonPrefixLength + 1)),
                    shortNode.Key.Skip(commonPrefixLength + 1).ToImmutableArray(),
                    shortNode.Value !));

            if (commonPrefixLength == 0)
            {
                return(branch);
            }

            // extension node
            return(new ShortNode(key.Take(commonPrefixLength).ToArray(), branch));
        }