int addToLeafNoSplit(byte *key, byte *payload, int position, TreeNode **rcvd_node) { TreeNode *node = *rcvd_node; node->addData(keytype, key, payloadlen, payload, position); node->numkeys = node->numkeys + 1; storeNode(node, Utils::getIntForBytes(node->myaddr)); *rcvd_node = 0; return 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; }
/* * 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; }