#include <BTreeNodeAccessor.h>
Inheritance diagram for BTreeNodeAccessor:
Public Types | |
enum | Capacity { CAN_FIT, CAN_FIT_WITH_COMPACTION, CAN_NOT_FIT } |
Enumeration used to classify the storage state of a node which is targeted for insertion. More... | |
Public Member Functions | |
virtual | ~BTreeNodeAccessor () |
uint | getKeyCount (BTreeNode const &node) const |
Gets the number of keys stored on a node. | |
virtual void | clearNode (BTreeNode &node, uint cbPage) |
Clears the contents of a node, converting it to an empty root. | |
virtual PBuffer | allocateEntry (BTreeNode &node, uint iEntry, uint cbEntry)=0 |
Allocates space for a new tuple. | |
virtual void | deallocateEntry (BTreeNode &node, uint iEntry)=0 |
Deallocates the space for an existing tuple. | |
virtual PConstBuffer | getEntryForRead (BTreeNode const &node, uint iEntry)=0 |
Gets the location of a stored tuple. | |
virtual void | onInit () |
Receives notification from BTreeAccessBase after tupleDescriptor has been set up. | |
void | dumpNode (std::ostream &os, BTreeNode const &node, PageId pageId) |
Dumps the contents of a node. | |
virtual bool | hasFixedWidthEntries () const=0 |
| |
virtual void | accessTuple (BTreeNode const &node, uint iEntry)=0 |
Binds tupleAccessor to a stored tuple. | |
virtual uint | binarySearch (BTreeNode const &node, TupleDescriptor const &keyDescriptor, TupleData const &searchKey, DuplicateSeek dupSeek, bool leastUpper, TupleData &scratchKey, bool &found)=0 |
Searches for a tuple based on a key. | |
virtual int | compareFirstKey (BTreeNode const &node, TupleDescriptor const &keyDescriptor, TupleData const &searchKey, TupleData &scratchKey)=0 |
Compare first key on a node to provided search key. | |
virtual void | accessTupleInline (BTreeNode const &node, uint iEntry)=0 |
Sets tuple accessor to provided node entry. | |
virtual Capacity | calculateCapacity (BTreeNode const &node, uint cbEntry)=0 |
Determines whether a tuple can be inserted into a node. | |
virtual uint | getEntryByteCount (uint cbTuple)=0 |
Determines the storage required for a tuple, including any overhead. | |
virtual void | unmarshalKey (TupleData &keyData)=0 |
Unmarshals the key for the current tuple after a call to accessTuple. | |
virtual void | compactNode (BTreeNode &node, BTreeNode &scratchNode) |
Performs compaction on a node. | |
virtual void | splitNode (BTreeNode &node, BTreeNode &newNode, uint cbNewTuple, bool monotonic) |
Splits a node. | |
Public Attributes | |
TupleDescriptor | tupleDescriptor |
Descriptor for tuples stored on nodes accessed by this. | |
TupleAccessor | tupleAccessor |
Accessor for tuples stored on nodes accessed by this. | |
TupleData | tupleData |
TupleData for tuples stored on nodes accessed by this. |
Derived classes fill in the implementation details.
The general idea is that low-level management of node data is orthogonal to high-level BTree algorithms, so it should be easy to plug in new node representations (fixed-width, variable-width, compressed, etc.). An alternate way of expressing this would be to define all of the high-level BTree classes as templates, with BTreeNodeAccessor as a template parameter. This would give the ultimate efficiency, but at the price of code bloat (number of high-level classes times number of BTreeNodeAccessor implementations) and higher complexity. A virtual interface was chosen instead, but still with performance in mind (e.g. the binarySearch method is delegated to BTreeNodeAccessor so that all tuple access within one node search can be computed inline).
Definition at line 54 of file BTreeNodeAccessor.h.
Enumeration used to classify the storage state of a node which is targeted for insertion.
CAN_FIT | The tuple can fit without compaction. |
CAN_FIT_WITH_COMPACTION | The tuple can fit, but only after compaction. |
CAN_NOT_FIT |
The tuple can't fit.
Compaction wouldn't help. |
Definition at line 238 of file BTreeNodeAccessor.h.
00238 { 00242 CAN_FIT, 00246 CAN_FIT_WITH_COMPACTION, 00247 00251 CAN_NOT_FIT 00252 };
BTreeNodeAccessor::~BTreeNodeAccessor | ( | ) | [virtual] |
Gets the number of keys stored on a node.
This may be one less than the number of tuples, since in the rightmost node on a non-leaf level, we pretend the last key is +infinity, so the actual stored key is ignored. But the last tuple is still stored, and its child PageId is used.
node | the node to access |
Definition at line 308 of file BTreeNodeAccessor.h.
References BTreeNode::height, BTreeNode::nEntries, NULL_PAGE_ID, and BTreeNode::rightSibling.
Referenced by BTreeWriter::lockParentPage(), BTreeWriter::splitCurrentNode(), and BTreeVerifier::verifyNode().
00309 { 00310 if (node.height && (node.rightSibling == NULL_PAGE_ID)) { 00311 // For non-leaf nodes on the rightmost fringe, we pretend the last 00312 // key is +infinity, and ignore whatever's actually stored 00313 // there (except for its child PageId). 00314 assert(node.nEntries); 00315 return node.nEntries - 1; 00316 } 00317 return node.nEntries; 00318 }
Clears the contents of a node, converting it to an empty root.
node | the node to clear | |
cbPage | number of usable bytes per page in segment storing BTree |
Reimplemented in BTreeHeapNodeAccessor.
Definition at line 34 of file BTreeNodeAccessor.cpp.
References BTreeNode::cbCompactFree, BTreeNode::cbTotalFree, BTreeNode::height, MAXU, BTreeNode::nEntries, NULL_PAGE_ID, and BTreeNode::rightSibling.
Referenced by BTreeBuildLevel::allocatePage(), BTreeBuilder::buildBalanced(), BTreeHeapNodeAccessor::clearNode(), BTreeWriter::compactNode(), BTreeWriter::grow(), and BTreeWriter::splitCurrentNode().
00035 { 00036 node.rightSibling = NULL_PAGE_ID; 00037 node.nEntries = 0; 00038 node.height = 0; 00039 node.cbTotalFree = cbPage - sizeof(BTreeNode); 00040 node.cbCompactFree = MAXU; 00041 }
virtual PBuffer BTreeNodeAccessor::allocateEntry | ( | BTreeNode & | node, | |
uint | iEntry, | |||
uint | cbEntry | |||
) | [pure virtual] |
Allocates space for a new tuple.
node | the node in which the tuple will be stored | |
iEntry | 0-based index at which tuple will be stored | |
cbEntry | number of bytes in stored tuple |
Implemented in BTreeCompactNodeAccessor, and BTreeHeapNodeAccessor.
Referenced by BTreeWriter::attemptInsertWithoutSplit(), compactNode(), BTreeWriter::grow(), BTreeBuildLevel::indexLastChild(), BTreeBuildLevel::processInput(), splitNode(), and BTreeWriter::updateCurrent().
Deallocates the space for an existing tuple.
node | the node from which to deallocate the tuple | |
iEntry | 0-based index of tuple to be deallocated |
Implemented in BTreeCompactNodeAccessor, and BTreeHeapNodeAccessor.
Referenced by BTreeWriter::deleteCurrent(), and BTreeWriter::updateCurrent().
virtual PConstBuffer BTreeNodeAccessor::getEntryForRead | ( | BTreeNode const & | node, | |
uint | iEntry | |||
) | [pure virtual] |
Gets the location of a stored tuple.
node | the node to access | |
iEntry | 0-based index of tuple to access |
Referenced by dumpNode(), BTreeWriter::splitCurrentNode(), and BTreeWriter::updateCurrent().
void BTreeNodeAccessor::onInit | ( | ) | [virtual] |
Receives notification from BTreeAccessBase after tupleDescriptor has been set up.
Reimplemented in BTreeCompactNodeAccessor.
Definition at line 43 of file BTreeNodeAccessor.cpp.
References TupleData::compute(), TupleAccessor::compute(), tupleAccessor, tupleData, and tupleDescriptor.
Referenced by BTreeCompactNodeAccessor::onInit().
00044 { 00045 tupleAccessor.compute(tupleDescriptor); 00046 tupleData.compute(tupleDescriptor); 00047 }
void BTreeNodeAccessor::dumpNode | ( | std::ostream & | os, | |
BTreeNode const & | node, | |||
PageId | pageId | |||
) |
Dumps the contents of a node.
os | output stream receiving the dump | |
node | the node to dump | |
pageId | PageId of the node being dumped |
Definition at line 49 of file BTreeNodeAccessor.cpp.
References BTreeNode::cbCompactFree, BTreeNode::cbTotalFree, getEntryForRead(), BTreeNode::height, isMAXU(), BTreeNode::nEntries, NULL_PAGE_ID, TuplePrinter::print(), BTreeNode::rightSibling, TupleAccessor::setCurrentTupleBuf(), tupleAccessor, tupleData, tupleDescriptor, and TupleAccessor::unmarshal().
Referenced by BTreeWriter::attemptInsertWithoutSplit(), BTreeWriter::grow(), BTreeWriter::splitCurrentNode(), and BTreeVerifier::verifyNode().
00051 { 00052 os << "PageId: " << pageId << std::endl; 00053 if (node.rightSibling == NULL_PAGE_ID) { 00054 os << "rightSibling: <null>" << std::endl; 00055 } else { 00056 os << "rightSibling: " << node.rightSibling << std::endl; 00057 } 00058 os << "nEntries: " << node.nEntries << std::endl; 00059 os << "height: " << node.height << std::endl; 00060 os << "cbTotalFree: " << node.cbTotalFree << std::endl; 00061 if (!isMAXU(node.cbCompactFree)) { 00062 os << "cbCompactFree: " << node.cbCompactFree << std::endl; 00063 } 00064 os << std::endl; 00065 TuplePrinter tuplePrinter; 00066 // TODO: print "+infinity" for last key on right fringe 00067 for (uint i = 0; i < node.nEntries; ++i) { 00068 PConstBuffer pEntry = getEntryForRead(node,i); 00069 os << "offset = " 00070 << pEntry - reinterpret_cast<PConstBuffer>(&node) << std::endl; 00071 tupleAccessor.setCurrentTupleBuf(pEntry); 00072 tupleAccessor.unmarshal(tupleData); 00073 tuplePrinter.print(os,tupleDescriptor,tupleData); 00074 os << std::endl; 00075 } 00076 os << std::endl; 00077 }
virtual bool BTreeNodeAccessor::hasFixedWidthEntries | ( | ) | const [pure virtual] |
Implemented in BTreeCompactNodeAccessor, and BTreeHeapNodeAccessor.
Referenced by BTreeBuilder::buildTwoPass(), and BTreeWriter::updateCurrent().
Binds tupleAccessor to a stored tuple.
node | the node to access | |
iEntry | 0-based index of tuple to access |
Referenced by BTreeReader::accessLeafTuple(), compactNode(), BTreeAccessBase::getChild(), BTreeWriter::grow(), BTreeWriter::lockParentPage(), BTreeWriter::splitCurrentNode(), splitNode(), BTreeBuildLevel::unmarshalLastKey(), BTreeVerifier::verifyChildren(), and BTreeVerifier::verifyNode().
virtual uint BTreeNodeAccessor::binarySearch | ( | BTreeNode const & | node, | |
TupleDescriptor const & | keyDescriptor, | |||
TupleData const & | searchKey, | |||
DuplicateSeek | dupSeek, | |||
bool | leastUpper, | |||
TupleData & | scratchKey, | |||
bool & | found | |||
) | [pure virtual] |
Searches for a tuple based on a key.
node | the node to search | |
keyDescriptor | key descriptor to be used for comparisons | |
searchKey | key to search for | |
dupSeek | what to do if duplicates are found | |
leastUpper | whether to position on least upper bound or greatest lower bound | |
scratchKey | key to be used as a temp variable in comparisons | |
found | same semantics as BTreeReader::binarySearch |
Referenced by BTreeReader::binarySearch(), and BTreeWriter::lockParentPage().
virtual int BTreeNodeAccessor::compareFirstKey | ( | BTreeNode const & | node, | |
TupleDescriptor const & | keyDescriptor, | |||
TupleData const & | searchKey, | |||
TupleData & | scratchKey | |||
) | [pure virtual] |
Compare first key on a node to provided search key.
node | the node to search | |
keyDescriptor | key descriptor to be used for comparisons | |
searchKey | key to search for | |
scratchKey | key to be used as a temp variable in comparison |
Referenced by BTreeReader::compareFirstKey().
virtual void BTreeNodeAccessor::accessTupleInline | ( | BTreeNode const & | node, | |
uint | iEntry | |||
) | [pure virtual] |
Sets tuple accessor to provided node entry.
node | the current node positioned on | |
iEntry | the entry within the node to set the tuple accessor to |
Referenced by BTreeReader::accessTupleInline().
virtual Capacity BTreeNodeAccessor::calculateCapacity | ( | BTreeNode const & | node, | |
uint | cbEntry | |||
) | [pure virtual] |
Determines whether a tuple can be inserted into a node.
node | the target node | |
cbEntry | the number of bytes in the tuple to be inserted |
Implemented in BTreeCompactNodeAccessor, and BTreeHeapNodeAccessor.
Referenced by BTreeWriter::attemptInsertWithoutSplit(), BTreeBuildLevel::isNodeFull(), BTreeWriter::splitCurrentNode(), and BTreeWriter::updateCurrent().
Determines the storage required for a tuple, including any overhead.
cbTuple | number of bytes without overhead |
Implemented in BTreeCompactNodeAccessor, and BTreeHeapNodeAccessor.
Referenced by splitNode().
virtual void BTreeNodeAccessor::unmarshalKey | ( | TupleData & | keyData | ) | [pure virtual] |
Unmarshals the key for the current tuple after a call to accessTuple.
keyData | receives the unmarshalled key |
Referenced by BTreeWriter::checkMonotonicity(), BTreeWriter::grow(), BTreeWriter::lockParentPage(), BTreeWriter::positionSearchKey(), BTreeWriter::splitCurrentNode(), BTreePrefetchSearchExecStream::testNonLeafInterval(), BTreeBuildLevel::unmarshalLastKey(), BTreeVerifier::verifyChildren(), and BTreeVerifier::verifyNode().
Performs compaction on a node.
node | the fragmented node to be compacted | |
scratchNode | receives a compacted copy of node |
Reimplemented in BTreeCompactNodeAccessor.
Definition at line 82 of file BTreeNodeAccessor.cpp.
References accessTuple(), allocateEntry(), BTreeNode::cbCompactFree, BTreeNode::cbTotalFree, TupleAccessor::getCurrentByteCount(), TupleAccessor::getCurrentTupleBuf(), isMAXU(), BTreeNode::nEntries, and tupleAccessor.
Referenced by BTreeWriter::compactNode().
00083 { 00084 assert(!scratchNode.nEntries); 00085 for (uint i = 0; i < node.nEntries; ++i) { 00086 accessTuple(node,i); 00087 uint cbTuple = tupleAccessor.getCurrentByteCount(); 00088 PBuffer pBuffer = allocateEntry(scratchNode,i,cbTuple); 00089 memcpy(pBuffer,tupleAccessor.getCurrentTupleBuf(),cbTuple); 00090 } 00091 00092 if (!isMAXU(node.cbCompactFree)) { 00093 node.cbCompactFree = node.cbTotalFree; 00094 } 00095 memcpy(&scratchNode,&node,sizeof(BTreeNode)); 00096 }
void BTreeNodeAccessor::splitNode | ( | BTreeNode & | node, | |
BTreeNode & | newNode, | |||
uint | cbNewTuple, | |||
bool | monotonic | |||
) | [virtual] |
Splits a node.
node | the node to be split | |
newNode | an empty node which receives half of the tuple data. | |
cbNewTuple | number of bytes which will be required to store the tuple which caused this split | |
monotonic | if true, inserts are always increasing so optimize the split accordingly |
Definition at line 104 of file BTreeNodeAccessor.cpp.
References accessTuple(), allocateEntry(), BTreeNode::cbTotalFree, TupleAccessor::getCurrentByteCount(), TupleAccessor::getCurrentTupleBuf(), getEntryByteCount(), BTreeNode::height, max(), BTreeNode::nEntries, and tupleAccessor.
Referenced by BTreeWriter::splitCurrentNode().
00108 { 00109 assert(!newNode.nEntries); 00110 assert(node.nEntries > 1); 00111 newNode.height = node.height; // split should be of the same height 00112 00113 // if monotonic, for leaf page, 00114 // don't actually split the page; leave the left 00115 // page as is and force all inserts to go into the new page 00116 // on the right 00117 // for internal node, 00118 // put the last entry to the right page. 00119 if (monotonic && node.height == 0) { 00120 return; 00121 } 00122 00123 // Calculate the balance point in bytes 00124 uint cbNeeded = getEntryByteCount(cbNewTuple); 00125 uint cbBalance = cbNeeded; 00126 if (!monotonic) { 00127 cbBalance = (node.cbTotalFree + newNode.cbTotalFree - cbNeeded) / 2; 00128 cbBalance = std::max(cbNeeded,cbBalance); 00129 } 00130 00131 // Calculate the corresponding split point in terms of tuples 00132 uint cbFreeAfterSplit = node.cbTotalFree; 00133 uint iSplitTuple = node.nEntries; 00134 while (cbFreeAfterSplit < cbBalance) { 00135 --iSplitTuple; 00136 accessTuple(node,iSplitTuple); 00137 uint cbTuple = tupleAccessor.getCurrentByteCount(); 00138 cbFreeAfterSplit += getEntryByteCount(cbTuple); 00139 } 00140 00141 // Copy tuples accordingly. 00142 for (uint i = iSplitTuple; i < node.nEntries; ++i) { 00143 accessTuple(node,i); 00144 uint cbTuple = tupleAccessor.getCurrentByteCount(); 00145 PBuffer pNewEntry = allocateEntry(newNode,newNode.nEntries,cbTuple); 00146 memcpy(pNewEntry,tupleAccessor.getCurrentTupleBuf(),cbTuple); 00147 } 00148 00149 // Truncate old node. NOTE: This isn't kosher, since it assumes too much 00150 // about data layout, but this whole method is going to go away soon 00151 // anyway. 00152 node.nEntries = iSplitTuple; 00153 node.cbTotalFree = cbFreeAfterSplit; 00154 }
Descriptor for tuples stored on nodes accessed by this.
Definition at line 60 of file BTreeNodeAccessor.h.
Referenced by dumpNode(), and onInit().
Accessor for tuples stored on nodes accessed by this.
This is used as a scratch variable in a variety of contexts, so reference with caution.
Definition at line 66 of file BTreeNodeAccessor.h.
Referenced by BTreeWriter::checkMonotonicity(), compactNode(), BTreeHeapNodeAccessor::deallocateEntry(), BTreeWriter::deleteCurrent(), dumpNode(), BTreeWriter::grow(), BTreeHeapNodeAccessor::hasFixedWidthEntries(), BTreeBuildLevel::indexLastChild(), VariableBuildLevel::indexLastKey(), BTreeWriter::insertTupleFromBuffer(), onInit(), BTreeCompactNodeAccessor::onInit(), BTreeBuildLevel::processInput(), BTreeWriter::splitCurrentNode(), splitNode(), and BTreeWriter::updateCurrent().
TupleData for tuples stored on nodes accessed by this.
This is used as a scratch variable in a variety of contexts, so reference with caution.
Definition at line 72 of file BTreeNodeAccessor.h.
Referenced by dumpNode(), BTreeWriter::grow(), BTreeBuildLevel::indexLastChild(), VariableBuildLevel::indexLastKey(), BTreeWriter::lockParentPage(), onInit(), and BTreeWriter::splitCurrentNode().