Example #1
0
        private TrieNode Insert(TrieNode node, TrieKey key, object node_or_value)
        {
            if (node.NodeType == TrieNode.TrieNodeType.BranchNode)
            {
                if (key.IsEmpty)
                {
                    return(node.BranchNodeSetValue((byte[])node_or_value));
                }
                TrieNode child = node.BranchNodeGetChild(key.GetHex(0));
                if (child != null)
                {
                    return(node.BranchNodeSetChild(key.GetHex(0), Insert(child, key.Shift(1), node_or_value)));
                }
                else
                {
                    TrieKey  child_key = key.Shift(1);
                    TrieNode new_child;
                    if (!child_key.IsEmpty)
                    {
                        new_child = new TrieNode(this, child_key, node_or_value);
                    }
                    else
                    {
                        new_child = node_or_value is TrieNode ? (TrieNode)node_or_value : new TrieNode(this, child_key, node_or_value);
                    }
                    return(node.BranchNodeSetChild(key.GetHex(0), new_child));
                }
            }
            else
            {
                TrieKey current_node_key = node.KVNodeGetKey();
                TrieKey common_prefix    = key.GetCommonPrefix(current_node_key);
                if (common_prefix.IsEmpty)
                {
                    TrieNode new_branch = new TrieNode(this);
                    Insert(new_branch, current_node_key, node.KVNodeGetValueOrNode());
                    Insert(new_branch, key, node_or_value);
                    node.Dispose();
                    return(new_branch);
                }
                else if (common_prefix.Equals(key))
                {
                    return(node.KVNodeSetValueOrNode(node_or_value));
                }
                else if (common_prefix.Equals(current_node_key))
                {
                    Insert(node.KVNodeGetChildNode(), key.Shift(common_prefix.GetLength()), node_or_value);
                    return(node.Invalidate());
                }
                else
                {
                    TrieNode new_branch = new TrieNode(this);
                    TrieNode newKvNode  = new TrieNode(this, common_prefix, new_branch);

                    Insert(newKvNode, current_node_key, node.KVNodeGetValueOrNode());
                    Insert(newKvNode, key, node_or_value);
                    node.Dispose();
                    return(newKvNode);
                }
            }
        }