if( isBranch() ) { return getLeafNode(tx, this, key).put(tx, key, value); } else { int idx = Arrays.binarySearch(keys, key); setLeafData(keys, values); } else { setLeafData(arrayInsert(keys, key, idx), arrayInsert(values, value, idx)); index.storeNode(tx, this, allowOverflow()); } catch ( Transaction.PageOverflowIOException e ) { split(tx);
if(isBranch()) { int idx = Arrays.binarySearch(keys, key); idx = idx < 0 ? -(idx + 1) : idx + 1; BTreeNode<Key, Value> child = getChild(tx, idx); if( child.getPageId() == index.getPageId() ) { throw new IOException("BTree corrupted: Cycle detected."); Value rc = child.remove(tx, key); if( child.isBranch() ) { tx.free(child.getPage()); } else { previousLeaf = getChild(tx, idx-1).getRightLeaf(tx); } else { BTreeNode<Key, Value> lp = getLeftPeer(tx, this); if( lp!=null ) { previousLeaf = lp.getRightLeaf(tx); setBranchData(arrayDelete(keys, idx), arrayDelete(children, idx)); } else { setBranchData(arrayDelete(keys, idx-1), arrayDelete(children, idx)); child = getChild(tx, 0); keys = child.keys; children = child.children;
public void setEmpty() { setLeafData(createKeyArray(0), createValueArray(0)); }
public int getMinLeafDepth(Transaction tx, int depth) throws IOException { depth++; if( isBranch() ) { int min = Integer.MAX_VALUE; for(int i=0 ; i < children.length; i++) { min = Math.min(min, getChild(tx, i).getMinLeafDepth(tx, depth)); } return min; } else { // print(depth*2, "- "+page.getPageId()); return depth; } }
if( isBranch() ) { leftKeys = createKeyArray(pivot); leftChildren = new long[leftKeys.length + 1]; rightKeys = createKeyArray(vc - (pivot + 1)); rightChildren = new long[rightKeys.length + 1]; leftKeys = createKeyArray(pivot); leftValues = createValueArray(leftKeys.length); rightKeys = createKeyArray(vc - pivot); rightValues = createValueArray(rightKeys.length); if( isBranch() ) { rNode.setBranchData(rightKeys, rightChildren); lNode.setBranchData(leftKeys, leftChildren); } else { rNode.setLeafData(rightKeys, rightValues); lNode.setLeafData(leftKeys, leftValues); lNode.setNext(rNode.getPageId()); Key[] v = createKeyArray(1); v[0]=separator; setBranchData(v, new long[] { lNode.getPageId(), rNode.getPageId() }); if( isBranch() ) { setBranchData(leftKeys, leftChildren); rNode.setBranchData(rightKeys, rightChildren); } else { rNode.setNext(next);
public void clear(Transaction tx) throws IOException { if( isBranch() ) { for (int i = 0; i < children.length; i++) { BTreeNode<Key, Value> node = index.loadNode(tx, children[i], this); node.clear(tx); tx.free(node.getPage()); } } // Reset the root node to be a leaf. if( parent == null ) { setLeafData(createKeyArray(0), createValueArray(0)); next=-1; index.storeNode(tx, this, true); } }
private void promoteValue(Transaction tx, Key key, long nodeId) throws IOException { int idx = Arrays.binarySearch(keys, key); idx = idx < 0 ? -(idx + 1) : idx + 1; setBranchData(arrayInsert(keys, key, idx), arrayInsert(children, nodeId, idx + 1)); try { index.storeNode(tx, this, allowOverflow()); } catch ( Transaction.PageOverflowIOException e ) { split(tx); } }
public void printStructure(Transaction tx, PrintWriter out, String prefix) throws IOException { if( prefix.length()>0 && parent == null ) { throw new IllegalStateException("Cycle back to root node detected."); } if (parent == null) { prefix += "|"; out.println(prefix + getPageId()); } if( isBranch() ) { for(int i=0 ; i < children.length; i++) { BTreeNode<Key, Value> child = getChild(tx, i); if( i == children.length-1) { out.println(prefix+"\\- "+child.getPageId()+(child.isBranch()?" ("+child.children.length+")":"")); child.printStructure(tx, out, prefix+" "); } else { out.println(prefix+"|- "+child.getPageId()+(child.isBranch()?" ("+child.children.length+")":"")+" : "+keys[i]); child.printStructure(tx, out, prefix+" "); } } } }
public int getMaxLeafDepth(Transaction tx, int depth) throws IOException { depth++; if( isBranch() ) { int v = 0; for(int i=0 ; i < children.length; i++) { v = Math.max(v, getChild(tx, i).getMaxLeafDepth(tx, depth)); } depth = v; } return depth; }
public boolean contains(Transaction tx, Key key) throws IOException { if (key == null) { throw new IllegalArgumentException("Key cannot be null"); } if( isBranch() ) { return getLeafNode(tx, this, key).contains(tx, key); } else { int idx = Arrays.binarySearch(keys, key); if (idx < 0) { return false; } else { return true; } } }
public Value get(Transaction tx, Key key) throws IOException { if (key == null) { throw new IllegalArgumentException("Key cannot be null"); } if( isBranch() ) { return getLeafNode(tx, this, key).get(tx, key); } else { int idx = Arrays.binarySearch(keys, key); if (idx < 0) { return null; } else { return values[idx]; } } }
public void visit(Transaction tx, BTreeVisitor<Key, Value> visitor) throws IOException { if (visitor == null) { throw new IllegalArgumentException("Visitor cannot be null"); } if( isBranch() ) { for(int i=0; i < this.children.length; i++) { Key key1 = null; if( i!=0 ) { key1 = keys[i-1]; } Key key2 = null; if( i!=this.children.length-1 ) { key2 = keys[i]; } if( visitor.isInterestedInKeysBetween(key1, key2) ) { BTreeNode<Key, Value> child = getChild(tx, i); child.visit(tx, visitor); } } } else { visitor.visit(Arrays.asList(keys), Arrays.asList(values)); } }
/** * Returns the left most leaf from the current btree graph. * @throws IOException */ private BTreeNode<Key,Value> getLeftPeer(Transaction tx, BTreeNode<Key,Value> x) throws IOException { BTreeNode<Key,Value> cur = x; while( cur.parent !=null ) { if( cur.parent.children[0] == cur.getPageId() ) { cur = cur.parent; } else { for( int i=0; i < cur.parent.children.length; i ++) { if( cur.parent.children[i]==cur.getPageId() ) { return cur.parent.getChild(tx, i-1); } } throw new AssertionError("page "+x+" was decendent of "+cur.getPageId()); } } return null; }
synchronized public boolean containsKey(Transaction tx, Key key) throws IOException { assertLoaded(); return getRoot(tx).contains(tx, key); }
synchronized public Value get(Transaction tx, Key key) throws IOException { assertLoaded(); return getRoot(tx).get(tx, key); }
synchronized public void clear(Transaction tx) throws IOException { getRoot(tx).clear(tx); }
@SuppressWarnings("unchecked") public BTreeNode<Key,Value> readPayload(DataInput is) throws IOException { BTreeNode<Key,Value> node = new BTreeNode<Key,Value>(index); int count = is.readShort(); node.keys = (Key[])new Object[count]; for (int i = 0; i < count; i++) { node.keys[i] = index.getKeyMarshaller().readPayload(is); } if( is.readBoolean() ) { node.children = new long[count+1]; for (int i = 0; i < count+1; i++) { node.children[i] = is.readLong(); } } else { node.values = (Value[])new Object[count]; for (int i = 0; i < count; i++) { node.values[i] = index.getValueMarshaller().readPayload(is); } node.next = is.readLong(); } return node; } }
if( isBranch() ) { leftKeys = createKeyArray(pivot); leftChildren = new long[leftKeys.length + 1]; rightKeys = createKeyArray(vc - (pivot + 1)); rightChildren = new long[rightKeys.length + 1]; leftKeys = createKeyArray(pivot); leftValues = createValueArray(leftKeys.length); rightKeys = createKeyArray(vc - pivot); rightValues = createValueArray(rightKeys.length); if( isBranch() ) { rNode.setBranchData(rightKeys, rightChildren); lNode.setBranchData(leftKeys, leftChildren); } else { rNode.setLeafData(rightKeys, rightValues); lNode.setLeafData(leftKeys, leftValues); lNode.setNext(rNode.getPageId()); Key[] v = createKeyArray(1); v[0]=separator; setBranchData(v, new long[] { lNode.getPageId(), rNode.getPageId() }); if( isBranch() ) { setBranchData(leftKeys, leftChildren); rNode.setBranchData(rightKeys, rightChildren); } else { rNode.setNext(next);