def create_node(shift, key1, val1, key2hash, key2, val2): key1hash = rt.hash(key1) if key1hash == key2hash: return HashCollisionNode(None, key1hash, [key1, val1, key2, val2]) added_leaf = Box() return BitmapIndexedNode_EMPTY.assoc_inode(shift, key1hash, key1, val1, added_leaf) \ .assoc_inode(shift, key1hash, key1, val1, added_leaf)
def _contains_key(self, key): assert isinstance(self, PersistentHashMap) if self._root is not None: return true if self._root.find(r_uint(0), rt.hash(key), key, NOT_FOUND) is not NOT_FOUND else false else: return false
def create_node(shift, key1, val1, key2hash, key2, val2): key1hash = rt.hash(key1) & MASK_32 if key1hash == key2hash: return HashCollisionNode(None, key1hash, [key1, val1, key2, val2]) added_leaf = Box() return BitmapIndexedNode_EMPTY.assoc_inode(shift, key1hash, key1, val1, added_leaf) \ .assoc_inode(shift, key2hash, key2, val2, added_leaf)
def without(self, key): if self._root is None: return self new_root = self._root.without_inode(0, rt.hash(key) & MASK_32, key) if new_root is self._root: return self return PersistentHashMap(self._cnt - 1, new_root, self._meta)
def assoc(self, key, val): added_leaf = Box() new_root = (BitmapIndexedNode_EMPTY if self._root is None else self._root) \ .assoc_inode(r_uint(0), rt.hash(key), key, val, added_leaf) if new_root is self._root: return self return PersistentHashMap(self._cnt if added_leaf._val is None else self._cnt + 1, new_root, self._meta)
def assoc(self, key, val): added_leaf = Box() new_root = (BitmapIndexedNode_EMPTY if self._root is None else self._root) \ .assoc_inode(r_uint(0), rt.hash(key) & MASK_32, key, val, added_leaf) if new_root is self._root: return self return PersistentHashMap( self._cnt if added_leaf._val is None else self._cnt + 1, new_root, self._meta)
def update_hash_unordered(self, itm): self._n += 1 self._hash += rt.hash(itm) return self
def update_hash_ordered(self, itm): self._n += 1 self._hash = 31 * self._hash + rt.hash(itm) return self
def val_at(self, key, not_found): return not_found if self._root is None else self._root.find( r_uint(0), rt.hash(key) & MASK_32, key, not_found)
def assoc_inode(self, shift, hash_val, key, val, added_leaf): bit = bitpos(hash_val, shift) idx = self.index(bit) if (self._bitmap & bit) != 0: key_or_null = self._array[2 * idx] val_or_node = self._array[2 * idx + 1] if key_or_null is None: assert isinstance(val_or_node, INode) n = val_or_node.assoc_inode(shift + 5, hash_val & MASK_32, key, val, added_leaf) if n is val_or_node: return self return BitmapIndexedNode( None, self._bitmap, clone_and_set(self._array, 2 * idx + 1, n)) if rt.eq(key, key_or_null): if val is val_or_node: return self return BitmapIndexedNode( None, self._bitmap, clone_and_set(self._array, 2 * idx + 1, val)) added_leaf._val = added_leaf return BitmapIndexedNode( None, self._bitmap, clone_and_set2( self._array, 2 * idx, None, 2 * idx + 1, create_node(shift + 5, key_or_null, val_or_node, hash_val, key, val))) else: n = bit_count(self._bitmap) if n >= 16: nodes = [None] * 32 jdx = mask(hash_val, shift) nodes[jdx] = BitmapIndexedNode_EMPTY.assoc_inode( shift + 5, hash_val, key, val, added_leaf) j = 0 for i in range(32): if (self._bitmap >> i) & 1 != 0: if self._array[j] is None: nodes[i] = self._array[j + 1] else: nodes[i] = BitmapIndexedNode_EMPTY.assoc_inode( shift + 5, rt.hash(self._array[j]), self._array[j], self._array[j + 1], added_leaf) j += 2 return ArrayNode(None, n + 1, nodes) else: new_array = [None] * (2 * (n + 1)) list_copy(self._array, 0, new_array, 0, 2 * idx) new_array[2 * idx] = key added_leaf._val = added_leaf new_array[2 * idx + 1] = val list_copy(self._array, 2 * idx, new_array, 2 * (idx + 1), 2 * (n - idx)) return BitmapIndexedNode(None, self._bitmap | bit, new_array)
def assoc_inode(self, shift, hash_val, key, val, added_leaf): bit = bitpos(hash_val, shift) idx = self.index(bit) if (self._bitmap & bit) != 0: key_or_null = self._array[2 * idx] val_or_node = self._array[2 * idx + 1] if key_or_null is None: assert isinstance(val_or_node, INode) n = val_or_node.assoc_inode(shift + 5, hash_val, key, val, added_leaf) if n is val_or_node: return self return BitmapIndexedNode(None, self._bitmap, clone_and_set(self._array, 2 * idx + 1, n)) if key_or_null is None or rt.eq(key, key_or_null): if val is val_or_node: return self return BitmapIndexedNode(None, self._bitmap, clone_and_set(self._array, 2 * idx + 1, val)) added_leaf._val = added_leaf return BitmapIndexedNode(None, self._bitmap, clone_and_set2(self._array, 2 * idx, None, 2 * idx + 1, create_node(shift+ 5, key_or_null, val_or_node, hash_val, key, val))) else: n = bit_count(self._bitmap) if n >= 16: nodes = [None] * 32 jdx = mask(hash_val, shift) nodes[jdx] = BitmapIndexedNode_EMPTY.assoc_inode(shift + 5, hash_val, key, val, added_leaf) j = 0 for i in range(32): if (self._bitmap >> i) & 1 != 0: if self._array[j] is None: nodes[i] = self._array[j + 1] else: nodes[i] = BitmapIndexedNode_EMPTY.assoc_inode(shift + 5, rt.hash(self._array[j]), self._array[j], self._array[j + 1], added_leaf) j += 1 return ArrayNode(None, n + 1, nodes) else: new_array = [None] * (2 * (n + 1)) list_copy(self._array, 0, new_array, 0, 2 * idx) new_array[2 * idx] = key added_leaf._val = added_leaf new_array[2 * idx + 1] = val list_copy(self._array, 2 * idx, new_array, 2 * (idx + 1), 2 * (n - idx)) return BitmapIndexedNode(None, self._bitmap | bit, new_array)
def val_at(self, key, not_found): return not_found if self._root is None else self._root.find(r_uint(0), rt.hash(key), key, not_found)