public abstract class BPlusTree<L,T extends L> extends DataStructure implements IgniteTree<L,T>
PageIO) and contains a
single tree node. There are two types of pages/nodes: BPlusInnerIO and BPlusLeafIO.
Every page in the tree contains a list of items. Item is just a fixed-size binary payload.
Inner nodes and leaves may have different item sizes. There's a limit on how many items each page can hold.
It is defined by a BPlusIO.getMaxCount(long, int) method of the corresponding IO. There should be no empty
pages in trees, so:
1 to max items0 to max items (an inner page with 0 items is a routing page,
it still has 1 pointer to 1 child, it's not considered an empty page; see below)
canGetRowFromInner is false,
or a key and a value otherwise. Items in every page are sorted according to the order dscribed by
compare(BPlusIO, long, int, Object) method. Specifics of the data stored in items are defined in the
implementation and generally don't matter.
All pages in the tree are divided into levels. Leaves are always at the level 0. Levels of inner pages are
thus positive. Each level represents a singly linked list - each page has a link to the forward page at the
same level. It can be retrieved by calling BPlusIO.getForward(long). This link must be a zero if there's no
forward page. Forward links on level 0 allow iterating tree's keys and values effectively without traversing
any inner nodes (AbstractForwardCursor). Forward links in inner nodes have different purpose, more on that
later.
Leaves have no links other than forward links. But inner nodes also have links to their children nodes. Every inner
node can be viewed like the following structure:
item(0) item(1) ... item(N-1)
link(0) link(1) link(2) ... link(N-1) link(N)
There are N items and N+1 links. Each link points to page of a lower level. For example, pages on
level 2 always point to pages of level 1. For an item i left subtree is defined by
link(i) and right subtree is defined by link(i+1) (BPlusInnerIO.getLeft(long, int) and
BPlusInnerIO.getRight(long, int)). All items in the left subtree are less or equal to the original item
(basic property for the trees).
There's one more important property of these links: forward(left(i)) == right(i). It is called the
triangle invariant. More information on B+Tree structure can easily be found online. Following documentation
concentrates more on specifics of this particular B+Tree implementation.
BPlusTree.Get). It goes recursively
from the root to the leaf (if it's needed). On each level several outcomes are possible.
BPlusTree.Result. Please refer to its usages for specifics of
each operation. Once the path and the leaf for put/remove is found, the operation is then performed from the bottom
to the top. Specifics are described in corresponding classes (BPlusTree.Put, BPlusTree.Remove).
| Modifier and Type | Class and Description |
|---|---|
class |
BPlusTree.Get
Get operation.
|
class |
BPlusTree.Insert |
class |
BPlusTree.Invoke
Invoke operation.
|
class |
BPlusTree.Put
Put operation.
|
class |
BPlusTree.Remove
Remove operation.
|
protected class |
BPlusTree.RemoveRange
The operation of deleting a range of values.
|
class |
BPlusTree.Replace |
static class |
BPlusTree.Result
Operation result.
|
class |
BPlusTree.Search |
static interface |
BPlusTree.TreeRowClosure<L,T extends L>
A generic visitor-style interface for performing filtering/modifications/miscellaneous operations on the tree.
|
static interface |
BPlusTree.TreeRowFactory<L,T extends L>
Row factory from page memory.
|
static interface |
BPlusTree.TreeVisitorClosure<L,T extends L>
A generic visitor-style interface for performing inspection/modification operations on the tree.
|
IgniteTree.InvokeClosure<T>, IgniteTree.OperationType| Modifier and Type | Field and Description |
|---|---|
static String |
CONC_DESTROY_MSG
Destroy msg.
|
static int |
IGNITE_BPLUS_TREE_LOCK_RETRIES_DEFAULT |
protected long |
metaPageId |
static ThreadLocal<Boolean> |
suspendFailureDiagnostic |
static PageHandlerWrapper<BPlusTree.Result> |
testHndWrapper
Wrapper for tree pages operations.
|
grpId, grpName, metrics, pageFlag, pageIoRslvr, pageMem, reuseList, rnd, wal| Modifier | Constructor and Description |
|---|---|
protected |
BPlusTree(String name,
int cacheGrpId,
String grpName,
PageMemory pageMem,
@Nullable IgniteWriteAheadLogManager wal,
AtomicLong globalRmvId,
long metaPageId,
ReuseList reuseList,
byte pageFlag,
@Nullable FailureProcessor failureProcessor,
PageLockTrackerManager pageLockTrackerManager,
PageIoResolver pageIoRslvr) |
protected |
BPlusTree(String name,
int cacheGrpId,
String cacheGrpName,
PageMemory pageMem,
@Nullable IgniteWriteAheadLogManager wal,
AtomicLong globalRmvId,
long metaPageId,
@Nullable ReuseList reuseList,
IOVersions<? extends BPlusInnerIO<L>> innerIos,
IOVersions<? extends BPlusLeafIO<L>> leafIos,
byte pageFlag,
@Nullable FailureProcessor failureProcessor,
PageLockTrackerManager pageLockTrackerManager) |
| Modifier and Type | Method and Description |
|---|---|
protected long |
acquirePage(long pageId) |
protected void |
checkDestroyed()
Check if the tree is getting destroyed.
|
protected abstract int |
compare(BPlusIO<L> io,
long pageAddr,
int idx,
L row) |
protected int |
compare(int lvl,
BPlusIO<L> io,
long pageAddr,
int idx,
L row) |
protected CorruptedTreeException |
corruptedTreeException(String msg,
Throwable cause,
int grpId,
long... pageIds)
Construct the exception and invoke failure processor.
|
long |
destroy()
Destroys tree.
|
long |
destroy(@Nullable IgniteInClosure<L> c,
boolean forceDestroy)
Destroys tree.
|
protected long |
destroyDownPages(LongListReuseBag bag,
long pageId,
int lvl,
@Nullable IgniteInClosure<L> c,
AtomicLong lockHoldStartTime,
long lockMaxTime,
Deque<GridTuple3<Long,Long,Long>> lockedPages)
Recursively destroys tree pages.
|
boolean |
destroyed() |
void |
enableSequentialWriteMode()
Flag for enabling single-threaded append-only tree creation.
|
GridCursor<T> |
find(L lower,
L upper)
Returns a cursor from lower to upper bounds inclusive.
|
GridCursor<T> |
find(L lower,
L upper,
boolean lowIncl,
boolean upIncl,
BPlusTree.TreeRowClosure<L,T> c,
BPlusTree.TreeRowFactory<L,T> rowFactory,
Object x) |
GridCursor<T> |
find(L lower,
L upper,
BPlusTree.TreeRowClosure<L,T> c,
Object x) |
GridCursor<T> |
find(L lower,
L upper,
Object x)
Returns a cursor from lower to upper bounds inclusive.
|
T |
findFirst()
Returns a value mapped to the lowest key, or
null if tree is empty |
T |
findFirst(BPlusTree.TreeRowClosure<L,T> filter)
Returns a value mapped to the lowest key, or
null if tree is empty or no entry matches the passed filter. |
T |
findLast()
Returns a value mapped to the greatest key, or
null if tree is empty |
T |
findLast(BPlusTree.TreeRowClosure<L,T> c)
Returns a value mapped to the greatest key, or
null if tree is empty or no entry matches the passed filter. |
T |
findOne(L row)
Returns the value to which the specified key is mapped, or
null if this tree contains no mapping for the
key. |
<R> R |
findOne(L row,
BPlusTree.TreeRowClosure<L,T> c,
Object x) |
<R> R |
findOne(L row,
Object x) |
protected Iterable<Long> |
getFirstPageIds(long pageAddr) |
protected int |
getLockRetries() |
long |
getMetaPageId()
Returns meta page id.
|
T |
getRow(BPlusIO<L> io,
long pageAddr,
int idx)
Get a full detached data row.
|
abstract T |
getRow(BPlusIO<L> io,
long pageAddr,
int idx,
Object x)
Get data row.
|
protected void |
initTree(boolean initNew)
Initialize new tree.
|
protected void |
initTree(boolean initNew,
int inlineSize)
Initialize new tree.
|
static void |
interruptAll()
Interrupt all operations on all threads and all indexes.
|
void |
invoke(L row,
Object z,
IgniteTree.InvokeClosure<T> c) |
boolean |
isEmpty() |
void |
iterate(L lower,
L upper,
BPlusTree.TreeRowClosure<L,T> c) |
BPlusInnerIO<L> |
latestInnerIO() |
BPlusLeafIO<L> |
latestLeafIO() |
protected String |
lockRetryErrorMessage(String op)
Create an error message when reaching the maximum
number of repetitions to capture a lock in the B+Tree.
|
boolean |
markDestroyed() |
protected long |
maxLockHoldTime()
Maximum time for which tree destroy process is allowed to hold the lock, after this time exceeds,
temporaryReleaseLock() is called and hold time is reset. |
String |
printTree()
For debug.
|
protected void |
processFailure(FailureType failureType,
Throwable e)
Processes failure with failure processor.
|
T |
put(T row)
Put value in this tree.
|
boolean |
putx(T row) |
protected <X,R> R |
read(long pageId,
long page,
PageHandler<X,R> h,
X arg,
int intArg,
R lockFailed) |
protected <X,R> R |
read(long pageId,
PageHandler<X,R> h,
X arg,
int intArg,
R lockFailed) |
T |
remove(L row)
Removes the mapping for a key from this tree if it is present.
|
List<L> |
remove(L lower,
L upper,
int limit) |
boolean |
removex(L row) |
int |
rootLevel() |
void |
setIos(IOVersions<? extends BPlusInnerIO<L>> innerIos,
IOVersions<? extends BPlusLeafIO<L>> leafIos) |
long |
size()
Returns number of elements in the tree by scanning pages of the bottom (leaf) level.
|
long |
size(@Nullable BPlusTree.TreeRowClosure<L,T> filter)
Returns number of elements in the tree that match the filter by scanning through the pages of the leaf level.
|
protected IoStatisticsHolder |
statisticsHolder() |
protected void |
temporaryReleaseLock()
Releases the lock that is held by long tree destroy process for a short period of time and acquires it again,
allowing other processes to acquire it.
|
String |
toString() |
static String |
treeName(String instance,
String type) |
void |
validateTree() |
void |
visit(L lower,
L upper,
BPlusTree.TreeVisitorClosure<L,T> c) |
acquirePage, allocatePage, allocatePage, allocatePageNoReuse, close, groupId, init, name, needWalDeltaRecord, pageSize, randomInt, read, read, readLock, readUnlock, recyclePage, releasePage, tryWriteLock, write, write, write, write, writeLock, writeUnlock, writeUnlockpublic static PageHandlerWrapper<BPlusTree.Result> testHndWrapper
public static final ThreadLocal<Boolean> suspendFailureDiagnostic
public static final String CONC_DESTROY_MSG
public static final int IGNITE_BPLUS_TREE_LOCK_RETRIES_DEFAULT
protected final long metaPageId
protected BPlusTree(String name, int cacheGrpId, String cacheGrpName, PageMemory pageMem, @Nullable @Nullable IgniteWriteAheadLogManager wal, AtomicLong globalRmvId, long metaPageId, @Nullable @Nullable ReuseList reuseList, IOVersions<? extends BPlusInnerIO<L>> innerIos, IOVersions<? extends BPlusLeafIO<L>> leafIos, byte pageFlag, @Nullable @Nullable FailureProcessor failureProcessor, PageLockTrackerManager pageLockTrackerManager) throws IgniteCheckedException
name - Tree name.cacheGrpId - Cache group ID.cacheGrpName - Cache group name.pageMem - Page memory.wal - Write ahead log manager.globalRmvId - Remove ID.metaPageId - Meta page ID.reuseList - Reuse list.innerIos - Inner IO versions.leafIos - Leaf IO versions.pageFlag - Default flag value for allocated pages.failureProcessor - if the tree is corrupted.pageLockTrackerManager - Page lock tracker manager.IgniteCheckedException - If failed.protected BPlusTree(String name, int cacheGrpId, String grpName, PageMemory pageMem, @Nullable @Nullable IgniteWriteAheadLogManager wal, AtomicLong globalRmvId, long metaPageId, ReuseList reuseList, byte pageFlag, @Nullable @Nullable FailureProcessor failureProcessor, PageLockTrackerManager pageLockTrackerManager, PageIoResolver pageIoRslvr)
name - Tree name.cacheGrpId - Cache ID.grpName - Cache group name.pageMem - Page memory.wal - Write ahead log manager.globalRmvId - Remove ID.metaPageId - Meta page ID.reuseList - Reuse list.pageFlag - Default flag value for allocated pages.failureProcessor - if the tree is corrupted.pageLockTrackerManager - Page lock tracker manager.public void setIos(IOVersions<? extends BPlusInnerIO<L>> innerIos, IOVersions<? extends BPlusLeafIO<L>> leafIos)
innerIos - Inner IO versions.leafIos - Leaf IO versions.public void enableSequentialWriteMode()
protected final void initTree(boolean initNew)
throws IgniteCheckedException
initNew - True if new tree should be created.IgniteCheckedException - If failed.protected final void initTree(boolean initNew,
int inlineSize)
throws IgniteCheckedException
initNew - True if new tree should be created.inlineSize - Inline size.IgniteCheckedException - If failed.protected final void checkDestroyed()
throws IgniteCheckedException
IgniteCheckedExceptionpublic final GridCursor<T> find(L lower, L upper) throws IgniteCheckedException
find in interface IgniteTree<L,T extends L>lower - Lower bound or null if unbounded.upper - Upper bound or null if unbounded.IgniteCheckedException - If failed.public final GridCursor<T> find(L lower, L upper, Object x) throws IgniteCheckedException
find in interface IgniteTree<L,T extends L>lower - Lower bound or null if unbounded.upper - Upper bound or null if unbounded.x - Implementation specific argument, null always means that we need to return full detached
data row.IgniteCheckedException - If failed.public GridCursor<T> find(L lower, L upper, BPlusTree.TreeRowClosure<L,T> c, Object x) throws IgniteCheckedException
lower - Lower bound inclusive or null if unbounded.upper - Upper bound inclusive or null if unbounded.c - Filter closure.x - Implementation specific argument, null always means that we need to return full detached data row.IgniteCheckedException - If failed.public GridCursor<T> find(L lower, L upper, boolean lowIncl, boolean upIncl, BPlusTree.TreeRowClosure<L,T> c, BPlusTree.TreeRowFactory<L,T> rowFactory, Object x) throws IgniteCheckedException
lower - Lower bound or null if unbounded.upper - Upper bound or null if unbounded.lowIncl - true if lower bound is inclusive.upIncl - true if upper bound is inclusive.c - Filter closure.rowFactory - Row factory or (@code null} for default factory.x - Implementation specific argument, null always means that we need to return full detached data row.IgniteCheckedException - If failed.public void iterate(L lower, L upper, BPlusTree.TreeRowClosure<L,T> c) throws IgniteCheckedException
lower - Lower bound inclusive.upper - Upper bound inclusive.c - Closure applied for all found items, iteration is stopped if closure returns false.IgniteCheckedException - If failed.public void visit(L lower, L upper, BPlusTree.TreeVisitorClosure<L,T> c) throws IgniteCheckedException
lower - Lower bound inclusive.upper - Upper bound inclusive.c - Closure applied for all found items.IgniteCheckedException - If failed.public T findFirst() throws IgniteCheckedException
null if tree is emptyfindFirst in interface IgniteTree<L,T extends L>IgniteCheckedException - If failed.public T findFirst(BPlusTree.TreeRowClosure<L,T> filter) throws IgniteCheckedException
null if tree is empty or no entry matches the passed filter.filter - Filter closure.IgniteCheckedException - If failed.public T findLast() throws IgniteCheckedException
null if tree is emptyfindLast in interface IgniteTree<L,T extends L>IgniteCheckedException - If failed.public T findLast(BPlusTree.TreeRowClosure<L,T> c) throws IgniteCheckedException
null if tree is empty or no entry matches the passed filter.c - Filter closure.IgniteCheckedException - If failed.public final <R> R findOne(L row, Object x) throws IgniteCheckedException
row - Lookup row for exact match.x - Implementation specific argument, null always means that we need to return full detached data row.nullIgniteCheckedException - If failed.public final <R> R findOne(L row, BPlusTree.TreeRowClosure<L,T> c, Object x) throws IgniteCheckedException
row - Lookup row for exact match.x - Implementation specific argument, null always means that we need to return full detached data row.null.IgniteCheckedException - If failed.public final T findOne(L row) throws IgniteCheckedException
IgniteTreenull if this tree contains no mapping for the
key.findOne in interface IgniteTree<L,T extends L>row - Lookup row for exact match.IgniteCheckedException - If failed.public static String treeName(String instance, String type)
instance - Instance name.type - Tree type.public final String printTree() throws IgniteCheckedException
String.IgniteCheckedException - If failed.public final void validateTree()
throws IgniteCheckedException
IgniteCheckedException - If failed.public static void interruptAll()
public final T remove(L row) throws IgniteCheckedException
IgniteTreeremove in interface IgniteTree<L,T extends L>row - Lookup row.IgniteCheckedException - If failed.public final boolean removex(L row) throws IgniteCheckedException
row - Lookup row.True if removed row.IgniteCheckedException - If failed.public List<L> remove(L lower, L upper, int limit) throws IgniteCheckedException
lower - Lower bound (inclusive).upper - Upper bound (inclusive).limit - Limit of processed entries by single call, 0 for no limit.IgniteCheckedException - If failed.public void invoke(L row, Object z, IgniteTree.InvokeClosure<T> c) throws IgniteCheckedException
invoke in interface IgniteTree<L,T extends L>row - Key.z - Implementation specific argument, null always means that we need a full detached data row.c - Closure.IgniteCheckedException - If failed.public final int rootLevel()
throws IgniteCheckedException
IgniteCheckedException - If failed.public final boolean isEmpty()
throws IgniteCheckedException
True in case the tree is empty.IgniteCheckedException - If failed.public final long size()
throws IgniteCheckedException
size in interface IgniteTree<L,T extends L>IgniteCheckedException - If failed.public long size(@Nullable
@Nullable BPlusTree.TreeRowClosure<L,T> filter)
throws IgniteCheckedException
filter - The filter to use or null to count all elements.IgniteCheckedException - If failed.public final T put(T row) throws IgniteCheckedException
put in interface IgniteTree<L,T extends L>row - Value to be associated with the specified key.IgniteCheckedException - If failed.public boolean putx(T row) throws IgniteCheckedException
row - New value.True if replaced existing row.IgniteCheckedException - If failed.protected void temporaryReleaseLock()
protected long maxLockHoldTime()
temporaryReleaseLock() is called and hold time is reset.public final long destroy()
throws IgniteCheckedException
0, otherwise it should return at least 2 (for meta page and root page), unless this tree is
used as metadata storage, or -1 if we don't have a reuse list and did not do recycling at all.IgniteCheckedException - If failed.public final long destroy(@Nullable
@Nullable IgniteInClosure<L> c,
boolean forceDestroy)
throws IgniteCheckedException
c - Visitor closure. Visits only leaf pages.forceDestroy - Whether to proceed with destroying, even if tree is already marked as destroyed (see
markDestroyed()).0, otherwise it should return at least 2 (for meta page and root page), unless this tree is
used as metadata storage, or -1 if we don't have a reuse list and did not do recycling at all.IgniteCheckedException - If failed.protected long destroyDownPages(LongListReuseBag bag, long pageId, int lvl, @Nullable @Nullable IgniteInClosure<L> c, AtomicLong lockHoldStartTime, long lockMaxTime, Deque<GridTuple3<Long,Long,Long>> lockedPages) throws IgniteCheckedException
pageId
and root level as lvl.bag - Reuse bag.pageId - Page id.lvl - Current level of tree.c - Visitor closure. Visits only leaf pages.lockHoldStartTime - When lock has been aquired last time.lockMaxTime - Maximum time to hold the lock.lockedPages - Deque of locked pages. Is used to release write-locked pages when temporary releasing
checkpoint read lock.IgniteCheckedException - If failed.public boolean markDestroyed()
True if state was changed.public boolean destroyed()
True if marked as destroyed.protected Iterable<Long> getFirstPageIds(long pageAddr)
pageAddr - Meta page address.public final BPlusInnerIO<L> latestInnerIO()
public final BPlusLeafIO<L> latestLeafIO()
protected abstract int compare(BPlusIO<L> io, long pageAddr, int idx, L row) throws IgniteCheckedException
io - IO.pageAddr - Page address.idx - Index of row in the given buffer.row - Lookup row.Comparator.compare(Object, Object).IgniteCheckedException - If failed.protected int compare(int lvl,
BPlusIO<L> io,
long pageAddr,
int idx,
L row)
throws IgniteCheckedException
lvl - Level.io - IO.pageAddr - Page address.idx - Index of row in the given buffer.row - Lookup row.Comparator.compare(Object, Object).IgniteCheckedException - If failed.public final T getRow(BPlusIO<L> io, long pageAddr, int idx) throws IgniteCheckedException
io - IO.pageAddr - Page address.idx - Index.IgniteCheckedException - If failed.public abstract T getRow(BPlusIO<L> io, long pageAddr, int idx, Object x) throws IgniteCheckedException
canGetRowFromInner is true.io - IO.pageAddr - Page address.idx - Index.x - Implementation specific argument, null always means that we need to return full detached data row.IgniteCheckedException - If failed.protected int getLockRetries()
protected final long acquirePage(long pageId)
throws IgniteCheckedException
pageId - Page ID.IgniteCheckedException - If failed.protected final <X,R> R read(long pageId,
PageHandler<X,R> h,
X arg,
int intArg,
R lockFailed)
throws IgniteCheckedException
pageId - Page ID.h - Handler.arg - Argument.intArg - Argument of type int.lockFailed - Result in case of lock failure due to page recycling.IgniteCheckedException - If failed.protected final <X,R> R read(long pageId,
long page,
PageHandler<X,R> h,
X arg,
int intArg,
R lockFailed)
throws IgniteCheckedException
pageId - Page ID.page - Page pointer.h - Handler.arg - Argument.intArg - Argument of type int.lockFailed - Result in case of lock failure due to page recycling.IgniteCheckedException - If failed.protected IoStatisticsHolder statisticsHolder()
protected CorruptedTreeException corruptedTreeException(String msg, Throwable cause, int grpId, long... pageIds)
msg - Message.cause - Cause.grpId - Group id.pageIds - Pages ids.protected void processFailure(FailureType failureType, Throwable e)
failureType - Failure type.e - Exception.public long getMetaPageId()
Follow @ApacheIgnite
Ignite Database and Caching Platform : ver. 2.15.0 Release Date : April 25 2023