Class SoftBPlusTree<V>
- Type Parameters:
V- value type
BPlusTree subclass that persists each node independently to a
SoftBPlusTree.NodeStore and wraps every inner-node child in a SoftBPlusTree.SoftNode.
After each put(byte[], V) or remove(byte[]), only the nodes on the modified
path (from the affected leaf up to the root's children) are serialized and
written — typically O(height) writes of a few hundred bytes each. Unmodified
subtrees keep their existing disk locations. A SoftReference at every
inner-node level lets the JVM evict cached subtrees under memory pressure;
they are reloaded from disk on demand.
Keys are not stored on disk. On deserialization, keys are loaded from the
external data source via the SoftBPlusTree.KeyLoader callback. This matches the
old IndexNode disk format exactly.
Disk space is managed internally using a block-aligned free list. Freed blocks are pooled by size and reused for future allocations to avoid unbounded index file growth.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classThrown by aBPlusTree.PublishFunctionor during node resolution when the underlying data for a tree entry is no longer available — for example, because a compactor deleted the data file between the time the index was read and the time the entry was accessed.static interfaceABPlusTree.PublishFunctionthat may throwIOException.static interfaceLoads the B+ tree key for a given value during leaf node deserialization.static final recordA disk region descriptor: byte offset and allocated size.static interfaceStorage backend for serialized nodes.static interfaceSerializes and deserializes values stored in leaf nodes.Nested classes/interfaces inherited from class BPlusTree
BPlusTree.LeafNode<V>, BPlusTree.Node<V>, BPlusTree.PathEntry<V>, BPlusTree.PublishFunction<V,R> -
Field Summary
Fields inherited from class BPlusTree
maxNodeSize, minNodeSize, RESERVED_SPACE -
Constructor Summary
ConstructorsConstructorDescriptionSoftBPlusTree(int minNodeSize, int maxNodeSize, SoftBPlusTree.NodeStore store, SoftBPlusTree.ValueSerializer<V> serializer, SoftBPlusTree.KeyLoader<V> keyLoader) Creates a disk-backed B+ tree with no block alignment (alignment of 1) and an initial store size of 0.SoftBPlusTree(int minNodeSize, int maxNodeSize, SoftBPlusTree.NodeStore store, SoftBPlusTree.ValueSerializer<V> serializer, SoftBPlusTree.KeyLoader<V> keyLoader, short blockAlignment, long initialStoreSize) Creates a disk-backed B+ tree with block-aligned free space management. -
Method Summary
Modifier and TypeMethodDescriptionvoidclear()Removes all entries, resetting the tree to an empty root leaf.voidRestores the free block lists from a buffer previously produced byserializeFreeBlocks().get(byte[] key) Look up a key.longReturns the current logical size of the backing store in bytes.voidloadTree(SoftBPlusTree.NodeSpace rootSpace) Reconstructs the tree from a previously persisted root.protected voidonChildrenReplaced(BPlusTree.Node<V>[] oldChildren, int from, int to) protected voidonValueOverwritten(Deque<BPlusTree.PathEntry<V>> stack, BPlusTree.LeafNode<V> leaf, int entryIndex) <R> io.reactivex.rxjava3.core.Flowable<R> publish(BPlusTree.PublishFunction<V, R> function) Returns aFlowablethat emits entries in sorted order.<R> io.reactivex.rxjava3.core.Flowable<R> publish(SoftBPlusTree.IOPublishFunction<V, R> function, boolean skipOnOutdated) Returns aFlowablethat emits entries in sorted order withSoftBPlusTree.IndexNodeOutdatedExceptionhandling controlled byskipOnOutdated.Insert or replace a value.remove(byte[] key) Remove a key.saveTree()Persists the tree to the store.Serializes the free block lists into aByteBufferfor persistence.voidsetStoreSize(long size) Sets the logical size of the backing store, typically restored from a persisted header.protected booleantryInPlaceLeafUpdate(Deque<BPlusTree.PathEntry<V>> stack, BPlusTree.LeafNode<V> oldLeaf, BPlusTree.LeafNode<V> newLeaf)
-
Constructor Details
-
SoftBPlusTree
public SoftBPlusTree(int minNodeSize, int maxNodeSize, SoftBPlusTree.NodeStore store, SoftBPlusTree.ValueSerializer<V> serializer, SoftBPlusTree.KeyLoader<V> keyLoader, short blockAlignment, long initialStoreSize) Creates a disk-backed B+ tree with block-aligned free space management.- Parameters:
minNodeSize- minimum serialized node size before mergingmaxNodeSize- maximum serialized node size before splittingstore- backing storage for serialized nodesserializer- value serializer/deserializerkeyLoader- reconstructs keys from values during deserializationblockAlignment- disk block alignment in bytes (freed blocks are pooled by aligned size)initialStoreSize- starting byte offset for new allocations (typically the header size)
-
SoftBPlusTree
public SoftBPlusTree(int minNodeSize, int maxNodeSize, SoftBPlusTree.NodeStore store, SoftBPlusTree.ValueSerializer<V> serializer, SoftBPlusTree.KeyLoader<V> keyLoader) Creates a disk-backed B+ tree with no block alignment (alignment of 1) and an initial store size of 0.- See Also:
-
-
Method Details
-
getStoreSize
public long getStoreSize()Returns the current logical size of the backing store in bytes. -
setStoreSize
public void setStoreSize(long size) Sets the logical size of the backing store, typically restored from a persisted header. -
serializeFreeBlocks
Serializes the free block lists into aByteBufferfor persistence. The caller should write this alongside the tree root descriptor so that free space can be restored on restart viadeserializeFreeBlocks(ByteBuffer).- Returns:
- a flipped buffer containing the serialized free block state
-
deserializeFreeBlocks
Restores the free block lists from a buffer previously produced byserializeFreeBlocks(). Any existing free block state is replaced. -
onChildrenReplaced
- Overrides:
onChildrenReplacedin classBPlusTree<V>
-
onValueOverwritten
protected void onValueOverwritten(Deque<BPlusTree.PathEntry<V>> stack, BPlusTree.LeafNode<V> leaf, int entryIndex) - Overrides:
onValueOverwrittenin classBPlusTree<V>
-
tryInPlaceLeafUpdate
protected boolean tryInPlaceLeafUpdate(Deque<BPlusTree.PathEntry<V>> stack, BPlusTree.LeafNode<V> oldLeaf, BPlusTree.LeafNode<V> newLeaf) - Overrides:
tryInPlaceLeafUpdatein classBPlusTree<V>
-
get
Look up a key. Returns the value or null if the key is not present.Retries up to
MAX_OUTDATED_RETRIEStimes onSoftBPlusTree.IndexNodeOutdatedException, which can occur when aSoftBPlusTree.SoftNoderesolves from disk and the backing data has been concurrently deleted (e.g., by a compactor). -
put
-
remove
-
publish
Returns aFlowablethat emits entries in sorted order. The function transforms each entry, returningnullto skip. Any exception thrown by the function or during node resolution propagates as a Flowable error; subclasses may override to add retry logic.Retries the entire iteration up to
MAX_OUTDATED_RETRIEStimes onSoftBPlusTree.IndexNodeOutdatedException, resuming from the last successfully emitted key. The function may throwSoftBPlusTree.IndexNodeOutdatedExceptionto force a retry for the current entry rather than returningnull(which skips the entry without retrying). -
publish
public <R> io.reactivex.rxjava3.core.Flowable<R> publish(SoftBPlusTree.IOPublishFunction<V, R> function, boolean skipOnOutdated) Returns aFlowablethat emits entries in sorted order withSoftBPlusTree.IndexNodeOutdatedExceptionhandling controlled byskipOnOutdated.When
skipOnOutdatedistrue, anySoftBPlusTree.IndexNodeOutdatedExceptionthrown by the function is caught and the entry is silently skipped (treated as if the function returnednull). Exceptions thrown during node resolution still trigger a full retry. Whenfalse, allSoftBPlusTree.IndexNodeOutdatedExceptions trigger a retry. -
clear
-
saveTree
Persists the tree to the store. All descendants should already be persisted as SoftNodes (via afterMutation calls during normal operation). This method serializes the root node itself and returns a descriptor that the caller can write into the file header forloadTree(SoftBPlusTree.NodeSpace)to find on restart.The free-block state must be persisted separately by the caller via
serializeFreeBlocks().- Returns:
- the root's disk location, or null if the tree is empty
- Throws:
IOException
-
loadTree
Reconstructs the tree from a previously persisted root. For an inner root, each child is created as aSoftBPlusTree.SoftNodepointing at its disk location — no child data is loaded until first access.- Throws:
IOException
-