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); } } }
public TrieNode Delete(TrieNode node, TrieKey key) { TrieNode kv_node = null; if (node.NodeType == TrieNode.TrieNodeType.BranchNode) { if (key.IsEmpty) { node.BranchNodeSetValue(null); } else { int index = key.GetHex(0); TrieNode child = node.BranchNodeGetChild(index); if (child == null) { return(node); } TrieNode new_node = Delete(child, key.Shift(1)); node.BranchNodeSetChild(index, new_node); if (new_node != null) { return(node); } } int compact_index = node.BranchNodeCompactIndex(); if (compact_index < 0) { return(node); } node.Dispose(); if (compact_index == 16) { return(new TrieNode(this, TrieKey.Empty(true), node.BranchNodeGetValue())); } else { kv_node = new TrieNode(this, TrieKey.SingleHex(compact_index), node.BranchNodeGetChild(compact_index)); } } else { TrieKey k = key.MatchAndShift(node.KVNodeGetKey()); if (k == null) { return(node); } else if (node.NodeType == TrieNode.TrieNodeType.KVNodeValue) { if (k.IsEmpty) { node.Dispose(); return(null); } else { return(node); } } else { TrieNode child = Delete(node.KVNodeGetChildNode(), k); if (child == null) { throw new System.Exception("Shouldn't happen"); } kv_node = node.KVNodeSetValueOrNode(child); } } TrieNode new_child = kv_node.KVNodeGetChildNode(); if (new_child.NodeType != TrieNode.TrieNodeType.BranchNode) { TrieKey new_key = kv_node.KVNodeGetKey().Concat(new_child.KVNodeGetKey()); TrieNode new_node = new TrieNode(this, new_key, new_child.KVNodeGetValueOrNode()); new_child.Dispose(); kv_node.Dispose(); return(new_node); } else { return(kv_node); } }