@Override public LeaveBlockImpl createBlock(long parentBlock, DataBlock dataBlock) throws JasDBStorageException { LeaveBlockImpl leaveBlock = new LeaveBlockImpl(persister, dataBlock, parentBlock, true); return leaveBlock; } }
protected void addKeys(List<TreeNode> nodes, LeaveBlockImpl targetLeave) { for(TreeNode node : nodes) { targetLeave.addKey(node.getKey()); } }
private void mergeLeaves(TreeBlock parentBlock, LeaveBlockImpl leftLeave, LeaveBlockImpl rightLeave) throws JasDBStorageException { //lets remove the block and update the admin above Key removeKey; if(leftLeave != null && leftLeave.getParentPointer() == getParentPointer()) { removeKey = getFirst(); log.debug("Doing merge into left leave with remove key: {}", removeKey); leftLeave.addKeys(leaves.values()); leftLeave.recalculateMemorySize(); } else if(rightLeave != null && rightLeave.getParentPointer() == getParentPointer()) { removeKey = getLast(); log.debug("Doing merge into right leave with remove key: {}", removeKey); rightLeave.addKeys(leaves.values()); rightLeave.recalculateMemorySize(); } else { throw new JasDBStorageException("Invalid index state there should always be a sibbling leave block"); } if(leftLeave != null) { leftLeave.setNext(rightLeave != null ? rightLeave.getPosition() : -1); } if(rightLeave != null) { rightLeave.setPrevious(leftLeave != null ? leftLeave.getPosition() : -1); } leaves.reset(); persister.markDeleted(this); parentBlock.removeBlockPointer(removeKey, this); }
if(leftLeave != null && leftLeave.getParentPointer() == getParentPointer() && leftLeave.size() > persister.getMinKeys()) { log.debug("Borrowing from left leave"); Key borrowKey = leftLeave.getLast(); leftLeave.removeKeyInternal(borrowKey); leaves.put(borrowKey, borrowKey); leftLeave.recalculateMemorySize(); parentBlock.updateBlockPointer(leftLeave.getLast(), leftLeave.getPosition(), getPosition()); } else if(rightLeave != null && rightLeave.getParentPointer() == getParentPointer() && rightLeave.size() > persister.getMinKeys()) { log.debug("Borrowing from right leave"); Key borrowKey = rightLeave.getFirst(); rightLeave.removeKeyInternal(borrowKey); leaves.put(borrowKey, borrowKey); rightLeave.recalculateMemorySize(); parentBlock.updateBlockPointer(borrowKey, getPosition(), rightLeave.getPosition()); } else { mergeLeaves(parentBlock, leftLeave, rightLeave);
private void handleBlockOverflow() throws JasDBStorageException { if(leaves.size() > persister.getMaxKeys()) { List<Key>[] splittedKeys = leaves.split(); this.leaves.reset(); /* this block keeps representing the right half, the last current block key == max right */ List<Key> rightKeys = splittedKeys[1]; addKeys(rightKeys); List<Key> leftKeys = splittedKeys[0]; long currentPrevious = leaveProperties.getPreviousBlock(); LeaveBlockImpl leftLeaveBlock = (LeaveBlockImpl) persister.createBlock(BlockTypes.LEAVEBLOCK, leaveProperties.getParentPointer()); leftLeaveBlock.setPrevious(currentPrevious); leftLeaveBlock.setNext(getPosition()); leftLeaveBlock.addKeys(leftKeys); this.recalculateMemorySize(); leftLeaveBlock.recalculateMemorySize(); if(currentPrevious != -1) { //we need to relink, there is a previous block present LeaveBlockImpl previousBlock = (LeaveBlockImpl) persister.loadBlock(currentPrevious); previousBlock.setNext(leftLeaveBlock.getPosition()); } leaveProperties.setPreviousBlock(leftLeaveBlock.getPosition()); TreeBlock parentBlock = (TreeBlock) persister.loadBlock(leaveProperties.getParentPointer()); parentBlock.insertBlock(leftLeaveBlock.getLast(), leftLeaveBlock, this); } }
@Override public void insertKey(Key key) throws JasDBStorageException { if(isLeave) { addKey(key); modified = true; if(treeNodes.size() > persister.getMaxKeys()) { List<TreeNode>[] leaveValues = treeNodes.split(); List<TreeNode> leftLeaves = leaveValues[0]; List<TreeNode> rightLeaves = leaveValues[1]; treeNodes.reset(); LeaveBlockImpl leftLeaveBlock = (LeaveBlockImpl) persister.createBlock(BlockTypes.LEAVEBLOCK, getPosition()); LeaveBlockImpl rightLeaveBlock = (LeaveBlockImpl) persister.createBlock(BlockTypes.LEAVEBLOCK, getPosition()); leftLeaveBlock.setNext(rightLeaveBlock.getPosition()); rightLeaveBlock.setPrevious(leftLeaveBlock.getPosition()); addKeys(leftLeaves, leftLeaveBlock); addKeys(rightLeaves, rightLeaveBlock); Key promoteKey = leftLeaves.get(leftLeaves.size() - 1).getKey(); TreeNode rootNode = new TreeNode(promoteKey, leftLeaveBlock.getPosition(), rightLeaveBlock.getPosition()); treeNodes.put(promoteKey, rootNode); isLeave = false; RootBlockFactory.writeHeader(getDataBlock(), false); } } else { throw new JasDBStorageException("Unable to store key, root is not a leave"); } }
@Override public void persistBlock(LeaveBlock block) throws JasDBStorageException { if(block instanceof LeaveBlockImpl && block.isModified()) { LOG.debug("Persisting block at position: {}", block.getPosition()); LeaveBlockImpl leaveBlock = (LeaveBlockImpl) block; List<Key> writeKeys = leaveBlock.getValues(); int nrKeys = writeKeys.size(); DataBlock dataBlock = block.getDataBlock(); dataBlock.reset(); dataBlock.getHeader().putLong(PREVIOUS_LEAVE_INDEX, leaveBlock.getProperties().getPreviousBlock()); dataBlock.getHeader().putLong(NEXT_LEAVE_INDEX, leaveBlock.getProperties().getNextBlock()); dataBlock.getHeader().putLong(PARENT_BLOCK_INDEX, leaveBlock.getParentPointer()); dataBlock.getHeader().putInt(AMOUNT_KEY_INDEX, nrKeys); LOG.debug("Writing amount of keys: {}", nrKeys); for(Key key : writeKeys) { dataBlock = keyInfo.writeKey(key, dataBlock); } } else if(block.isModified()) { throw new JasDBStorageException("Unable to store block, unexpected type"); } }
@Override public LeaveBlock loadBlock(DataBlock dataBlock) throws JasDBStorageException { LOG.debug("Loading block: {}", dataBlock); LeaveBlockImpl leaveBlock = createBlock(-1, dataBlock); LeaveBlockProperties properties = leaveBlock.getProperties(); properties.setModified(false); int amountOfKeys = dataBlock.getHeader().getInt(AMOUNT_KEY_INDEX); long nextBlock = dataBlock.getHeader().getLong(NEXT_LEAVE_INDEX); long previousBlock = dataBlock.getHeader().getLong(PREVIOUS_LEAVE_INDEX); long parent = dataBlock.getHeader().getLong(PARENT_BLOCK_INDEX); int offset = 0; DataBlock currentBlock = dataBlock; for(int i=0; i<amountOfKeys; i++) { KeyLoadResult loadedKeyResult = keyInfo.loadKey(offset, currentBlock); leaveBlock.addKey(loadedKeyResult.getLoadedKey()); currentBlock = loadedKeyResult.getEndBlock(); offset = loadedKeyResult.getNextOffset(); } properties.setNextBlock(nextBlock); properties.setPreviousBlock(previousBlock); properties.setModified(false); properties.setParentBlock(parent); return leaveBlock; }
public void insertKey(Key key) throws JasDBStorageException { leaves.put(key, key); memorySize += key.size(); leaveProperties.setModified(true); handleBlockOverflow(); }
isLeave = true; RootBlockFactory.writeHeader(getDataBlock(), true); for(Key key : leaveBlock.getValues()) { addKey(key);