def _set_kv_node(self, node, trie_key, value): current_key = extract_key(node) common_prefix, current_key_remainder, trie_key_remainder = consume_common_prefix( current_key, trie_key, ) is_extension = is_extension_node(node) if not current_key_remainder and not trie_key_remainder: if is_leaf_node(node): return [node[0], value] else: sub_node = self._get_node(node[1]) # TODO: this needs to cleanup old storage. new_node = self._set(sub_node, trie_key_remainder, value) elif not current_key_remainder: if is_extension: sub_node = self._get_node(node[1]) # TODO: this needs to cleanup old storage. new_node = self._set(sub_node, trie_key_remainder, value) else: subnode_position = trie_key_remainder[0] subnode_key = compute_leaf_key(trie_key_remainder[1:]) sub_node = [subnode_key, value] new_node = [BLANK_NODE] * 16 + [node[1]] new_node[subnode_position] = self._persist_node(sub_node) else: new_node = [BLANK_NODE] * 17 if len(current_key_remainder) == 1 and is_extension: new_node[current_key_remainder[0]] = node[1] else: if is_extension: compute_key_fn = compute_extension_key else: compute_key_fn = compute_leaf_key new_node[current_key_remainder[0]] = self._persist_node([ compute_key_fn(current_key_remainder[1:]), node[1], ]) if trie_key_remainder: new_node[trie_key_remainder[0]] = self._persist_node([ compute_leaf_key(trie_key_remainder[1:]), value, ]) else: new_node[-1] = value if common_prefix: new_node_key = self._persist_node(new_node) return [compute_extension_key(common_prefix), new_node_key] else: return new_node
def test_iter_error(): trie = HexaryTrie({}) trie[b'cat'] = b'cat' trie[b'dog'] = b'dog' trie[b'bird'] = b'bird' assert is_extension_node(trie.root_node) node_to_remove = trie.root_node[1] trie.db.pop(node_to_remove) iterator = NodeIterator(trie) key = b'' with pytest.raises(KeyError): while key is not None: key = iterator.next(key)