// if the page has too few nodes and this is not the root page
} else if (this.prevPage.getPageNumber() != 0 && currNode < order / 2) {
BTreePage parent = new BTreePage(btreeSpec.btree.getBtreeId(), this.prevPage, btreeSpec, buffer);
int nodeSize = btreeSpec.getInternalNodeSize();
Key newKey = null; // V'
BTreePage newPage = null; // L'
// if this is the leftmost child in parent page
// set L' to be the right sibling of the page
if (parent.nextPage.getPageNumber() == this.pageNumber.getPageNumber()) {
// get L' and V'
BTreeNode newNode = parent.getNode(0);
/* Modified by ben zhang at Aug, 12, 2002*/
newKey = newNode.getKey();
newPage = new BTreePage(btreeSpec.btree.getBtreeId(), newNode.getPageNumber(), btreeSpec, buffer);
verifyLR(parent.pageNumber, pageNumber, newPage.pageNumber, true);
// if nodes in L and L' can fit in one page
int size = order;
if (!isLeaf() && isBTree()) size = order - 1;
if (currNode + newPage.getCurrNodeNumbers() <= size) {
if (isLeaf()) {
// append all nodes in L' to L
/********* add by leon *******/
if (needLog) {
int pgno = pageNumber.getPageNumber();
int siblingpgno = newPage.getPageNumber().getPageNumber();
BTreeMergeLogRecord lr = new BTreeMergeLogRecord(pageNumber.getTreeId(), pgno, txnId, false, siblingpgno, page, newPage.getPage(), (short) btreeSpec.getNodeSize(), btreeSpec.btree.getType());
lr.log();
}
/***************************/
for (int j = 0; j < newPage.getCurrNodeNumbers(); j++) {
upperBound -= nodeSize;
System.arraycopy(newPage.page, newPage.getNodeOffset(j), page, upperBound, nodeSize);
System.arraycopy(ByteTool.shortToBytes(upperBound), 0, page, lowerBound, 2);
lowerBound += 2;
}
setLowerBound(lowerBound);
setUpperBound(upperBound);
// set L.nextPage = L'.nextPage
setNextPage(newPage.nextPage);
// unfix this page L
buffer.releasePage(pageNumber.getTreeId(), pageNumber, true);
} else if (isBTree()) {
// append V' and leftmost pointer in L' to L
insertNode(newKey, ByteTool.intToBytes(newPage.nextPage.getPageNumber()), IDBIndex.STORE_REPLACE, kContext);
currNode = this.getCurrNodeNumbers();
// set newpage's child page's parent to this page
BTreePage childPage = new BTreePage(btreeSpec.btree.getBtreeId(), newPage.nextPage, btreeSpec, buffer);
/********* add by leon *******/
childPage.setLogInfo(txnId, needLog);
/***************************/
childPage.setPrevPage(pageNumber);
// unfix child page
buffer.releasePage(childPage.pageNumber.getTreeId(), childPage.pageNumber, true);
// fix this page
/********* add by leon *******/
if (needLog) {
int pgno = pageNumber.getPageNumber();
int siblingpgno = newPage.getPageNumber().getPageNumber();
BTreeMergeLogRecord lr = new BTreeMergeLogRecord(pageNumber.getTreeId(), pgno, txnId, false, siblingpgno, page, newPage.getPage(), (short) btreeSpec.getNodeSize(), btreeSpec.btree.getType());
lr.log();
}
/***************************/
// append all nodes in L' to L
for (int j = 0; j < newPage.getCurrNodeNumbers(); j++) {
upperBound -= nodeSize;
BTreeNode node = newPage.getNode(j);
// set newpage's child page's parent to this page
childPage = new BTreePage(btreeSpec.btree.getBtreeId(), node.getPageNumber(), btreeSpec, buffer);
/********* add by leon *******/
childPage.setLogInfo(txnId, needLog);
/***************************/
childPage.setPrevPage(pageNumber);
// unfix child page
buffer.releasePage(childPage.pageNumber.getTreeId(), childPage.pageNumber, true);
System.arraycopy(newPage.page, node.getNodeOffset(), page, upperBound, nodeSize);
System.arraycopy(ByteTool.shortToBytes(upperBound), 0, page, lowerBound, 2);
lowerBound += 2;
}
setLowerBound(lowerBound);
setUpperBound(upperBound);
// unfix this page
buffer.releasePage(pageNumber.getTreeId(), pageNumber, true);
}
if (Debug.DEBUG_BTREEPAGE) {
logger.debug("L: " + this.toString());
logger.debug("L': " + newPage.toString());
}
// delete L'
/******************* Add by Leon, Sep 30 *****************/
if (needLog) {
int pgno = newPage.pageNumber.getPageNumber();
int prevPg = newPage.prevPage.getPageNumber();
int nextPg = newPage.nextPage.getPageNumber();
BTreeFreePageLogRecord lr = new BTreeFreePageLogRecord(pageNumber.getTreeId(), pgno, txnId, newPage.flags, prevPg, nextPg, newPage.keyType, -1, btreeSpec.btree.getType());
lr.log();
}
/***************************/
buffer.addToFreeList(btreeSpec.btree.getBtreeId(), newPage.pageNumber, needLog ? new Integer(txnId) : null);
// recursive delete
result = parent.delete(newKey, kContext);
} else {
// redistribution: borrow one node from L' and insert to L rightmost
if (isLeaf()) {
BTreeNode firstNode = newPage.getNode(0);
int firstNodeOffset = firstNode.getNodeOffset();
// insert the new node to L rightmost
/***************** Add by leon,2001-9-27 14:56 ********************/
if (needLog) {
int pgno = pageNumber.getPageNumber();
byte[] oldV = ByteTool.shortToBytes(lowerBound);
oldV = ByteTool.append(oldV, ByteTool.shortToBytes(upperBound));
byte[] newV = ByteTool.shortToBytes((short) (lowerBound + 2));
newV = ByteTool.append(newV, ByteTool.shortToBytes((short) (upperBound - nodeSize)));
if (oldV != newV) {
BTreeReplLogRecord lr = new BTreeReplLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeSpec.OFF_LOWERBOUND, oldV, newV, btreeSpec.btree.getType());
lr.log();
}
}
/******************************************************************/
short oldLB = lowerBound;
setUpperBound((short) (upperBound - nodeSize));
setLowerBound((short) (lowerBound + 2));
/***************** Add by leon,2001-9-27 14:56 ********************/
if (needLog) {
int pgno = pageNumber.getPageNumber();
byte[] node = ByteTool.copyByteArray(newPage.page, firstNodeOffset, nodeSize);
BTreeAddRemoveLogRecord lr = new BTreeAddRemoveLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeAddRemoveLogRecord.ADD_FLAG, upperBound, node, btreeSpec.btree.getType());
lr.log();
}
/******************************************************************/
System.arraycopy(newPage.page, firstNodeOffset, page, upperBound, nodeSize);
/***************** Add by leon,2001-9-27 14:56 ********************/
if (needLog) {
int pgno = pageNumber.getPageNumber();
BTreeAddRemoveLogRecord lr = new BTreeAddRemoveLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeAddRemoveLogRecord.ADD_FLAG, oldLB, ByteTool.shortToBytes(upperBound), btreeSpec.btree.getType());
lr.log();
}
/******************************************************************/
System.arraycopy(ByteTool.shortToBytes(upperBound), 0, page, oldLB, 2);
// remove the first node from L'
/******************* Add by Leon, Sep 29 *****************/
int pgno = newPage.pageNumber.getPageNumber();
if (needLog) {
//remember the dead node
byte[] data = ByteTool.copyByteArray(newPage.page, firstNodeOffset, nodeSize);
BTreeAddRemoveLogRecord lr = new BTreeAddRemoveLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeAddRemoveLogRecord.REMOVE_FLAG, firstNodeOffset, data, btreeSpec.btree.getType());
lr.log();
//here we dont remember the offset of this node, for later move offset talbe will
//log it, which is different from borrowing the last node from left sibling.
}
if (firstNodeOffset != newPage.upperBound) {
if (needLog) {
byte[] data = ByteTool.copyByteArray(newPage.page, newPage.upperBound, nodeSize);
BTreeMoveLogRecord lr1 = new BTreeMoveLogRecord(pageNumber.getTreeId(), pgno, txnId, newPage.upperBound, firstNodeOffset, data.length, data, btreeSpec.btree.getType());
lr1.log();
}
/***************************/
System.arraycopy(newPage.page, newPage.upperBound, newPage.page, firstNodeOffset, nodeSize);
// find the key has upperBound
int upperBoundNodeIndex = -1;
// some better algorithm later ###
for (int j = 0; j < newPage.getCurrNodeNumbers(); j++) {
if (newPage.getNodeOffset(j) == newPage
.upperBound) {
upperBoundNodeIndex = j;
break;
}
}
if (upperBoundNodeIndex >= 0) {
/***************** Add by leon,2001-9-27 14:56 ********************/
if (needLog) {
byte[] oldV = ByteTool.copyByteArray(newPage.page, BTreeSpec
.PAGE_HEADER_SIZE + 2 * upperBoundNodeIndex, 2);
byte[] newV = ByteTool.shortToBytes((short) firstNodeOffset);
if (oldV != newV) {
BTreeReplLogRecord lr = new BTreeReplLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeSpec
.PAGE_HEADER_SIZE + 2 * upperBoundNodeIndex, oldV, newV, btreeSpec.btree.getType());
lr.log();
}
}
/******************************************************************/
System.arraycopy(ByteTool.shortToBytes((short) firstNodeOffset), 0, newPage.page, BTreeSpec
.PAGE_HEADER_SIZE + 2 * upperBoundNodeIndex, 2);
}
}
// rest clean up, upperBound, lowerBound
oldLB = newPage.lowerBound;
/***************** Add by leon,2001-9-27 14:56 ********************/
if (needLog) {
byte[] oldV = ByteTool.shortToBytes(newPage.lowerBound);
oldV = ByteTool.append(oldV, ByteTool.shortToBytes(newPage.upperBound));
byte[] newV = ByteTool.shortToBytes((short) (newPage.lowerBound - 2));
newV = ByteTool.append(newV, ByteTool.shortToBytes((short) (newPage
.upperBound + nodeSize)));
BTreeReplLogRecord lr = new BTreeReplLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeSpec.OFF_LOWERBOUND, oldV, newV, btreeSpec.btree.getType());
lr.log();
}
/******************************************************************/
newPage.setUpperBound((short) (newPage.upperBound + nodeSize));
newPage.setLowerBound((short) (newPage.lowerBound - 2));
// move all pointers one slot up
/******************* Add by Leon, Sep 29 *****************/
if (needLog) {
byte[] data = ByteTool.copyByteArray(newPage.page, BTreeSpec.PAGE_HEADER_SIZE, 2);
BTreeAddRemoveLogRecord lr = new BTreeAddRemoveLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeAddRemoveLogRecord.REMOVE_FLAG, BTreeSpec.PAGE_HEADER_SIZE, data, btreeSpec.btree.getType());
lr.log();
data = ByteTool.copyByteArray(newPage.page, BTreeSpec.PAGE_HEADER_SIZE + 2, oldLB - BTreeSpec.PAGE_HEADER_SIZE - 2);
BTreeMoveLogRecord lr1 = new BTreeMoveLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeSpec.PAGE_HEADER_SIZE + 2, BTreeSpec.PAGE_HEADER_SIZE, data.length, data, btreeSpec.btree.getType());
lr1.log();
}
/***************************/
System.arraycopy(newPage.page, BTreeSpec.PAGE_HEADER_SIZE + 2, newPage.page, BTreeSpec.PAGE_HEADER_SIZE, oldLB - BTreeSpec.PAGE_HEADER_SIZE - 2);
// replace V' in parent by firstNode's key
BTreeNode newFirstNode = newPage.getNode(0);
newNode.internalReplaceKey(newFirstNode.getKey().toBytes(), kContext);
} else if (isBTree()) {
PageNumber leftmostPageNumber = new PageNumber(newPage.nextPage);
BTreeNode firstNode = newPage.getNode(0);
PageNumber firstNodePageNumber = firstNode.getPageNumber();
/*Modified by ben zhang at Aug, 12, 2002 */
Key firstNodeKey = firstNode.getKey();
// remove the first node from L', already unfix page
/********* add by leon *******/
newPage.setLogInfo(txnId, needLog);
/***************************/
newPage.setNextPage(firstNodePageNumber);
newPage.deleteNode(firstNodeKey, kContext);
// insert V' and leftmostPageNumber to the rightmost of L
// already unfix page
insertNode(newKey, ByteTool.intToBytes(leftmostPageNumber.getPageNumber()), IDBIndex.STORE_REPLACE, kContext);
// set newpage's child page's parent to this page
BTreePage childPage = new BTreePage(btreeSpec.btree.getBtreeId(), leftmostPageNumber, btreeSpec, buffer);
/********* add by leon *******/
childPage.setLogInfo(txnId, needLog);
/***************************/
childPage.setPrevPage(pageNumber);
// unfix child page
buffer.releasePage(childPage.pageNumber.getTreeId(), childPage.pageNumber, true);
// replace V' in parent by firstNode's key
newNode.internalReplaceKey(firstNodeKey.toBytes(), kContext);
}
// unfix and unlock this page and its sibling
buffer.releasePage(pageNumber.getTreeId(), pageNumber, true);
buffer.releasePage(newPage.pageNumber.getTreeId(), newPage.pageNumber, true);
result = new OperResult(true, null);
}
// otherwise let L' be the left sibling (predecessor) of this page L
} else {
// get L' and V'
int prevIndex = parent.nextPage.getPageNumber();
BTreeNode newNode = null;
// int newNodeLocation = 0;
for (int i = 0; i < parent.getCurrNodeNumbers(); i++) {
BTreeNode node = parent.getNode(i);
if (node.getPageNumber().getPageNumber() == this.pageNumber.getPageNumber()) {
/* Modified by ben at Aug, 12, 2002 */
newKey = node.getKey();
newNode = node;
// newNodeLocation = i;
break;
}
prevIndex = node.getPageNumber().getPageNumber();
}
tmpPgNo = new PageNumber(prevIndex);
tmpPgNo.setTreeId(btreeSpec.btree.getBtreeId());
newPage = new BTreePage(btreeSpec.btree.getBtreeId(), tmpPgNo, btreeSpec, buffer);
verifyLR(parent.pageNumber, newPage.pageNumber, pageNumber, false);
if (Debug.DEBUG_BTREEPAGE)
logger.debug("L'= " + newPage.pageNumber.getPageNumber() + " V'=" + new String(newKey.toBytes())); //Modified by ben at Aug, 12, 2002. Pending issue
// if nodes in L and L' can fit in one page
int size = order;
if (!isLeaf() && isBTree()) size = order - 1;
if (currNode + newPage.getCurrNodeNumbers() <= size) {
if (isLeaf()) {
/********* add by leon *******/
if (needLog) {
int pgno = pageNumber.getPageNumber();
int siblingpgno = newPage.getPageNumber().getPageNumber();
BTreeMergeLogRecord lr = new BTreeMergeLogRecord(pageNumber.getTreeId(), pgno, txnId, true, siblingpgno, page, newPage.getPage(), (short) btreeSpec.getNodeSize(), btreeSpec.btree.getType());
lr.log();
}
/***************************/
// append all nodes in L to L'
for (int j = 0; j < currNode; j++) {
newPage.upperBound -= nodeSize;
System.arraycopy(page, getNodeOffset(j), newPage.page, newPage.upperBound, nodeSize);
System.arraycopy(ByteTool.shortToBytes(newPage.upperBound), 0, newPage.page, newPage.lowerBound, 2);
newPage.lowerBound += 2;
}
newPage.setLowerBound(newPage.lowerBound);
newPage.setUpperBound(newPage.upperBound);
// set L'.nextPage = L.nextPage
/********* add by leon *******/
newPage.setLogInfo(txnId, needLog);
/***************************/
newPage.setNextPage(this.nextPage);
// unfix new page
buffer.releasePage(newPage.pageNumber.getTreeId(), newPage.pageNumber, true);
} else if (isBTree()) {
// append V' and leftmost pointer in L to L'
newPage.insertNode(newKey, ByteTool.intToBytes(this.nextPage.getPageNumber()), IDBIndex.STORE_REPLACE, kContext);
// set child page's parent to newPage
BTreePage childPage = new BTreePage(btreeSpec.btree.getBtreeId(), this.nextPage, btreeSpec, buffer);
/********* add by leon *******/
childPage.setLogInfo(txnId, needLog);
/***************************/
childPage.setPrevPage(newPage.pageNumber);
// unfix child page
buffer.releasePage(childPage.pageNumber.getTreeId(), childPage.pageNumber, true);
// fix new page
//newPage.page = buffer.getPage(btreeSpec.btree.getBtreeId(),newPage.pageNumber);
/********* add by leon *******/
if (needLog) {
int pgno = pageNumber.getPageNumber();
int siblingpgno = newPage.getPageNumber().getPageNumber();
BTreeMergeLogRecord lr = new BTreeMergeLogRecord(pageNumber.getTreeId(), pgno, txnId, true, siblingpgno, page, newPage.getPage(), (short) btreeSpec.getNodeSize(), btreeSpec.btree.getType());
lr.log();
}
/***************************/
// append all nodes in L to L'
for (int j = 0; j < currNode; j++) {
newPage.upperBound -= nodeSize;
BTreeNode node = getNode(j);
// set child page's parent to new page
childPage = new BTreePage(btreeSpec.btree.getBtreeId(), node.getPageNumber(), btreeSpec, buffer);
/********* add by leon *******/
childPage.setLogInfo(txnId, needLog);
/***************************/
childPage.setPrevPage(newPage.pageNumber);
// unfix child page
buffer.releasePage(childPage.pageNumber.getTreeId(), childPage.pageNumber, true);
System.arraycopy(page, getNodeOffset(j), newPage.page, newPage.upperBound, nodeSize);
System.arraycopy(ByteTool.shortToBytes(newPage.upperBound), 0, newPage.page, newPage.lowerBound, 2);
newPage.lowerBound += 2;
}
newPage.setLowerBound(newPage.lowerBound);
newPage.setUpperBound(newPage.upperBound);
// unfix new page
buffer.releasePage(newPage.pageNumber.getTreeId(), newPage.pageNumber, true);
}
if (Debug.DEBUG_BTREEPAGE) {
logger.debug("L: " + this.toString());
logger.debug("L': " + newPage.toString());
}
// delete L
/******************* Add by Leon, Sep 30 *****************/
if (needLog) {
int pgno = pageNumber.getPageNumber();
int prevPg = prevPage.getPageNumber();
int nextPg = nextPage.getPageNumber();
BTreeFreePageLogRecord lr = new BTreeFreePageLogRecord(pageNumber.getTreeId(), pgno, txnId, flags, prevPg, nextPg, keyType, -1, btreeSpec.btree.getType());
lr.log();
}
/***************************/
buffer.addToFreeList(btreeSpec.btree.getBtreeId(), this.pageNumber, needLog ? new Integer(txnId) : null);
// delete node from parent
result = parent.delete(newKey, kContext);
} else {
// redistribution: borrow and node from L' and insert to L leftmost
if (isLeaf()) {
BTreeNode lastNode = newPage.getNode(newPage.getCurrNodeNumbers() - 1);
byte[] lastNodeKey = lastNode.getKey().toBytes();
int lastNodeOffset = lastNode.getNodeOffset();
// insert to the new node to L leftmost
/***************** Add by leon,2001-9-27 14:56 ********************/
if (needLog) {
int pgno = pageNumber.getPageNumber();
byte[] oldV = ByteTool.shortToBytes(lowerBound);
oldV = ByteTool.append(oldV, ByteTool.shortToBytes(upperBound));
byte[] newV = ByteTool.shortToBytes((short) (lowerBound + 2));
newV = ByteTool.append(newV, ByteTool.shortToBytes((short) (upperBound - nodeSize)));
BTreeReplLogRecord lr = new BTreeReplLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeSpec.OFF_LOWERBOUND, oldV, newV, btreeSpec.btree.getType());
lr.log();
}
/******************************************************************/
setLowerBound((short) (lowerBound + 2));
setUpperBound((short) (upperBound - nodeSize));
/***************** Add by leon,2001-9-27 14:56 ********************/
if (needLog) {
int pgno = pageNumber.getPageNumber();
byte[] node = ByteTool.copyByteArray(newPage.page, lastNodeOffset, nodeSize);
BTreeAddRemoveLogRecord lr = new BTreeAddRemoveLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeAddRemoveLogRecord.ADD_FLAG, upperBound, node, btreeSpec.btree.getType());
lr.log();
}
/******************************************************************/
System.arraycopy(newPage.page, lastNodeOffset, page, upperBound, nodeSize);
/******************* Add by Leon, Sep 29 *****************/
if (needLog) {
int pgno = pageNumber.getPageNumber();
byte[] oldV = ByteTool.copyByteArray(page, BTreeSpec.PAGE_HEADER_SIZE, 2 * currNode);
byte[] newV = ByteTool.shortToBytes(upperBound);
newV = ByteTool.append(newV, oldV);
BTreeReplLogRecord lr = new BTreeReplLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeSpec.PAGE_HEADER_SIZE, oldV, newV, btreeSpec.btree.getType());
lr.log();
}
/***************************/
System.arraycopy(page, BTreeSpec.PAGE_HEADER_SIZE, page, BTreeSpec.PAGE_HEADER_SIZE + 2, 2 * currNode);
System.arraycopy(ByteTool.shortToBytes(upperBound), 0, page, BTreeSpec.PAGE_HEADER_SIZE, 2);
// remove the last node from L'
/******************* Add by Leon, Sep 29 *****************/
int pgno = newPage.pageNumber.getPageNumber();
if (needLog) {
//remember the dead node.
byte[] data = ByteTool.copyByteArray(newPage.page, lastNodeOffset, nodeSize);
BTreeAddRemoveLogRecord lr = new BTreeAddRemoveLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeAddRemoveLogRecord.REMOVE_FLAG, lastNodeOffset, data, btreeSpec.btree.getType());
lr.log();
data = ByteTool.copyByteArray(newPage.page, newPage.lowerBound - 2, 2);
lr = new BTreeAddRemoveLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeAddRemoveLogRecord.REMOVE_FLAG, newPage.lowerBound - 2, data, btreeSpec.btree.getType());
lr.log();
}
if (lastNodeOffset != newPage.upperBound) {
if (needLog) {
byte[] data = ByteTool.copyByteArray(newPage.page, newPage.upperBound, nodeSize);
BTreeMoveLogRecord lr1 = new BTreeMoveLogRecord(pageNumber.getTreeId(), pgno, txnId, newPage.upperBound, lastNodeOffset, data.length, data, btreeSpec.btree.getType());
lr1.log();
}
/***************************/
System.arraycopy(newPage.page, newPage.upperBound, newPage.page, lastNodeOffset, nodeSize);
// find the key has upperBound
int upperBoundNodeIndex = -1;
// some better algorithm later ###
for (int j = 0; j < newPage.getCurrNodeNumbers(); j++) {
if (newPage.getNodeOffset(j) == newPage
.upperBound) {
upperBoundNodeIndex = j;
break;
}
}
if (upperBoundNodeIndex >= 0) {
/****** Add by leon,2001-9-27 14:56 ******/
if (needLog) {
byte[] oldV = ByteTool.copyByteArray(newPage.page, BTreeSpec
.PAGE_HEADER_SIZE + 2 * upperBoundNodeIndex, 2);
byte[] newV = ByteTool.shortToBytes((short) lastNodeOffset);
BTreeReplLogRecord lr = new BTreeReplLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeSpec
.PAGE_HEADER_SIZE + 2 * upperBoundNodeIndex, oldV, newV, btreeSpec.btree.getType());
lr.log();
}
/******************************************************************/
System.arraycopy(ByteTool.shortToBytes((short) lastNodeOffset), 0, newPage.page, BTreeSpec
.PAGE_HEADER_SIZE + 2 * upperBoundNodeIndex, 2);
}
}
// rest clean up, upperBound, lowerBound
/******************* Add by Leon, Sep 29 *****************/
if (needLog) {
byte[] oldV = ByteTool.copyByteArray(newPage.page, BTreeSpec.OFF_LOWERBOUND, 4);
byte[] newV = ByteTool.shortToBytes((short) (newPage.lowerBound - 2));
newV = ByteTool.append(newV, ByteTool.shortToBytes((short) (newPage
.upperBound + nodeSize)));
BTreeReplLogRecord lr = new BTreeReplLogRecord(pageNumber.getTreeId(), pgno, txnId, BTreeSpec.OFF_LOWERBOUND, oldV, newV, btreeSpec.btree.getType());
lr.log();
}
/***************************/
newPage.setUpperBound((short) (newPage.upperBound + nodeSize));
newPage.setLowerBound((short) (newPage.lowerBound - 2));
if (newPage.getCurrNodeNumbers() == 0) {
/******************* Add by Leon, Sep 30 *****************/
if (needLog) {
int prevPg = newPage.prevPage.getPageNumber();
int nextPg = newPage.nextPage.getPageNumber();
BTreeFreePageLogRecord lr = new BTreeFreePageLogRecord(pageNumber.getTreeId(), pgno, txnId, newPage.flags, prevPg, nextPg, newPage.keyType, -1, btreeSpec.btree.getType());
lr.log();
}
/***************************/
buffer.addToFreeList(btreeSpec.btree.getBtreeId(), newPage.pageNumber, needLog ? new Integer(txnId) : null);
}
// replace V' in parent by lastNode's key
newNode.internalReplaceKey(lastNodeKey, kContext);
} else if (isBTree()) {
BTreeNode lastNode = newPage.getNode(newPage.getCurrNodeNumbers() - 1);
PageNumber lastNodePageNumber = lastNode.getPageNumber();
/* Modified by ben zhang at Aug, 12, 2002 */
Key lastNodeKey = lastNode.getKey();
// set child page's parent to this page
BTreePage childPage = new BTreePage(btreeSpec.btree.getBtreeId(), lastNodePageNumber, btreeSpec, buffer);
/********* add by leon *******/
childPage.setLogInfo(txnId, needLog);
/***************************/
childPage.setPrevPage(pageNumber);
// unfix child page
buffer.releasePage(childPage.pageNumber.getTreeId(), childPage.pageNumber, true);
PageNumber oldNextPage = new PageNumber(nextPage);
setNextPage(lastNodePageNumber);
// insert lastNodePageNumber and V' to L; already unfix page
insertNode(newKey, ByteTool.intToBytes(oldNextPage.getPageNumber()), IDBIndex.STORE_REPLACE, kContext);
// remove the last node from L'; already unfix page
newPage.deleteNode(lastNodeKey, kContext);
// replace V' in parent by lastNode's key
newNode.internalReplaceKey(lastNodeKey.toBytes(), kContext);
}
// unfix this page and new page
buffer.releasePage(pageNumber.getTreeId(), pageNumber, true);