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); }
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"); } }