// The main function that inserts a new key in this B-Tree void BTree::insert(int k) { char varnam[64]; // If tree is empty if (root == NULL) { bzero(varnam, 64); sprintf(varnam,"%d",count); strcat(varnam,"node"); varnam[64]=0; // Allocate memory for root root =(BTreeNode *)nvalloc_(sizeof(BTreeNode), varnam, 0); //root = (BTreeNode *)nvalloc_(sizeof(BTreeNode)); root->Initialize(root, t, true, count); //root = new BTreeNode(t, true); root->keys[0] = k; // Insert key root->n = 1; // Update number of keys in root } else // If tree is not empty { // If root is full, then tree grows in height if (root->n == 2*t-1) { bzero(varnam, 64); sprintf(varnam,"%d",count); strcat(varnam,"node"); varnam[64]=0; // Allocate memory for root BTreeNode *s =(BTreeNode *)nvalloc_(sizeof(BTreeNode), varnam, 0); s->Initialize(s, t, false, count); // Allocate memory for new root //BTreeNode *s = new BTreeNode(t, false); BEGIN_OBJTRANS((void *)s,0); // Make old root as child of new root s->C[0] = root; // Split the old root and move 1 key to the new root s->splitChild(0, root); // New root has two children now. Decide which of the // two children is going to have new key int i = 0; if (s->keys[0] < k) i++; s->C[i]->insertNonFull(k); nvcommitobj((void *)s,0); // Change root root = s; } else // If root is not full, call insertNonFull for root root->insertNonFull(k); } count++; }
// A utility function to split the child y of this node // Note that y must be full when this function is called void BTreeNode::splitChild(int i, BTreeNode *y) { // Create a new node which is going to store (t-1) keys // of y //BTreeNode *z = new BTreeNode(y->t, y->leaf); char varnam[64]; bzero(varnam, 64); sprintf(varnam,"%d",count); strcat(varnam,"node"); varnam[64]=0; // Allocate memory for root BTreeNode *z =(BTreeNode *)nvalloc_(sizeof(BTreeNode), varnam, 0); //root = (BTreeNode *)nvalloc_(sizeof(BTreeNode)); z->Initialize(z, y->t, y->leaf, count); BEGIN_OBJTRANS((void *)z,0); z->n = t - 1; // Copy the last (t-1) keys of y to z for (int j = 0; j < t-1; j++) { BEGIN_WRDTRANS((void *)&z->keys[j],0, sizeof(int)); z->keys[j] = y->keys[j+t]; nvcommitword_((void *)&z->keys[j]); } // Copy the last t children of y to z if (y->leaf == false) { for (int j = 0; j < t; j++) { BEGIN_WRDTRANS((void *)&z->C[j],0, sizeof(BTreeNode *)); z->C[j] = y->C[j+t]; nvcommitword_((void *)&z->C[j]); } } nvcommitobj((void *)z,0); BEGIN_WRDTRANS((void *)&y->n,0, sizeof(int)); // Reduce the number of keys in y y->n = t - 1; nvcommitword_((void *)&y->n); // Since this node is going to have a new child, // create space of new child for (int j = n; j >= i+1; j--) { BEGIN_WRDTRANS((void *)&C[j+1],0, sizeof(BTreeNode *)); C[j+1] = C[j]; nvcommitword_((void *)&C[j+1]); } // Link the new child to this node BEGIN_WRDTRANS((void *)&C[i+1],0, sizeof(BTreeNode *)); C[i+1] = z; nvcommitword_((void *)&C[i+1]); // A key of y will move to this node. Find location of // new key and move all greater keys one space ahead for (int j = n-1; j >= i; j--){ BEGIN_WRDTRANS((void *)&keys[j+1],0, sizeof(int)); keys[j+1] = keys[j]; nvcommitword_((void *)&keys[j+1]); } BEGIN_WRDTRANS((void *)&keys[i],0, sizeof(int)); // Copy the middle key of y to this node keys[i] = y->keys[t-1]; nvcommitword_((void *)&keys[i]); // Increment count of keys in this node n = n + 1; }