Ejemplo n.º 1
0
 def ensureEditable(self, edit):
     if self.edit is edit:
         return self
     n = bitCount(self.bitmap)
     newArray = [None] * (2*(n+1) if n >= 0 else 4) # make room for next assoc
     arrayCopy(self.array, 0, newArray, 0, 2*n)
     return PersistentHashMap.BitmapIndexedNode(self.edit, self.bitmap, newArray)
Ejemplo n.º 2
0
        def assocEd(self, edit, shift, hsh, key, val, addedLeaf):
            bit = bitpos(hsh, shift)
            idx = self.index(bit)
            if self.bitmap & bit:
                keyOrNull = self.array[2*idx]
                valOrNode = self.array[2*idx+1]
                if keyOrNull is None:
                    n = valOrNode.assoc(edit, shift + 5, hsh, key, val, addedLeaf)
                    if n == valOrNode:
                        return self
                    return self.editAndSet(edit, 2*idx+1, n)

                if key == keyOrNull:
                    if val == valOrNode:
                        return self
                    return self.editAndSet(edit, 2*idx+1, val)
                addedLeaf.val = addedLeaf
                return self.editAndSet(edit, 2*idx, None, 2*idx+1,
                                    createNode(edit, shift + 5, keyOrNull, valOrNode, hsh, key, val))
            else:
                n = bitCount(self.bitmap)
                if n*2 < len(self.array):
                    addedLeaf.val = addedLeaf
                    editable = self.ensureEditable(edit)
                    arrayCopy(editable.array, 2*idx, editable.array, 2*(idx+1), 2*(n-idx))
                    editable.array[2*idx] = key
                    editable.array[2*idx+1] = val
                    editable.bitmap |= bit
                    return editable
                if n >= 16:
                    nodes = [None] * 32
                    jdx = mask(hsh, shift)
                    nodes[jdx] = EMPTY_BITMAP_NODE.assocEd(edit, shift + 5, hsh, key, val, addedLeaf)
                    j = 0
                    for i in range(32):
                        if (self.bitmap >> i) & 1:
                            if self.array[j] is None:
                                nodes[i] = self.array[j+1]
                            else:
                                nodes[i] = EMPTY_BITMAP_NODE.assocEd(edit,
                                                                         shift + 5,
                                                                         hash(self.array[j]),
                                                                         self.array[j],
                                                                         self.array[j+1],
                                                                         addedLeaf)
                            j += 2
                    return PersistentHashMap.ArrayNode(edit, n + 1, nodes)
                else:
                    newArray = [None] * (2*(n+4))
                    arrayCopy(self.array, 0, newArray, 0, 2*idx)
                    newArray[2*idx] = key
                    addedLeaf.val = addedLeaf
                    newArray[2*idx+1] = val
                    arrayCopy(self.array, 2*idx, newArray, 2*(idx+1), 2*(n-idx))
                    editable = self.ensureEditable(edit)
                    editable.array = newArray
                    editable.bitmap |= bit
                    return editable
Ejemplo n.º 3
0
        def assoc(self, shift,  hsh, key, val, addedLeaf):
            bit = bitpos(hsh, shift)
            idx = self.index(bit)
            if self.bitmap & bit:
                keyOrNull = self.array[2*idx]
                valOrNode = self.array[2*idx+1]

                if keyOrNull is None:
                    n = valOrNode.assoc(shift + 5, hsh, key, val, addedLeaf)
                    if n is valOrNode:
                        return self
                    return PersistentHashMap.BitmapIndexedNode(None, self.bitmap, cloneAndSet(self.array, 2*idx+1, n))

                if key == keyOrNull:
                    if val is valOrNode:
                        return self
                    return PersistentHashMap.BitmapIndexedNode(None, self.bitmap, cloneAndSet(self.array, 2*idx+1, val))

                addedLeaf.val = addedLeaf
                return PersistentHashMap.BitmapIndexedNode(None, self.bitmap,
                                        cloneAndSet(self.array,
                                            2*idx, None,
                                            2*idx+1, createNode(None, shift + 5, keyOrNull, valOrNode, hsh, key, val)))
            else:
                n = bitCount(self.bitmap)
                if n >= 16:
                    nodes = [None] * 32
                    jdx = mask(hsh, shift)
                    nodes[jdx] = EMPTY_BITMAP_NODE.assoc(shift + 5, hsh, key, val, addedLeaf)
                    j = 0
                    for i in range(0, 32):
                        if (self.bitmap >> i) & 1:
                            if self.array[j] is None:
                                nodes[i] = self.array[j+1]
                            else:
                                nodes[i] = EMPTY_BITMAP_NODE.assoc(shift + 5, hash(self.array[j]), self.array[j], self.array[j+1], addedLeaf)
                            j += 2
                    return PersistentHashMap.ArrayNode(None, n + 1, nodes)
                else:
                    newArray = self.array[:2 * idx]
                    newArray.append(key)
                    newArray.append(val)
                    newArray.extend(self.array[2*idx:])
                    addedLeaf.val = addedLeaf
                    return PersistentHashMap.BitmapIndexedNode(None, self.bitmap | bit, newArray)
Ejemplo n.º 4
0
 def index(self, bit):
     return bitCount(self.bitmap & (bit - 1))