Beispiel #1
0
    /*
     * This stores the node on the disk. If the offset passed is -1 node will be stored at the end of the file.
     * This indicated newly added node.
     */
    int storeNode(TreeNode *node, long long int offset) {
        if (offset == -1) {
            offset = fHandler->getSize();
        }
        Utils::copyBytes(node->myaddr, Utils::getBytesForInt(offset), NODE_OFFSET_SIZE);
        char *block = (char *) malloc(BLOCK_SIZE);
        int position = 0;
        Utils::copyBytes(&block[position], Utils::getBytesForInt(offset),
                         NODE_OFFSET_SIZE);
        position += NODE_OFFSET_SIZE;
        block[position] = node->flag;
        position += 1;
        Utils::copyBytes(&block[position], Utils::getBytesForInt(node->numkeys),
                         sizeof(node->numkeys));
        position += sizeof(node->numkeys);
        Utils::copyBytes(&block[position], (node->data), sizeof(node->data));
        position += sizeof(node->data);
        if(node->nextaddr){
			Utils::copyBytes(&(block[position]), (node->nextaddr), NODE_OFFSET_SIZE);
		}
        else Utils::copyBytes(&(block[position]), Utils::getBytesForInt(-1), NODE_OFFSET_SIZE);
        fHandler->writeBlock(offset, block);
        free(block);
        return 0;
    }
Beispiel #2
0
    /*
	 * This is to handle first addition. First addition needs to update header of the file with nodes address
	 */
    int addFirstElement(byte *key, byte *payload) {
        root = new TreeNode();
        root->numkeys = 0;
        root->flag = 'c';
        root->addData(keytype, key, payloadlen, payload, 0);
        root->numkeys = 1;
        Utils::copyBytes(header, Utils::getBytesForInt((long long int) 1), NODE_OFFSET_SIZE);
        Utils::copyBytes(rootAddress, Utils::getBytesForInt((long long int) 1), NODE_OFFSET_SIZE);
        fHandler->writeBlock(0, header);
        storeNode(root, 1);
        return 0;
    }
Beispiel #3
0
    /*
     * This inserts pointers into node.May result in node split which is also handled.This results in recursive call to add pointers
     * to the parents up the tree till root
     */
    int insertIntoParent(byte left[NODE_OFFSET_SIZE], byte key[],
                         byte right[NODE_OFFSET_SIZE], byte parentOffset[NODE_OFFSET_SIZE],
                         int height, char accessPath[][NODE_OFFSET_SIZE]) {
        if (strncmp(rootAddress, left, NODE_OFFSET_SIZE) == 0) {
            TreeNode *newRoot = new TreeNode();
            newRoot->numkeys = 1;
            newRoot->flag = 'n';
            Utils::copyBytes(newRoot->data, key, keylen(&keytype));
            Utils::copyBytes(&(newRoot->data[DATA_SIZE - NODE_OFFSET_SIZE]),
                             left, NODE_OFFSET_SIZE);
            Utils::copyBytes(&(newRoot->data[DATA_SIZE - NODE_OFFSET_SIZE * 2]),
                             right, NODE_OFFSET_SIZE);
            root = newRoot;
            storeNode(newRoot, -1);
            Utils::copyBytes(rootAddress, root->myaddr, NODE_OFFSET_SIZE);

            byte *block = (byte *) malloc(BLOCK_SIZE);

            fHandler->readBlock(0, block);
            Utils::copyBytes(block, rootAddress, NODE_OFFSET_SIZE);
            fHandler->writeBlock(0, block);
            free(block);
            return 0;
        }

        TreeNode *parent = new TreeNode();
        loadNode(parent, parentOffset);
        int i;
        char nodekey[keylen(&keytype)];
        for (i = 0; i < parent->numkeys; i++) {
            parent->getKey(keytype, nodekey, i);
            int isLesser = compare(nodekey, key, keytype);
            if (isLesser > 0) {
                break;
            }
        }
        if (splitNecessary(parent->numkeys + 1, parent->flag) != 1) {
            parent->addData(keytype, key, NODE_OFFSET_SIZE, right, i);
            parent->numkeys = parent->numkeys + 1;
            storeNode(parent, Utils::getIntForBytes(parent->myaddr));

        } else {
            TreeNode *newNonLeaf = new TreeNode();
            int numPointers = parent->numkeys;
            if (parent->flag != 'c')
                numPointers++;
            int tempSpaceSize = DATA_SIZE + payloadlen + keylen(&keytype);
            char *tempSpace = (char *) calloc(tempSpaceSize, sizeof(char));
            Utils::copyBytes(tempSpace, parent->data,
                             (parent->numkeys) * keylen(&keytype));
            Utils::copyBytes(
                    &tempSpace[tempSpaceSize - (numPointers) * NODE_OFFSET_SIZE],
                    &(parent->data[DATA_SIZE - (numPointers) * NODE_OFFSET_SIZE]),
                    (numPointers) * NODE_OFFSET_SIZE);
            for (int j = parent->numkeys - 1; j >= (i); j--) {
                Utils::copyBytes(&(tempSpace[(j + 1) * keylen(&keytype)]),
                                 &(tempSpace[j * keylen(&keytype)]), keylen(&keytype));
            }
            strncpy(&(tempSpace[(i) * keylen(&keytype)]), key,
                    keylen(&keytype));
            int pointerPosition = i;
            if (parent->flag != 'c')
                pointerPosition++;
            for (int j = (tempSpaceSize - numPointers * NODE_OFFSET_SIZE);
                 j < (tempSpaceSize - pointerPosition * NODE_OFFSET_SIZE);
                 j += NODE_OFFSET_SIZE) {
                Utils::copyBytes(&(tempSpace[j - NODE_OFFSET_SIZE]),
                                 &(tempSpace[j]), NODE_OFFSET_SIZE);
            }
            strncpy(
                    &(tempSpace[tempSpaceSize
                                - (pointerPosition + 1) * NODE_OFFSET_SIZE]), right,
                    NODE_OFFSET_SIZE);

            parent->numkeys = parent->numkeys + 1;
            int n_by_two = (parent->numkeys) / 2;
            int k = 0;
            for (int i = 0; i < n_by_two; i++) {
                Utils::copyBytes(&(parent->data[(i) * keylen(&keytype)]),
                                 &(tempSpace[(i * keylen(&keytype))]), keylen(&keytype));
                Utils::copyBytes(
                        &(parent->data[DATA_SIZE - ((i + 1)) * NODE_OFFSET_SIZE]),
                        &(tempSpace[tempSpaceSize - ((i + 1) * NODE_OFFSET_SIZE)]),
                        NODE_OFFSET_SIZE);
                k = i + 1;
            }
            if (parent->flag != 'c')
                Utils::copyBytes(
                        &(parent->data[DATA_SIZE - ((k + 1)) * NODE_OFFSET_SIZE]),
                        &(tempSpace[tempSpaceSize - ((k + 1) * NODE_OFFSET_SIZE)]),
                        NODE_OFFSET_SIZE);
            for (int i = n_by_two + 1; i < parent->numkeys; i++) {
                Utils::copyBytes(
                        &(newNonLeaf->data[(i - (n_by_two + 1))
                                           * keylen(&keytype)]),
                        &(tempSpace[(i * keylen(&keytype))]), keylen(&keytype));
                Utils::copyBytes(
                        &(newNonLeaf->data[DATA_SIZE
                                           - ((i + 1) - (n_by_two + 1)) * NODE_OFFSET_SIZE]),
                        &(tempSpace[tempSpaceSize - ((i + 1) * NODE_OFFSET_SIZE)]),
                        NODE_OFFSET_SIZE);
                k = i + 1;
            }
            if (parent->flag != 'c')
                Utils::copyBytes(
                        &(newNonLeaf->data[DATA_SIZE
                                           - ((k + 1) - (n_by_two + 1)) * NODE_OFFSET_SIZE]),
                        &(tempSpace[tempSpaceSize - ((k + 1) * NODE_OFFSET_SIZE)]),
                        NODE_OFFSET_SIZE);
            newNonLeaf->flag = 'n';
            newNonLeaf->numkeys = parent->numkeys - n_by_two - 1;
            parent->numkeys = n_by_two;

            TreeNode* grandParent = new TreeNode();
            for (int i = 0; i < height; i++) {
                if (strncmp(accessPath[i], (parent->myaddr), NODE_OFFSET_SIZE)
                    == 0) if (i != 0)
                    loadNode(grandParent, accessPath[i - 1]);
            }

            char nextKey[keylen(&keytype)];

            Utils::copyBytes(nextKey,
                             &(tempSpace[(n_by_two * keylen(&keytype))]),
                             keylen(&keytype));
            storeNode(newNonLeaf, -1);
            storeNode(parent, Utils::getIntForBytes(parent->myaddr));

            char left[NODE_OFFSET_SIZE];
            Utils::copyBytes(left, parent->myaddr, NODE_OFFSET_SIZE);
            char right[NODE_OFFSET_SIZE];
            Utils::copyBytes(right, newNonLeaf->myaddr, NODE_OFFSET_SIZE);
            char parentAdd[NODE_OFFSET_SIZE];
            Utils::copyBytes(parentAdd, grandParent->myaddr, NODE_OFFSET_SIZE);
            if (parent != root)
                delete (parent);
            delete (newNonLeaf);
            delete (grandParent);
            insertIntoParent(left, nextKey, right, parentAdd, height,
                             accessPath);
        }
        return 0;
    }