package com.neocoretechs.bigsack.btree;
import java.io.IOException;
import com.neocoretechs.bigsack.io.pooled.ObjectDBIO;
/**
* Request sent to NodeSplitThread operating on parent nodes. If another NodeSplitThread
* request is also in progress with the same data and sharing, a synchronization lock on the former parent node is needed.
* A CyclicBarrier with node split participants as waiters is used to determine a barrier synchronization point.
* This barrier is set up in the main calling thread and awaited in the node split processors
* @author jg Copyright (c) NeoCoreTechs 2015
*
*/
public final class NodeSplitRequest extends AbstractNodeSplitRequest {
private static boolean DEBUG = false;
BTreeKeyPage newNode = null;
static enum NODETYPE {NODE_LEFT,NODE_RIGHT};
// from rootOffs to MAXKEYS is range of keys to extract
private static int rootOffs = BTreeKeyPage.MAXKEYS - keysToMove; // the place in root to start pulling keys
private int nodeOffs;
public NodeSplitRequest(ObjectDBIO globalIO, BTreeKeyPage targetPage, NODETYPE ntype) {
this.globalIO = globalIO;
this.oldRoot = targetPage;
switch(ntype) {
case NODE_LEFT:
nodeOffs = 0;
break;
case NODE_RIGHT:
nodeOffs = rootOffs;
}
}
/**
* Attempt insert, we may not have it on this node. A slit is always assumed necessary if we get here.
*/
@Override
public void process() throws IOException {
// get the new page
newNode = BTreeKeyPage.getPageFromPool(globalIO);
// pull everything from the right nodes and move it down
synchronized(oldRoot) {
//
for(int i = 0; i < keysToMove; i++) {
BTreeMain.moveKeyData(oldRoot, nodeOffs+i, newNode, i, true);
BTreeMain.moveChildData(oldRoot, nodeOffs+i, newNode, i, true);
}
//
newNode.numKeys = keysToMove;
// See if leaf node, simply, no pointers out
newNode.mIsLeafNode = true;
for( int i = 0; i < newNode.numKeys; i++) {
if( newNode.pageIdArray[i] != -1L ) {
newNode.mIsLeafNode = false;
break;
}
}
newNode.setUpdated(true);
// set our new left/right pointers from root
if(nodeOffs == 0) { // left
oldRoot.pageIdArray[BTreeMain.T-1] = newNode.pageId;
oldRoot.pageArray[BTreeMain.T-1] = newNode;
} else {
oldRoot.pageIdArray[BTreeMain.T] = newNode.pageId;
oldRoot.pageArray[BTreeMain.T] = newNode;
}
oldRoot.setUpdated(true);
}
}
@Override
public long getLongReturn() {
return newNode.pageId;
}
@Override
public Object getObjectReturn() {
return newNode;
}
}