Пример #1
0
    def __init__(self, degree):
        # This method is complete.
        self.degree = degree
        self.rootNode = BTreeNode(degree)

        # If time, file creation code, etc.
        self.nodes = {}
        self.stackOfNodes = MyStack()
        self.rootNode.setIndex(1)
        self.writeAt(1, self.rootNode)
        self.rootIndex = 1
        self.freeIndex = 2
Пример #2
0
    def __init__(self, table_dir, column, p) :
        self.table_dir = table_dir
        self.column = column

        infile = open('{}/header'.format(table_dir),'r')
        header = infile.read().strip().split(',')
        if column in header:
            self.colnum = header.index(column) # set this from dir/header and check it exists!
        else:
            print('Column named {} does not exist!'.format(column))
        infile.close()

        self.p = p
        self.root = BTreeNode(p)
Пример #3
0
    def delete(self, anItem):
        ''' Answer None if a matching item is not found.  If found,
          answer the entire item.  
        '''
        searchResult = self.searchTree(anItem)
        n = self.degree

        if searchResult['found']:  #the item is in the tree; delete it
            aNode = self.readFrom(
                searchResult['fileIndex'])  #get the node that contains anItem
            nodeIndex = searchResult['nodeIndex']
            done = False

            if not aNode.isLeaf(
            ):  #if anItem is in a leaf node, find the inorder successor
                (ioSuc, iosNode) = self.inorderSuccessor(aNode, nodeIndex)
                searchResult = self.searchTree(
                    ioSuc
                )  #search the tree in order to get the stack of nodes on the search path
                aNode.getItems(
                )[nodeIndex] = ioSuc  #replace anItem with the inorder successor
                iosNode.removeItem(
                    0)  #remove the inorder successor from its original node
                self.writeAt(aNode.getIndex(),
                             aNode)  #write the revised aNode to the file
                aNode = iosNode  #reset what aNode refers to
                anItem = ioSuc

            else:  #if anItem was already in a leaf node
                aNode.removeItem(nodeIndex)  #remove anItem from the leaf node

            while not done and aNode.getNumberOfKeys() < n and aNode.getIndex(
            ) != self.rootIndex:  #while aNode has less than n keys and is not the root
                parentNode = self.stackOfNodes.pop()  #get the parent node
                (parentIndex,
                 siblingNode, sibSide) = self.findParentAndSibling(
                     anItem, parentNode)  #get the parent index and the sibling
                totNumKeys = siblingNode.getNumberOfKeys(
                ) + aNode.getNumberOfKeys(
                ) + 1  #find the total number of keys, including the parent item

                tempNode = BTreeNode(2 * n)  #create a temporary BTreeNode

                if sibSide == "right":  #if using the right sibling, copy aNode, then parent, then sibling
                    tempNode.copyItemsAndChildren(aNode, 0,
                                                  aNode.getNumberOfKeys() - 1,
                                                  0)
                    tempNode.getItems()[aNode.getNumberOfKeys(
                    )] = parentNode.getItems()[parentIndex]
                    tempNode.copyItemsAndChildren(
                        siblingNode, 0,
                        siblingNode.getNumberOfKeys() - 1,
                        aNode.getNumberOfKeys() + 1)

                else:  #if using the left sibling, copy the sibling, then parent, then aNode
                    tempNode.copyItemsAndChildren(
                        siblingNode, 0,
                        siblingNode.getNumberOfKeys() - 1, 0)
                    tempNode.getItems()[siblingNode.getNumberOfKeys(
                    )] = parentNode.getItems()[parentIndex]
                    tempNode.copyItemsAndChildren(
                        aNode, 0,
                        aNode.getNumberOfKeys() - 1,
                        siblingNode.getNumberOfKeys() + 1)

                aNode.clear()  #clear the items and children from the two nodes
                siblingNode.clear()

                if totNumKeys > 2 * n:  #case 2a: redistribute
                    sepKey = (totNumKeys +
                              1) // 2  #find the new separating key

                    aNode.copyItemsAndChildren(
                        tempNode, 0, sepKey - 2, 0
                    )  #put the items of the temp node back to where they belong, redistributed
                    parentNode.getItems()[parentIndex] = tempNode.getItems()[
                        sepKey - 1]
                    siblingNode.copyItemsAndChildren(tempNode, sepKey,
                                                     totNumKeys - 1, 0)

                    aNode.setNumberOfKeys(sepKey - 1)
                    siblingNode.setNumberOfKeys(totNumKeys - sepKey)

                else:  #case 2b: merge
                    parentNode.removeItem(
                        parentIndex
                    )  #remove the parent item from the parent node

                    if sibSide == "right":  #remove the child representing the right sibling
                        parentNode.removeChild(parentIndex + 1)
                        if parentNode.getNumberOfKeys(
                        ) == 0:  #if the parent is now empty after the merge, make aNode the root of the tree
                            done = True
                            self.rootNode = aNode
                            self.rootIndex = aNode.getIndex()

                        aNode.copyItemsAndChildren(
                            tempNode, 0, totNumKeys - 1,
                            0)  #merge all the items into aNode
                        aNode.setNumberOfKeys(totNumKeys)

                    else:  #remove the child representing the right sibling (aNode)
                        parentNode.removeChild(parentIndex + 1)
                        if parentNode.getNumberOfKeys(
                        ) == 0:  #if the parent is now empty after the merge, make sibNode the root of the tree
                            done = True
                            self.rootNode = siblingNode
                            self.rootIndex = siblingNode.getIndex()

                        siblingNode.copyItemsAndChildren(
                            tempNode, 0, totNumKeys - 1,
                            0)  #merge all the items into the sibling node
                        siblingNode.setNumberOfKeys(totNumKeys)

                self.writeAt(aNode.getIndex(),
                             aNode)  #write the updates to the file
                self.writeAt(siblingNode.getIndex(), siblingNode)
                self.writeAt(parentNode.getIndex(), parentNode)

                aNode = parentNode  #move up the tree and check if it's ok

        else:  #the item is not in the tree; return None
            return None
Пример #4
0
    def insert(self, anItem):
        ''' Answer None if the BTree already contains a matching
          item. If not, insert a deep copy of anItem and answer
          anItem.
        '''
        searchResult = self.searchTree(anItem)  #search for anItem
        if searchResult[
                'found']:  #if anItem already exists in the tree, return None
            return None

        else:  #if anItem doesn't exist in the tree
            insertNode = self.readFrom(searchResult['fileIndex']
                                       )  #get the node anItem should belong in
            if insertNode.isFull(
            ):  #if the node is full, need to split the node
                toParent = deepcopy(
                    anItem)  #make a deepcopy of the item we want to insert
                leftChild = None  #since inserting into a leaf node, left and right children are None
                rightChild = None

                while insertNode.isFull():
                    splitNode = insertNode.addItemAndSplit(
                        toParent, leftChild, rightChild)  #split the full node
                    splitNode.setIndex(
                        self.freeIndex
                    )  #set the index of the new node to be the next available index
                    self.freeIndex += 1  #increment the free index number

                    toParent = deepcopy(insertNode.getItems()[
                        insertNode.getNumberOfKeys() -
                        1])  #get the item that will go to the parent node
                    insertNode.getItems()[
                        insertNode.getNumberOfKeys() -
                        1] = None  #get rid of the record of the parent item
                    insertNode.getChild()[insertNode.getNumberOfKeys(
                    )] = None  #get rid of the right child of the parent in the insertNode
                    insertNode.setNumberOfKeys(insertNode.getNumberOfKeys() -
                                               1)

                    leftChild = insertNode.getIndex(
                    )  #get the left and right indices of the parent
                    rightChild = splitNode.getIndex()

                    self.writeAt(leftChild,
                                 insertNode)  #write both nodes to the file
                    self.writeAt(rightChild, splitNode)

                    insertNode = self.stackOfNodes.pop()  #get the parent node

                    if insertNode == None:  #if there is no parent, create a new root node
                        insertNode = BTreeNode(self.degree)  #create a new node
                        insertNode.setIndex(
                            self.freeIndex
                        )  #set the index of the new root node
                        self.rootNode = insertNode
                        self.rootIndex = self.freeIndex  #set the root index
                        self.freeIndex += 1  #increment the free index number

                insertNode.insertItem(
                    toParent, leftChild, rightChild
                )  #if the parent node isn't full, just insert the item
                self.writeAt(insertNode.getIndex(),
                             insertNode)  #write the final node to the file

            else:  #there is room for anItem, so just perform an insert
                insertNode.insertItem(deepcopy(anItem))
                self.writeAt(searchResult['fileIndex'],
                             insertNode)  #write the node to the file
            return anItem  #return the item