/* * Constructor to load already existing index */ Index(char* indexName) { fHandler = new FileHandler(indexName, 'o'); header = (char *) malloc(BLOCK_SIZE); fHandler->readBlock(0, header); Utils::copyBytes(rootAddress, header, NODE_OFFSET_SIZE); root = new TreeNode(); loadNode(root, rootAddress); payloadlen = Utils::getIntForBytes(&header[NODE_OFFSET_SIZE]); keytype = Utils::getKeyTypeForBytes( &header[NODE_OFFSET_SIZE + sizeof(payloadlen)]); }
/* * This loads the node.We are using an in memory structure for node.Following function generates the node from the block read. */ int loadNode(TreeNode *here, char *offset) { int position = 0; char *block = (char *) malloc(BLOCK_SIZE); fHandler->readBlock(Utils::getIntForBytes(offset), block); Utils::copyBytes(here->myaddr, offset, NODE_OFFSET_SIZE); position += NODE_OFFSET_SIZE; here->flag = block[position]; position += 1; here->numkeys = Utils::getIntForBytes(&(block[position])); position += sizeof(here->numkeys); Utils::copyBytes(here->data, &(block[position]), sizeof(here->data)); position += sizeof(here->data); //printf("%d %d\n",Utils::getIntForBytes(&block[position]),position); if(Utils::getIntForBytes(&block[position]) != -1){ here->nextaddr = (char *) malloc(NODE_OFFSET_SIZE); Utils::copyBytes(here->nextaddr, &(block[position]), NODE_OFFSET_SIZE); } free(block); 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; }