/* replace old data with new data*/
BTreeReplLogRecord logRec = new BTreeReplLogRecord(page.getPageNumber().getTreeId(), newPageNo, txnId, nodeOffset, oldData, newData, page.btreeSpec.btree.getType());
logRec.log();
} else {
if (page.btreeSpec.btree.getType() == IDBIndex.HYPER_BTREE) {
BTreeAddRemoveLogRecord logRec = new BTreeAddRemoveLogRecord(page.getPageNumber().getTreeId(), newPageNo, txnId, BTreeAddRemoveLogRecord.ADD_FLAG, nodeOffset, newData, page.btreeSpec.btree.getType());
logRec.log();
}
}
}
// add the new node
System.arraycopy(this.getHeader(), 0, page.getPage(), nodeOffset, BTreeSpec.DATA_NODE_HEADER_SIZE);
System.arraycopy(data, 0, page.getPage(), nodeOffset + BTreeSpec.DATA_NODE_HEADER_SIZE, dataSize);
} else {
//=====>>> Build overflow pages
// make it large enough
int freeSpace = page.btreeSpec.getPageSize() - BTreeSpec.PAGE_HEADER_SIZE;
int overflows = data.length / freeSpace + (data.length % freeSpace > 0 ? 1 : 0);
int dataStartPos = 0;
int dataLeft = data.length;
int requireSpace;
int left;
int dataLength = 0;
DataPage last = page;
PageNumber firstOverflowPageNo = null;
for (int i = 0; i < overflows; i++) {
left = dataLeft;
if (left <= 0) break;
requireSpace = (left > freeSpace) ? freeSpace : left;
dataLength = (dataLeft >= freeSpace) ? freeSpace : dataLeft;
DataPage overflowPage = DataPage.newPage(page.btreeSpec, page.buffer, true, kContext, 0);
overflowPage.setLogInfo(txnId, false);
if (needLog) {
int pgno = overflowPage.getPageNumber().getPageNumber();
byte[] oldV = ByteTool.copyByteArray(overflowPage.getPage(), 0, BTreeSpec.PAGE_HEADER_SIZE);
byte[] newV = new byte[oldV.length];
System.arraycopy(oldV, 0, newV, 0, oldV.length);
System.arraycopy(ByteTool.intToBytes(4), 0, newV, BTreeSpec.OFF_FLAGS, 4);
System.arraycopy(ByteTool.shortToBytes((short) (overflowPage.upperBound - requireSpace)), 0, newV, BTreeSpec.OFF_UPPERBOUND, 2);
System.arraycopy(ByteTool.intToBytes(last.pageNumber.getPageNumber(), overflowPage.btreeSpec.getMsbFirst()), 0, newV, BTreeSpec.OFF_PREVPAGE, 4);
if (newV != oldV) {
BTreeReplLogRecord lr = new BTreeReplLogRecord(overflowPage.getPageNumber().getTreeId(), pgno, txnId, 0, oldV, newV, overflowPage.btreeSpec.btree.getType());
lr.log();
}
}
overflowPage.setUpperBound((short) (overflowPage.upperBound - requireSpace));
overflowPage.setPrevPage(last.pageNumber);
overflowPage.setLogInfo(txnId, needLog);
if (i == 0) firstOverflowPageNo = overflowPage.pageNumber;
else last.setNextPage(overflowPage.pageNumber);
//add the new node
if (needLog) {
int newPageNo = overflowPage.getPageNumber().getPageNumber();
byte[] addData = ByteTool.subByteArray(data, dataStartPos, dataLength);
BTreeAddRemoveLogRecord logRec = new BTreeAddRemoveLogRecord(overflowPage.getPageNumber().getTreeId(), newPageNo, txnId, BTreeAddRemoveLogRecord.ADD_FLAG, overflowPage.upperBound, addData, overflowPage.btreeSpec.btree.getType());
logRec.log();
}
// only data left
System.arraycopy(data, dataStartPos, overflowPage.page, overflowPage.upperBound, dataLength);
dataStartPos += dataLength;
dataLeft -= dataLength;