Esempio n. 1
0
        public void ScanTree(TrieNode node, TrieKey key, IScanAction scan_action)
        {
            if (node != null)
            {
                if (node.Hash != null)
                {
                    scan_action.OnNode(node.Hash, node);
                }

                if (node.NodeType == TrieNode.TrieNodeType.BranchNode)
                {
                    if (node.BranchNodeGetValue() != null)
                    {
                        scan_action.OnValue(node.Hash, node, key.ToNormal(), node.BranchNodeGetValue());
                    }

                    for (int i = 0; i < 16; i++)
                    {
                        ScanTree(node.BranchNodeGetChild(i), key.Concat(TrieKey.SingleHex(i)), scan_action);
                    }
                }
                else if (node.NodeType == TrieNode.TrieNodeType.KVNodeNode)
                {
                    ScanTree(node.KVNodeGetChildNode(), key.Concat(node.KVNodeGetKey()), scan_action);
                }
                else
                {
                    scan_action.OnValue(node.Hash, node, key.Concat(node.KVNodeGetKey()).ToNormal(), node.KVNodeGetValue());
                }
            }
        }
Esempio n. 2
0
        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);
            }
        }