template<class BtreeLayout>
class mongo::BtreeLogic< BtreeLayout >
This is the logic for manipulating the Btree.
It is (mostly) independent of the on-disk format.
|
| BtreeLogic (HeadManager *head, RecordStore *store, SavedCursorRegistry *cursors, const Ordering &ordering, const std::string &indexName, bool isUnique) |
| 'head' manages the catalog information. More...
|
|
Builder * | newBuilder (OperationContext *opCtx, bool dupsAllowed) |
| Caller owns the returned pointer. More...
|
|
Status | dupKeyCheck (OperationContext *opCtx, const BSONObj &key, const DiskLoc &loc) const |
|
Status | insert (OperationContext *opCtx, const BSONObj &rawKey, const DiskLoc &value, bool dupsAllowed) |
|
bool | locate (OperationContext *opCtx, const BSONObj &key, const DiskLoc &recordLoc, const int direction, int *posOut, DiskLoc *bucketLocOut) const |
| Navigates down the tree and locates the bucket and position containing a record with the specified <key, recordLoc> combination. More...
|
|
void | advance (OperationContext *opCtx, DiskLoc *bucketLocInOut, int *posInOut, int direction) const |
|
bool | exists (OperationContext *opCtx, const KeyDataType &key) const |
|
bool | unindex (OperationContext *opCtx, const BSONObj &key, const DiskLoc &recordLoc) |
|
bool | isEmpty (OperationContext *opCtx) const |
|
long long | fullValidate (OperationContext *, long long *unusedCount, bool strict, bool dumpBuckets, unsigned depth) const |
|
DiskLoc | getDiskLoc (OperationContext *opCtx, const DiskLoc &bucketLoc, const int keyOffset) const |
|
BSONObj | getKey (OperationContext *opCtx, const DiskLoc &bucketLoc, const int keyOffset) const |
|
IndexKeyEntry | getRandomEntry (OperationContext *opCtx) const |
| Returns a pseudo-random element from the tree. More...
|
|
DiskLoc | getHead (OperationContext *opCtx) const |
|
Status | touch (OperationContext *opCtx) const |
|
void | customLocate (OperationContext *opCtx, DiskLoc *locInOut, int *keyOfsInOut, const IndexSeekPoint &seekPoint, int direction) const |
|
void | advanceTo (OperationContext *, DiskLoc *thisLocInOut, int *keyOfsInOut, const IndexSeekPoint &seekPoint, int direction) const |
|
void | restorePosition (OperationContext *opCtx, const BSONObj &savedKey, const DiskLoc &savedLoc, int direction, DiskLoc *bucketInOut, int *keyOffsetInOut) const |
|
Status | initAsEmpty (OperationContext *opCtx) |
| Returns OK if the index was uninitialized before, error status otherwise. More...
|
|
const RecordStore * | getRecordStore () const |
|
SavedCursorRegistry * | savedCursors () const |
|
Ordering | ordering () const |
|
int | customBSONCmp (const BSONObj &inIndex_left, const IndexSeekPoint &seekPoint_right, int direction) const |
| NOTE: Currently the Ordering implementation assumes a compound index will not have more keys than an unsigned variable has bits. More...
|
|
bool | isUnique () const |
|
|
bool | basicInsert (OperationContext *opCtx, BucketType *bucket, const DiskLoc bucketLoc, int &keypos, const KeyDataType &key, const DiskLoc recordLoc) |
| Durability note: More...
|
|
void | dropFront (BucketType *bucket, int nDrop, int &refpos) |
|
void | _pack (OperationContext *opCtx, BucketType *bucket, const DiskLoc thisLoc, int &refPos) |
| When we delete things, we just leave empty space until the node is full and then we repack it. More...
|
|
void | customLocate (OperationContext *opCtx, DiskLoc *locInOut, int *keyOfsInOut, const IndexSeekPoint &seekPoint, int direction, std::pair< DiskLoc, int > &bestParent) const |
|
Status | _find (OperationContext *opCtx, BucketType *bucket, const KeyDataType &key, const DiskLoc &recordLoc, bool errorIfDup, int *keyPositionOut, bool *foundOut) const |
| Find a key within this btree bucket. More...
|
|
bool | customFind (OperationContext *opCtx, int low, int high, const IndexSeekPoint &seekPoint, int direction, DiskLoc *thisLocInOut, int *keyOfsInOut, std::pair< DiskLoc, int > &bestParent) const |
|
void | advanceToImpl (OperationContext *opCtx, DiskLoc *thisLocInOut, int *keyOfsInOut, const IndexSeekPoint &seekPoint, int direction) const |
| find smallest/biggest value greater-equal/less-equal than specified More...
|
|
bool | wouldCreateDup (OperationContext *opCtx, const KeyDataType &key, const DiskLoc self) const |
|
bool | keyIsUsed (OperationContext *opCtx, const DiskLoc &loc, const int &pos) const |
|
void | skipUnusedKeys (OperationContext *opCtx, DiskLoc *loc, int *pos, int direction) const |
|
DiskLoc | advance (OperationContext *opCtx, const DiskLoc &bucketLoc, int *posInOut, int direction) const |
|
DiskLoc | _locate (OperationContext *opCtx, const DiskLoc &bucketLoc, const KeyDataType &key, int *posOut, bool *foundOut, const DiskLoc &recordLoc, const int direction) const |
| Recursively walk down the btree, looking for a match of key and recordLoc. More...
|
|
long long | _fullValidate (OperationContext *opCtx, const DiskLoc bucketLoc, long long *unusedCount, bool strict, bool dumpBuckets, unsigned depth) const |
|
DiskLoc | _addBucket (OperationContext *opCtx) |
|
bool | canMergeChildren (OperationContext *opCtx, BucketType *bucket, const DiskLoc bucketLoc, const int leftIndex) |
|
int | _rebalancedSeparatorPos (OperationContext *opCtx, BucketType *bucket, int leftIndex) |
| This implementation must respect the meaning and value of lowWaterMark. More...
|
|
void | _packReadyForMod (BucketType *bucket, int &refPos) |
| Version when write intent already declared. More...
|
|
void | truncateTo (BucketType *bucket, int N, int &refPos) |
|
void | split (OperationContext *opCtx, BucketType *bucket, const DiskLoc bucketLoc, int keypos, const DiskLoc recordLoc, const KeyDataType &key, const DiskLoc lchild, const DiskLoc rchild) |
|
Status | _insert (OperationContext *opCtx, BucketType *bucket, const DiskLoc bucketLoc, const KeyDataType &key, const DiskLoc recordLoc, bool dupsAllowed, const DiskLoc leftChild, const DiskLoc rightChild) |
|
void | insertHere (OperationContext *opCtx, const DiskLoc bucketLoc, int pos, const KeyDataType &key, const DiskLoc recordLoc, const DiskLoc leftChild, const DiskLoc rightChild) |
| insert a key in this bucket, splitting if necessary. More...
|
|
std::string | dupKeyError (const KeyDataType &key) const |
|
void | setInternalKey (OperationContext *opCtx, BucketType *bucket, const DiskLoc bucketLoc, int keypos, const DiskLoc recordLoc, const KeyDataType &key, const DiskLoc lchild, const DiskLoc rchild) |
|
void | fixParentPtrs (OperationContext *trans, BucketType *bucket, const DiskLoc bucketLoc, int firstIndex=0, int lastIndex=-1) |
| This can cause a lot of additional page writes when we assign buckets to different parents. More...
|
|
bool | mayBalanceWithNeighbors (OperationContext *opCtx, BucketType *bucket, const DiskLoc bucketLoc) |
|
void | doBalanceChildren (OperationContext *opCtx, BucketType *bucket, const DiskLoc bucketLoc, int leftIndex) |
|
void | doBalanceLeftToRight (OperationContext *opCtx, BucketType *bucket, const DiskLoc thisLoc, int leftIndex, int split, BucketType *l, const DiskLoc lchild, BucketType *r, const DiskLoc rchild) |
|
void | doBalanceRightToLeft (OperationContext *opCtx, BucketType *bucket, const DiskLoc thisLoc, int leftIndex, int split, BucketType *l, const DiskLoc lchild, BucketType *r, const DiskLoc rchild) |
|
bool | tryBalanceChildren (OperationContext *opCtx, BucketType *bucket, const DiskLoc bucketLoc, int leftIndex) |
|
int | indexInParent (OperationContext *opCtx, BucketType *bucket, const DiskLoc bucketLoc) const |
|
void | doMergeChildren (OperationContext *opCtx, BucketType *bucket, const DiskLoc bucketLoc, int leftIndex) |
|
void | replaceWithNextChild (OperationContext *opCtx, BucketType *bucket, const DiskLoc bucketLoc) |
|
void | deleteInternalKey (OperationContext *opCtx, BucketType *bucket, const DiskLoc bucketLoc, int keypos) |
| This function replaces the specified key (k) by either the prev or next key in the btree (k'). More...
|
|
void | delKeyAtPos (OperationContext *opCtx, BucketType *bucket, const DiskLoc bucketLoc, int p) |
| May delete the bucket 'bucket' rendering 'bucketLoc' invalid. More...
|
|
void | delBucket (OperationContext *opCtx, BucketType *bucket, const DiskLoc bucketLoc) |
|
void | deallocBucket (OperationContext *opCtx, BucketType *bucket, const DiskLoc bucketLoc) |
|
bool | _keyIsAt (const BSONObj &savedKey, const DiskLoc &savedLoc, BucketType *bucket, int keyPos) const |
|
bool | pushBack (BucketType *bucket, const DiskLoc recordLoc, const KeyDataType &key, const DiskLoc prevChild) |
| Tries to push key into bucket. More...
|
|
BucketType * | childForPos (OperationContext *opCtx, BucketType *bucket, int pos) const |
|
BucketType * | getBucket (OperationContext *opCtx, const DiskLoc dl) const |
|
BucketType * | getBucket (OperationContext *opCtx, const RecordId dl) const |
|
BucketType * | getRoot (OperationContext *opCtx) const |
|
DiskLoc | getRootLoc (OperationContext *opCtx) const |
|
void | recordRandomWalk (OperationContext *opCtx, PseudoRandom *prng, BucketType *curBucket, int64_t nBucketsInCurrentLevel, std::vector< int64_t > *nKeysInLevel, std::vector< FullKey > *selectedKeys) const |
| Does a random walk through the tree, recording information about the walk along the way. More...
|
|
|
static LocType & | childLocForPos (BucketType *bucket, int pos) |
|
static FullKey | getFullKey (const BucketType *bucket, int i) |
|
static KeyHeaderType & | getKeyHeader (BucketType *bucket, int i) |
|
static const KeyHeaderType & | getKeyHeader (const BucketType *bucket, int i) |
|
static char * | dataAt (BucketType *bucket, short ofs) |
|
static void | markUnused (BucketType *bucket, int keypos) |
|
static int | totalDataSize (BucketType *bucket) |
|
static void | init (BucketType *bucket) |
|
static int | _alloc (BucketType *bucket, int bytes) |
| We allocate space from the end of the buffer for data. More...
|
|
static void | _unalloc (BucketType *bucket, int bytes) |
|
static void | _delKeyAtPos (BucketType *bucket, int keypos, bool mayEmpty=false) |
|
static void | popBack (BucketType *bucket, DiskLoc *recordLocOut, KeyDataType *keyDataOut) |
| Pull rightmost key from the bucket and set its prevChild pointer to be the nextChild for the whole bucket. More...
|
|
static bool | mayDropKey (BucketType *bucket, int index, int refPos) |
| With this implementation, refPos == 0 disregards effect of refPos. More...
|
|
static int | _packedDataSize (BucketType *bucket, int refPos) |
|
static void | setPacked (BucketType *bucket) |
|
static void | setNotPacked (BucketType *bucket) |
|
static BucketType * | btreemod (OperationContext *opCtx, BucketType *bucket) |
|
static int | splitPos (BucketType *bucket, int keypos) |
| In the standard btree algorithm, we would split based on the existing keys and the new key. More...
|
|
static void | reserveKeysFront (BucketType *bucket, int nAdd) |
|
static void | setKey (BucketType *bucket, int i, const DiskLoc recordLoc, const KeyDataType &key, const DiskLoc prevChildBucket) |
|
static bool | isHead (BucketType *bucket) |
|
static void | dumpBucket (const BucketType *bucket, int indentLength=0) |
|
static void | assertValid (const std::string &ns, BucketType *bucket, const Ordering &ordering, bool force=false) |
|
template<class BtreeLayout >
This function replaces the specified key (k) by either the prev or next key in the btree (k').
We require that k have either a left or right child. If k has a left child, we set k' to the prev key of k, which must be a leaf present in the left child. If k does not have a left child, we set k' to the next key of k, which must be a leaf present in the right child. When we replace k with k', we copy k' over k (which may cause a split) and then remove k' from its original location. Because k' is stored in a descendent of k, replacing k by k' will not modify the storage location of the original k', and we can easily remove k' from its original location.
This function is only needed in cases where k has a left or right child; in other cases a simpler key removal implementation is possible.
NOTE on noncompliant BtreeBuilder btrees: It is possible (though likely rare) for btrees created by BtreeBuilder to have k' that is not a leaf, see SERVER-2732. These cases are handled in the same manner as described in the "legacy btree structures" note below.
NOTE on legacy btree structures: In legacy btrees, k' can be a nonleaf. In such a case we 'delete' k by marking it as an unused node rather than replacing it with k'. Also, k' may be a leaf but marked as an unused node. In such a case we replace k by k', preserving the key's unused marking. This function is only expected to mark a key as unused when handling a legacy btree.