use of org.apache.jena.dboe.base.record.Record in project jena by apache.
the class BPTreeNode method internalMinRecord.
@Override
protected Record internalMinRecord(AccessPath path) {
BPTreePage page = get(0);
trackPath(path, this, 0, page);
Record r = page.internalMinRecord(path);
page.release();
return r;
}
use of org.apache.jena.dboe.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 (BPT.CheckingNode)
if (!root.isRoot())
BPT.error("Not root: %d (root is id zero)", root.getId());
root.internalCheckNode();
promoteRoot(root);
// Median record
int splitIdx = root.params.SplitIndex;
Record rec = root.records.get(splitIdx);
if (logging(log)) {
log(log, "** Split root %d (%s)", splitIdx, rec);
log(log, "splitRoot >> %s", root);
}
// New blocks.
BPTreeNode left = create(bpTree, root.getId(), root.isLeaf);
BPTreeNode right = create(bpTree, root.getId(), 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)) {
log(log, "splitRoot -- left: %s", left);
log(log, "splitRoot -- right: %s", 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.getId());
// slot 1
root.ptrs.set(1, right.getId());
if (logging(log)) {
log(log, "splitRoot << %s", root);
log(log, "splitRoot << %s", left);
log(log, "splitRoot << %s", right);
}
left.write();
right.write();
left.release();
right.release();
root.write();
if (BPT.CheckingNode) {
root.internalCheckNode();
left.internalCheckNode();
right.internalCheckNode();
}
}
use of org.apache.jena.dboe.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)) {
log(log, "** delete(%s) / start", rec);
if (BPT.DumpTree)
root.dump();
}
if (!root.isRoot())
throw new BPTreeException("Delete begins but this is not the root");
AccessPath path = new AccessPath(root);
if (root.isLeaf && root.count == 0) {
// Special case. Just a records block. Allow that to go too small.
BPTreePage page = root.get(0);
if (BPT.CheckingNode && !(page instanceof BPTreeRecords))
BPT.error("Zero size leaf root but not pointing to a records block");
trackPath(path, root, 0, page);
Record r = page.internalDelete(path, rec);
page.release();
if (r != null)
root.write();
if (BPT.DumpTree)
root.dump();
return r;
}
// Entry: checkNodeDeep();
Record v = root.internalDelete(path, rec);
// Fix the root in case it became empty in deletion process.
if (!root.isLeaf && root.count == 0) {
reduceRoot(root);
root.bpTree.newRoot(root);
root.internalCheckNodeDeep();
}
if (logging(log)) {
log(log, "** delete(%s) / finish", rec);
if (BPT.DumpTree)
root.dump();
}
return v;
}
use of org.apache.jena.dboe.base.record.Record in project jena by apache.
the class BPTreeNode method checkNode.
// Checks of a single node - no looking at children
// min - inclusive; max - inclusive (allows for duplicates)
private final void checkNode(Record min, Record max) {
int id = getId();
if (count != records.size())
BPT.error("Inconsistent: id=%d, count=%d, records.size()=%d : %s", id, count, records.size(), this);
if (!isLeaf && count + 1 != ptrs.size())
BPT.error("Inconsistent: id=%d, count+1=%d, ptrs.size()=%d; %s", id, count + 1, ptrs.size(), this);
// if ( bpTree.root != null && !isRoot() && count < params.MinRec)
if (!isRoot() && count < params.MinRec) {
// warning("Runt node: %s", this);
BPT.error("Runt node: %s", this);
}
if (!isRoot() && count > maxRecords())
BPT.error("Over full node: %s", this);
if (!isLeaf && parent == id)
BPT.error("Parent same as id: %s", this);
Record k = min;
// Test records in the allocated area
for (int i = 0; i < count; i++) {
if (records.get(i) == null)
BPT.error("Node: %d : Invalid record @%d :: %s", id, i, this);
if (k != null && keyGT(k, records.get(i))) {
Record r = records.get(i);
// keyGT(k, r);
BPT.error("Node: %d: Not sorted (%d) (%s, %s) :: %s ", id, i, k, r, this);
}
k = records.get(i);
}
if (k != null && max != null && keyGT(k, max))
BPT.error("Node: %d - Record is too high (max=%s):: %s", id, max, this);
if (SystemIndex.getNullOut()) {
// Test records in the free area
for (int i = count; i < maxRecords(); i++) {
if (!records.isClear(i))
BPT.error("Node: %d - not clear (idx=%d) :: %s", id, i, this);
}
}
// Pointer checks.
int i = 0;
// Check not empty at bottom.
for (; i < count + 1; i++) {
if (ptrs.get(i) < 0)
BPT.error("Node: %d: Invalid child pointer @%d :: %s", id, i, this);
// // This does Block IO so disturbs tracking.
// if ( BPT.CheckingTree && isLeaf ) {
// int ptr = ptrs.get(i);
// BPTreeRecords records = bpTree.getRecordsMgr().getRead(ptr);
// int rid = records.getId();
// if ( rid != ptrs.get(i) )
// BPT.error("Records: Block @%d has a different id: %d :: %s", rid, i, this);
// int link = records.getLink();
// // Don't check if -1 which does not exist.
// if ( link != -1 && i != count ) {
// BPTreeRecords page = bpTree.getRecordsMgr().getRead(ptrs.get(i));
// int rid2 = page.getLink();
// if ( link != rid2 )
// BPT.error("Records: Link not to next block @%d/@%d has a different id: %d :: %s", rid, rid2, i, records);
// bpTree.getRecordsMgr().release(page);
// }
// records.release();
// }
}
// Check empty is empty
if (SystemIndex.getNullOut()) {
int x = params.MaxPtr;
for (; i < x; i++) {
if (!ptrs.isClear(i))
BPT.error("Node: %d: Unexpected pointer @%d :: %s", id, i, this);
}
}
}
use of org.apache.jena.dboe.base.record.Record in project jena by apache.
the class BPTreeNode method checkNodeDeep.
private void checkNodeDeep(Record min, Record max) {
checkNode(min, max);
int id = getId();
// Check pointers.
int limit = (count == 0) ? 0 : count + 1;
for (int i = 0; i < limit; i++) {
Record min1 = min;
Record max1 = max;
BPTreePage n = get(i);
if (i != count) {
// high key in immediate
Record keySubTree = n.getHighRecord();
// child
// key in this
Record keyHere = records.get(i);
if (keySubTree == null)
BPT.error("Node: %d: Can't get high record from %d", id, n.getId());
if (keySubTree.getKey() == null)
BPT.error("Node: %d: Can't get high record is missing it's key from %d", id, n.getId());
if (keyHere == null)
BPT.error("Node: %d: record is null", id);
if (keyHere.getKey() == null)
BPT.error("Node: %d: Record key is null", id);
if (keyGT(keySubTree, keyHere))
BPT.error("Node: %d: Child key %s is greater than this key %s", id, keySubTree, keyHere);
// max key in subTree
Record keyMax = n.maxRecord();
Record keyMin = n.internalMinRecord(null);
if (keyNE(keyHere, keyMax))
BPT.error("Node: %d: Key %s is not the max [%s] of the sub-tree idx=%d", id, keyHere, keyMax, i);
if (min != null && keyGT(min, keyMin))
BPT.error("Node: %d: Minimun for this node should be %s but it's %s", id, min, keyMin);
if (max != null && keyLT(max, keyMax))
BPT.error("Node: %d: Maximum for this node should be %s but it's %s", id, max, keyMax);
if (min != null && keyGT(min, keyHere))
BPT.error("Node: %d: Key too small: %s - min should be %s", id, keyHere, min);
// keyHere == keyMax ??
if (max != null && keyLT(max, keyHere))
BPT.error("Node: %d: Key too large: %s - max should be %s", id, keyHere, max);
}
// Look deeper.
if (!(n instanceof BPTreeNode)) {
// Records.
n.checkNodeDeep();
n.release();
continue;
}
// Valid pointer?
if (isLeaf) {
if (!bpTree.getRecordsMgr().getBlockMgr().valid(ptrs.get(i)))
BPT.error("Node: %d: Dangling ptr (records) in block @%d :: %s", id, i, this);
} else {
if (!bpTree.getNodeManager().valid(ptrs.get(i)))
BPT.error("Node: %d: Dangling ptr in block @%d :: %s", id, i, this);
}
// Calc new min/max.
if (i == 0)
max1 = records.get(0);
else if (i == count) {
min1 = records.get(count - 1);
max1 = null;
} else {
min1 = records.get(i - 1);
max1 = records.get(i);
}
// if ( n.parent != id )
// error("Node: %d [%d]: Parent/child mismatch :: %s", id, n.parent,
// this);
((BPTreeNode) n).checkNodeDeep(min1, max1);
n.release();
}
}
Aggregations