use of org.apache.jena.tdb.base.record.Record in project jena by apache.
the class BPTreeNode method splitRoot.
/* Split the root and leave the root block as the root.
* This is the only point the height of the tree increases.
*
* Allocate new blocks.
* Copy root low into left
* Copy root high into right
* Set counts.
* Create new root settings (two pointers, one key record)
* WRITE(left)
* WRITE(right)
* WRITE(root)
*/
private static void splitRoot(BPTreeNode root) {
BPlusTree bpTree = root.bpTree;
if (CheckingNode)
if (root.id != 0)
root.error("Not root: %d (root is id zero)", root.id);
root.internalCheckNode();
root.promote();
// Median record
int splitIdx = root.params.SplitIndex;
Record rec = root.records.get(splitIdx);
if (logging()) {
log.debug(format("** Split root %d (%s)", splitIdx, rec));
log.debug("splitRoot >> " + root);
}
// New blocks.
BPTreeNode left = create(bpTree, root.id, root.isLeaf);
BPTreeNode right = create(bpTree, root.id, root.isLeaf);
// int maxRecords = maxRecords() ;
// New left
root.records.copy(0, left.records, 0, splitIdx);
root.ptrs.copy(0, left.ptrs, 0, splitIdx + 1);
left.count = splitIdx;
// New right
root.records.copy(splitIdx + 1, right.records, 0, root.maxRecords() - (splitIdx + 1));
root.ptrs.copy(splitIdx + 1, right.ptrs, 0, root.params.MaxPtr - (splitIdx + 1));
right.count = root.maxRecords() - (splitIdx + 1);
if (logging()) {
log.debug("splitRoot -- left: " + left);
log.debug("splitRoot -- right: " + right);
}
// So left.count+right.count = bTree.NumRec-1
// Clear root by reformatting. New root not a leaf. Has count of 1 after formatting.
BPTreeNodeMgr.formatForRoot(root, false);
// Make a non-leaf.
// Insert two subnodes, divided by the median record
root.count = 1;
root.records.add(0, rec);
root.ptrs.setSize(2);
// slot 0
root.ptrs.set(0, left.id);
// slot 1
root.ptrs.set(1, right.id);
if (logging()) {
log.debug("splitRoot << " + root);
log.debug("splitRoot << " + left);
log.debug("splitRoot << " + right);
}
left.write();
right.write();
left.release();
right.release();
root.write();
if (CheckingTree)
root.checkNodeDeep();
else if (CheckingNode) {
root.internalCheckNode();
left.internalCheckNode();
right.internalCheckNode();
}
}
use of org.apache.jena.tdb.base.record.Record in project jena by apache.
the class BPTreeNode method delete.
/**
* Delete a record - return the old value if there was one, else null
*/
public static Record delete(BPTreeNode root, Record rec) {
if (logging()) {
log.debug(format("** delete(%s) / start", rec));
if (DumpTree)
root.dump();
}
if (!root.isRoot())
throw new BPTreeException("Delete begins but this is not the root");
if (root.isLeaf && root.count == 0) {
// Special case. Just a records block. Allow that to go too small.
BPTreePage page = root.get(0, WRITE);
if (CheckingNode && !(page instanceof BPTreeRecords))
root.error("Zero size leaf root but not pointing a records block");
Record r = page.internalDelete(rec);
page.release();
return r;
}
// Entry: checkNodeDeep() ;
Record v = root.internalDelete(rec);
// Fix root in case it became empty in deletion process.
if (!root.isLeaf && root.count == 0) {
root.reduceRoot();
root.internalCheckNodeDeep();
}
if (logging()) {
log.debug(format("** delete(%s) / finish", rec));
if (DumpTree)
root.dump();
}
return v;
}
use of org.apache.jena.tdb.base.record.Record in project jena by apache.
the class BPTreeNode method shiftLeft.
private void shiftLeft(BPTreePage left, BPTreePage right, int i) {
if (logging()) {
log.debug(">> shiftLeft: this: " + this);
log.debug(">> shiftLeft: left: " + left);
log.debug(">> shiftLeft: right: " + right);
}
Record r1 = records.get(i);
Record r2 = left.shiftLeft(right, r1);
r2 = keyRecord(r2);
this.records.set(i, r2);
left.write();
right.write();
// Do this later - this.put();
if (logging()) {
log.debug("<< shiftLeft: this: " + this);
log.debug("<< shiftLeft: left: " + left);
log.debug("<< shiftLeft: right: " + right);
}
}
use of org.apache.jena.tdb.base.record.Record in project jena by apache.
the class BPTreeNode method insert.
/**
* Insert a record - return existing value if any, else null
*/
public static Record insert(BPTreeNode root, Record record) {
if (logging()) {
log.debug(format("** insert(%s) / start", record));
if (DumpTree)
root.dump();
}
if (!root.isRoot())
throw new BPTreeException("Insert begins but this is not the root");
if (root.isFull()) {
// Root full - root split is a special case.
splitRoot(root);
if (DumpTree)
root.dump();
}
// Root ready - call insert proper.
Record result = root.internalInsert(record);
root.internalCheckNodeDeep();
if (logging()) {
log.debug(format("** insert(%s) / finish", record));
if (DumpTree)
root.dump();
}
return result;
}
use of org.apache.jena.tdb.base.record.Record in project jena by apache.
the class RecordRangeIterator method hasNext.
@Override
public boolean hasNext() {
if (slot != null)
return true;
if (currentPage == null)
return false;
// Set slot.
while (currentIdx >= currentPage.getCount()) {
// Move to next.
int link = currentPage.getLink();
if (link < 0) {
close();
return false;
}
if (currentPage != null)
pageMgr.release(currentPage);
RecordBufferPage nextPage = pageMgr.getReadIterator(link);
// Check currentPage -> nextPage is strictly increasing keys.
Record r1 = currentPage.getRecordBuffer().getHigh();
Record r2 = nextPage.getRecordBuffer().getLow();
if (Record.keyGE(r1, r2))
throw new StorageException("RecordRangeIterator: records not strictly increasing: " + r1 + " // " + r2);
currentPage = nextPage;
countBlocks++;
currentIdx = 0;
}
slot = currentPage.getRecordBuffer().get(currentIdx);
currentIdx++;
if (maxRec != null && Record.keyGE(slot, maxRec)) {
close();
return false;
}
if (slot == null) {
close();
return false;
}
countRecords++;
return true;
}
Aggregations