Beispiel #1
0
///////////////////////////////////////////////////////////////////////////////////////////////////
//--
void BPTree::insert_entry(_F_FileAddr L, pKey_Attr pPrimKey, _F_FileAddr pRec) {
	BPTreeNode NodeL;
	NodeL.readNodeFromFile(L);
	//if L has less than n-1 key values
	if(NodeL.ItemOnNode < NodeL.MaxItem) {
		if(NodeL.IsLeaf ==1)
			NodeL.insertKeyInLeaf(pRec, pPrimKey);
		else
			NodeL.insertKeyNotLeaf(pPrimKey, pRec);
	}
	else {
		//create a new node
		_F_FileAddr L_ = createNodeInFile();
		BPTreeNode NodeL_;
		pKey_Attr pPrimKey_;
		int n = NodeL.MaxItem + 1;

		if(NodeL.IsLeaf ==1) {
			NodeL_.IsLeaf = 1;
			int m;
			if( !(n%2) )
				m = n/2 ;
			else 
				m = n/2 + 1;
			//p[0]k[0]...k[m-1]p[m] | k[m]...
			// pPrimKey < k[m-1]
			if( NodeL.compare(NodeL.k[m-1], pPrimKey) > 0) { 
				m--;                                  
				pPrimKey_ = NodeL.createKey(NodeL.k[m]);
			}
			// k[m] > pPrimKey >= k[m-1]
			else if( (m == n - 1) || ( NodeL.compare(NodeL.k[m], pPrimKey) > 0 ) ) 
				pPrimKey_ = NodeL.createKey(pPrimKey);
			else
				// pPrimKey > k[m]
				pPrimKey_ = NodeL.createKey(NodeL.k[m]);
			//copy p[m]....to L_
			for(int i=m; i<NodeL.MaxItem; i++) {
				NodeL_.p[i-m] = NodeL.p[i];
				NodeL_.k[i-m] = NodeL.k[i];
				//erase
				NodeL.k[i] = NULL;
				NodeL.p[i].ulFilePageID = 0;
				NodeL.p[i].uiOffset     = 0;
				NodeL_.ItemOnNode++;
				NodeL.ItemOnNode--;
			}
			if(NodeL.compare(pPrimKey, pPrimKey_) < 0)
				NodeL.insertKeyInLeaf(pRec,pPrimKey);
			else
				NodeL_.insertKeyInLeaf(pRec,pPrimKey);
		}
		else { //NodeL is not a leaf
			NodeL_.IsLeaf = 0;
			int m;
			if( !(n%2) )
				m = n/2 ;
			else 
				m = n/2 + 1;
			m = NodeL.MaxItem - m;
			//p[0],k[0]....k[m]p[m+1] | k[m+1]...
			//pPrimKey > k[m+1]
			if( NodeL.compare(pPrimKey, NodeL.k[m+1]) > 0 ) {
				m++;
				pPrimKey_ = NodeL.createKey(NodeL.k[m]);
			}
			// k[m] < pPrimKey <= k[m+1]
			else if( NodeL.compare(pPrimKey, NodeL.k[m]) > 0 ) {
				m++;
				pPrimKey_ = NodeL.createKey(pPrimKey);
			}
			// pPrimKey <= k[m]
			else {
				pPrimKey_ = NodeL.createKey(NodeL.k[m]);
			}
			// move and delete
			NodeL_.p[0].ulFilePageID = 0;
			NodeL_.p[0].uiOffset     = 0;  
			NodeL_.k[0] = NodeL.k[m];
			NodeL.k[m] = NULL;
			NodeL_.ItemOnNode++;
			NodeL.ItemOnNode--;
			for(int i=m+1; i<NodeL.MaxItem; i++) {
				NodeL_.p[i-m] = NodeL.p[i];
				NodeL_.k[i-m] = NodeL.k[i];
				//erase
				NodeL.k[i] = NULL;
				NodeL.p[i].ulFilePageID = 0;
				NodeL.p[i].uiOffset     = 0;
				NodeL_.ItemOnNode++;
				NodeL.ItemOnNode--;
			}
			NodeL_.p[i-m] = NodeL.p[i];
			NodeL.p[i].ulFilePageID = 0;
			NodeL.p[i].uiOffset     = 0;
			if( NodeL.compare(pPrimKey, pPrimKey_) < 0 )
				NodeL.insertKeyNotLeaf(pPrimKey, pRec);
			else 
				NodeL_.insertKeyNotLeaf(pPrimKey,pRec);
			NodeL_.deleteFirstKey();
		}
		if( !isRoot(L) )
			insert_entry(getParent(L), pPrimKey_, L_);
		else
			createNewRoot(L, pPrimKey_, L_);  
		if(NodeL.IsLeaf == 1) {
			NodeL_.p[NodeL.MaxItem] = NodeL.p[NodeL.MaxItem];
			NodeL.p[NodeL.MaxItem]  = L_;
		}
		NodeL_.writeNodeToFile(L_);
	}
	NodeL.writeNodeToFile(L);
}
Beispiel #2
0
bool BTree<K, Comp>::insert(K key, uint64_t tid) {
  //latch the root
  BufferFrame* curFrame = &bufferManager.fixPage(rootPID, true);
  Node<K, Comp>* curNode = reinterpret_cast<Node<K, Comp>*>(curFrame->getData());
  BufferFrame* parFrame = NULL;
  while (!curNode->isLeaf()) {
    if (curNode->count >= maxNodeSize) {
      // --> split to safe inner pages
      if (parFrame == NULL) {
        //Need to create a new root (parent) first
        parFrame = createNewRoot();
      }
      BufferFrame* newFrame = &bufferManager.fixPage(nextFreePage++, true);
      K splitKey = curNode->split(curFrame->pageId, newFrame, parFrame, smaller);

      //determine correct node and release the other one
      if (smaller(key, splitKey)) {
        bufferManager.unfixPage(*newFrame, true);
      } else {
        curNode = reinterpret_cast<Node<K, Comp>*>(newFrame->getData());
        bufferManager.unfixPage(*curFrame, true);
        curFrame = newFrame;
      }
    }

    //release the parent node
    if (parFrame != NULL) {
      bufferManager.unfixPage(*parFrame, true); //TODO only set true when parent is really dirty?
    }
    parFrame = curFrame;

    //latch the next level
    uint64_t pos = curNode->findKeyPos(key, smaller);
    uint64_t nextPID =
        (pos == curNode->count) ?
            curNode->next : curNode->keyValuePairs[pos].second;
    curFrame = &bufferManager.fixPage(nextPID, true);
    curNode = reinterpret_cast<Node<K, Comp>*>(curFrame->getData());
  }

  Node<K, Comp>* leaf = reinterpret_cast<Node<K, Comp>*>(curNode);
  if (leaf->count >= maxNodeSize) {
    if (parFrame == NULL) {
      parFrame = createNewRoot();
    }

    BufferFrame* newFrame = &bufferManager.fixPage(nextFreePage++, true);
    K splitKey = leaf->split(curFrame->pageId, newFrame, parFrame, smaller);
    if (smaller(key, splitKey)) {
      bufferManager.unfixPage(*newFrame, true);
    } else {
      leaf = reinterpret_cast<Node<K, Comp>*>(newFrame->getData());
      bufferManager.unfixPage(*curFrame, true);
      curFrame = newFrame;
    }
  }
  if (parFrame != NULL) {
    bufferManager.unfixPage(*parFrame, true); //TODO: only mark dirty when parent was actually updated
  }

  bool insertSuccessful = leaf->insertKey(key, tid, smaller);
  if (insertSuccessful) {
    elements++;
  }
  bufferManager.unfixPage(*curFrame, true);
  return insertSuccessful;
}