def get_node_value(self, node, key): _node_type = self.node_type(node) if _node_type == 'Branch': #key="", find if not key: return node[-1] child = node[key[0]] return self.get_node_value(self.decode(child), key[1:]) if _node_type == 'Blank': return "" #leaf node or extension node original_key = encoding.terminator(encoding.hp_to_hex(node[0]), False) if _node_type == "Leaf": if key == original_key: return node[1] else: return "" if _node_type == "Extension": #check new_key is in the prefix of key if len(original_key) > len(key) or key[:len(original_key)] != original_key: return "" else: return self.get_node_value(self.decode(node[1]), key[len(original_key):])
def _iter_subtree(self, node): _node_type = self.node_type(node) if _node_type == "Blank": return {} if _node_type == "Branch": result = {} for i in range(16): res = self._iter_subtree(self.decode(node[i])) for key, value in res.items(): #print("key:",key) original_key = str(i) + "," + key #print("ori:",original_key) result[original_key] = value if node[-1]: result["16"] = node[-1] return result tmp = encoding.terminator(encoding.hp_to_hex(node[0]), False) key = ",".join([str(t) for t in tmp]) if _node_type == "Extension": res = self._iter_subtree(self.decode(node[1])) if _node_type == "Leaf": res = {"16": node[1]} result = {} for key2, value in res.items(): print('key:', key, "key2:", key2, "value:", value) original_key = key + "," + key2 result[original_key] = value return result
def node_type(self, node): if len(node) == 17: return "Branch" elif len(node) == 2: nib = encoding.hp_to_hex(node[0]) #print("nib",nib) if nib[-1] == END: return "Leaf" else: return "Extension" elif node == "": return "Blank" else: raise TypeError("There is no this node type!")
def search_prefix(self, node, prefix, curr_prefix): _node_type = self.node_type(node) print("type:", _node_type) #check this type #print("prefix:",prefix) if not prefix: return node, curr_prefix if _node_type == "Blank": return "", curr_prefix if _node_type == "Branch": if not prefix: return node, curr_prefix child = node[prefix[0]] curr_prefix += [prefix[0]] #print(self.decode(child)) node, curr_prefix = self.search_prefix(self.decode(child), prefix[1:], curr_prefix) return node, curr_prefix #leaf node or extension node key = encoding.terminator(encoding.hp_to_hex(node[0]), False) if _node_type == "Leaf": #print("prefix:", prefix, "key:", key) if len(prefix) < len(key) and prefix == key[:len(prefix)]: return node, curr_prefix else: return "", curr_prefix if _node_type == "Extension": print("extendsion node:", node, "key:", key, "prefix:", prefix) if len(prefix) < len(key) and prefix == key[:len(prefix)]: return node, curr_prefix elif prefix not in key and len(prefix) < len(key): return "", curr_prefix elif len(prefix) > len(key) and prefix[:len(key)] != key: return "", curr_prefix else: curr_prefix += key node, curr_prefix = self.search_prefix(self.decode(node[1]), prefix[len(key):], curr_prefix) return node, curr_prefix
def update_node(self, node, key, value): _node_type = self.node_type(node) #print("Node Type:", _node_type) if _node_type == 'Branch': #key空,直接將value 存在branch node 的最後 if not key: node[-1] = value #沿著branch node繼續往下找 else: new_node = self.update_and_delete(self.decode(node[key[0]]), key[1:], value) node[key[0]] = self.update_db(new_node) return node elif _node_type == 'Leaf' or _node_type == 'Extension': original_key = ori_key = encoding.terminator(encoding.hp_to_hex(node[0]),False) prefix = 0 for i in range(min(len(ori_key), len(key))): if key[i] != ori_key[i]: break prefix = i + 1 key = key[prefix:] ori_key = ori_key[prefix:] #與現在node's key一樣 if key == ori_key == []: if _node_type == 'Leaf': return [node[0], value] new_node = self.update_and_delete(self.decode(node[1]), key, value) elif ori_key == []: #查此extension node的child if _node_type == 'Extension': new_node = self.update_and_delete(self.decode(node[1]), key, value) #如果是leaf node 開一個branch node 將原本node和new node放進新的branch else: new_node = [""]*17 new_node[-1] = node[1] new_node[key[0]] = self.update_db([encoding.hex_to_hp(encoding.terminator(key[1:],True)), value]) else: new_node = [""]*17 if len(ori_key) == 1 and _node_type == "Extension": new_node[ori_key[0]] = node[1] else: if _node_type == "Extension": ter = False else: ter = True new_node[ori_key[0]] = self.update_db([encoding.hex_to_hp(encoding.terminator(ori_key[1:],ter)),node[1]]) #if key空 value直接放進branch,else 把剩下的key value存入branch if key == []: new_node[-1] = value else: new_node[key[0]] = self.update_db([encoding.hex_to_hp(encoding.terminator(key[1:],True)), value]) #change current node to a extension node which connected with the branch node we create above if prefix > 0: new_node = [encoding.hex_to_hp(original_key[:prefix]), self.update_db(new_node)] return new_node elif _node_type == "Blank": return [encoding.hex_to_hp(encoding.terminator(key,True)), value]
def delete_node(self, node, key): _node_type = self.node_type(node) if _node_type == "Blank": return "" elif _node_type == "Branch": #key empty, find it if not key: node[-1] = "" #print("Node after delete",node) else: new_node = self.delete_and_delete(self.decode(node[key[0]]), key[1:]) new_node = self.update_db(new_node) if new_node == node[key[0]]: return node else: node[key[0]] = new_node #after deleting, if the branch node has only one child, change it into extension/leaf node count = 0 not_blank = [] for idx in range(17): if node[idx] != "": count += 1 not_blank.append(idx) if count > 1: return node else: #return leaf node if not_blank[0] == END: return [encoding.hex_to_hp(encoding.terminator([], True)), node[-1]] else: child_node = self.decode(node[not_blank[0]]) child_node_type = self.node_type(child_node) if child_node_type == "Branch": return [encoding.hex_to_hp(not_blank), self.update_db(child_node)] elif child_node_type == "Leaf" or child_node_type == "Extension": new_key = not_blank + encoding.hp_to_hex(child_node[0]) return [encoding.hex_to_hp(new_key), child_node[1]] else: original_key = encoding.terminator(encoding.hp_to_hex(node[0]),False) if _node_type == "Leaf": if original_key == key: return "" else: return node if len(original_key) > len(key) or key[:len(original_key)] != original_key: return node new_node = self.delete_and_delete(self.decode(node[1]), key[len(original_key):]) #child is not found if new_node == self.decode(node[1]): return node if new_node == "": return "" #some nodes have been changed else: new_node_type = self.node_type(new_node) if new_node_type == "Branch": return [encoding.hex_to_hp(original_key), self.update_db(new_node)] else: original_key = original_key + encoding.hp_to_hex(new_node[0]) return [encoding.hex_to_hp(original_key), new_node[1]]