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)); }