#include <BTreeBuilder.h>
Inheritance diagram for BTreeBuilder:
Public Member Functions | |
BTreeBuilder (BTreeDescriptor const &descriptor, SharedSegment pTempSegment=SharedSegment()) | |
Creates a new BTreeBuilder. | |
virtual | ~BTreeBuilder () |
void | build (ByteInputStream &sortedStream, RecordNum nEntries, double fillFactor=1.0) |
Builds the tree, which must be currently empty or non-existent. | |
void | createEmptyRoot () |
Creates an empty tree (just a root node with no tuples). | |
void | truncate (bool rootless, TupleProjection const *pLeafPageIdProj=NULL) |
Truncates or drops an existing tree. | |
SharedSegment | getSegment () const |
| |
SharedCacheAccessor | getCacheAccessor () const |
| |
PageId | getRootPageId () const |
| |
void | setRootPageId (PageId rootPageId) |
Updates the BTree's root PageId. | |
SegmentId | getSegmentId () const |
| |
PageOwnerId | getPageOwnerId () const |
| |
TupleDescriptor const & | getTupleDescriptor () const |
| |
TupleDescriptor const & | getKeyDescriptor () const |
| |
TupleProjection const & | getKeyProjection () const |
| |
void | validateTupleSize (TupleAccessor const &tupleAccessor) |
Validates that a particular tuple can fit in this BTree, throwing a TupleOverflowExcn if not. | |
Protected Member Functions | |
BTreeNodeAccessor & | getLeafNodeAccessor (BTreeNode const &node) |
Gets the node accessor for a leaf node, asserting that the node really is a leaf. | |
BTreeNodeAccessor & | getNonLeafNodeAccessor (BTreeNode const &node) |
Gets the node accessor for a non-leaf node, asserting that the node really is a non-leaf. | |
BTreeNodeAccessor & | getNodeAccessor (BTreeNode const &node) |
Gets the node accessor for any node, using the node height to determine whether it's a leaf or not. | |
PageId | getChildForCurrent () |
Gets the child PageId corresponding to the current key in a non-leaf node. | |
PageId | getChild (BTreeNode const &node, uint iChild) |
Accesses a non-leaf tuple and gets its child PageId. | |
PageId | getRightSibling (PageId pageId) |
Gets the right sibling of a node by consulting the containing segment's successor information. | |
void | setRightSibling (BTreeNode &leftNode, PageId leftPageId, PageId rightPageId) |
Sets the right sibling of a node. | |
PageId | getFirstChild (PageId pageId) |
Gets the first child of a non-leaf node. | |
Protected Attributes | |
BTreeDescriptor | treeDescriptor |
Descriptor for tree being accessed. | |
TupleDescriptor | keyDescriptor |
Descriptor for pure keys (common across leaf and non-leaf tuples). | |
AttributeAccessor const * | pChildAccessor |
Accessor for the attribute of non-leaf tuples which stores the child PageId. | |
TupleProjectionAccessor | leafKeyAccessor |
Accessor for keys of tuples stored in leaves. | |
boost::scoped_ptr< BTreeNodeAccessor > | pNonLeafNodeAccessor |
Accessor for non-leaf nodes. | |
boost::scoped_ptr< BTreeNodeAccessor > | pLeafNodeAccessor |
Accessor for leaf nodes. | |
uint | cbTupleMax |
Maximum size for a leaf-level tuple. | |
Private Member Functions | |
uint | getRootHeight () |
void | buildBalanced (ByteInputStream &sortedStream, uint iInputLevel, RecordNum nEntriesTotal, double fillFactor) |
void | buildTwoPass (ByteInputStream &sortedStream, RecordNum nEntries, double fillFactor) |
void | buildUnbalanced (ByteInputStream &sortedStream, RecordNum nEntries, double fillFactor) |
void | processInput (ByteInputStream &sortedStream) |
BTreeBuildLevel & | getLevel (uint i) |
void | growTree () |
void | swapRoot () |
void | truncateChildren (BTreeNode const &node) |
void | truncateExternal (TupleProjection const &leafPageIdProj) |
Static Private Member Functions | |
static uint | calculateChildEntriesPerNode (RecordNum parentLevelTotalEntries, RecordNum childLevelTotalEntries, RecordNum parentLevelProcessedEntries) |
static uint | calculateNodesOnLevel (uint nChildEntries, uint nEntriesPerChildNode) |
Private Attributes | |
std::vector< SharedBTreeBuildLevel > | levels |
SharedSegment | pTempSegment |
Friends | |
class | BTreeBuildLevel |
class | FixedBuildLevel |
class | VariableBuildLevel |
class | DynamicBuildLevel |
When non-leaf nodes store fixed-width entries, it builds a nicely balanced tree. In other cases, it builds an unbalanced tree. An optional fill factor is supported for all cases.
BTreeBuilder is also used for creating empty trees and truncating or dropping existing ones.
Definition at line 49 of file BTreeBuilder.h.
BTreeBuilder::BTreeBuilder | ( | BTreeDescriptor const & | descriptor, | |
SharedSegment | pTempSegment = SharedSegment() | |||
) | [explicit] |
Creates a new BTreeBuilder.
In order to build a non-empty tree with variable-width tuples in the leaf nodes and fixed-width entries in the non-leaf nodes, a temporary disk buffer is required.
descriptor | descriptor for tree to be built | |
pTempSegment | segment to use for temporary buffer, or NULL if it is known that none is needed |
Definition at line 34 of file BTreeBuilder.cpp.
References pTempSegment.
00037 : BTreeAccessBase(descriptor) 00038 { 00039 pTempSegment = pTempSegmentInit; 00040 }
BTreeBuilder::~BTreeBuilder | ( | ) | [virtual] |
uint BTreeBuilder::calculateChildEntriesPerNode | ( | RecordNum | parentLevelTotalEntries, | |
RecordNum | childLevelTotalEntries, | |||
RecordNum | parentLevelProcessedEntries | |||
) | [static, private] |
Definition at line 295 of file BTreeBuilder.cpp.
Referenced by BTreeBuildLevel::allocateAndLinkNewNode(), and buildBalanced().
00299 { 00300 // Determine the desired fanout. This is non-integral, so our job is to 00301 // distribute it as evenly as possible. 00302 // TODO: we could remember this instead of recalculating it. 00303 double fanout = 00304 double(childLevelTotalEntries) / double(parentLevelTotalEntries); 00305 00306 uint childLevelNewTotal; 00307 if (parentLevelProcessedEntries == (parentLevelTotalEntries - 1)) { 00308 // Last child node needs to make everything come out exact. 00309 childLevelNewTotal = childLevelTotalEntries; 00310 } else { 00311 childLevelNewTotal = 00312 uint(0.5 + fanout * (parentLevelProcessedEntries + 1)); 00313 } 00314 00315 // Use what we returned from the previous call as a baseline. 00316 // TODO: we could remember this instead of recalculating it. 00317 uint childLevelPrevTotal = uint(0.5 + fanout * parentLevelProcessedEntries); 00318 00319 uint n = childLevelNewTotal - childLevelPrevTotal; 00320 assert(n > 0); 00321 return n; 00322 }
uint BTreeBuilder::calculateNodesOnLevel | ( | uint | nChildEntries, | |
uint | nEntriesPerChildNode | |||
) | [static, private] |
Definition at line 46 of file BTreeBuilder.cpp.
Referenced by buildBalanced().
00048 { 00049 uint nNodes = nEntries / nEntriesPerNode; 00050 if (nEntries % nEntriesPerNode) { 00051 // need an extra node for the remainder 00052 ++nNodes; 00053 } 00054 return nNodes; 00055 }
uint BTreeBuilder::getRootHeight | ( | ) | [inline, private] |
Definition at line 74 of file BTreeBuilder.h.
Referenced by buildBalanced(), growTree(), DynamicBuildLevel::indexLastKey(), FixedBuildLevel::indexLastKey(), and swapRoot().
00075 { 00076 return levels.size() - 1; 00077 }
void BTreeBuilder::buildBalanced | ( | ByteInputStream & | sortedStream, | |
uint | iInputLevel, | |||
RecordNum | nEntriesTotal, | |||
double | fillFactor | |||
) | [private] |
Definition at line 182 of file BTreeBuilder.cpp.
References BTreeBuildLevel::allocatePage(), calculateChildEntriesPerNode(), calculateNodesOnLevel(), BTreeNodeAccessor::clearNode(), FixedBuildLevel, getLevel(), SegNodeLock< Node >::getNodeForWrite(), getRootHeight(), BTreeAccessBase::getRootPageId(), BTreeAccessBase::getSegment(), BTreeNode::height, BTreeBuildLevel::iLevel, BTreeBuildLevel::indexLastKey(), levels, SegPageLock::lockExclusive(), BTreeNode::nEntries, BTreeBuildLevel::nEntriesPerNode, BTreeBuildLevel::nEntriesTotal, BTreeBuildLevel::nodeAccessor, NULL_PAGE_ID, BTreeBuildLevel::pageId, BTreeBuildLevel::pageLock, BTreeAccessBase::pLeafNodeAccessor, BTreeAccessBase::pNonLeafNodeAccessor, BTreeBuildLevel::processInput(), BTreeDescriptor::rootPageId, and BTreeAccessBase::treeDescriptor.
Referenced by build(), and buildTwoPass().
00187 { 00188 // First, determine node capacities based on fixed-width entry sizes. This 00189 // gives us the maximum fanout. 00190 00191 uint nEntriesPerNonLeaf = 00192 getSegment()->getUsablePageSize() - sizeof(BTreeNode); 00193 nEntriesPerNonLeaf /= 00194 pNonLeafNodeAccessor->getEntryByteCount( 00195 pNonLeafNodeAccessor->tupleAccessor.getMaxByteCount()); 00196 00197 uint nEntriesPerLeaf = 00198 getSegment()->getUsablePageSize() - sizeof(BTreeNode); 00199 nEntriesPerLeaf /= 00200 pLeafNodeAccessor->getEntryByteCount( 00201 pLeafNodeAccessor->tupleAccessor.getMaxByteCount()); 00202 00203 nEntriesPerNonLeaf = uint(nEntriesPerNonLeaf*fillFactor); 00204 nEntriesPerLeaf = uint(nEntriesPerLeaf*fillFactor); 00205 00206 if (!nEntriesPerNonLeaf) { 00207 nEntriesPerNonLeaf = 1; 00208 } 00209 if (!nEntriesPerLeaf) { 00210 nEntriesPerLeaf = 1; 00211 } 00212 00213 // Next, calculate how high a "full" tree with this fanout would have to be 00214 // in order to accommodate the expected number of entries. In most cases 00215 // the tree won't actually be full, but the height can't be any lower than 00216 // this. 00217 00218 RecordNum nEntriesFull = iInputLevel ? nEntriesPerNonLeaf : nEntriesPerLeaf; 00219 uint nLevels = iInputLevel + 1; 00220 while (nEntriesFull < nEntriesTotal) { 00221 ++nLevels; 00222 nEntriesFull *= nEntriesPerNonLeaf; 00223 } 00224 levels.resize(nLevels); 00225 00226 // Now, calculate how many entries to expect on each level. We could do 00227 // the per-level balancing here as well, but then we'd have to keep around 00228 // an in-memory structure proportional to the number of nodes in the tree. 00229 // Instead, we calculate the balancing on the fly later. 00230 RecordNum nEntriesInLevel = nEntriesTotal; 00231 for (uint i = iInputLevel; i < levels.size(); i++) { 00232 BTreeNodeAccessor &nodeAccessor = 00233 i ? *pNonLeafNodeAccessor : *pLeafNodeAccessor; 00234 00235 assert(nodeAccessor.hasFixedWidthEntries()); 00236 levels[i].reset(new FixedBuildLevel(*this,nodeAccessor)); 00237 00238 BTreeBuildLevel &level = getLevel(i); 00239 level.iLevel = i; 00240 level.nEntriesTotal = nEntriesInLevel; 00241 00242 // number of parent entries is same as number of child nodes 00243 nEntriesInLevel = calculateNodesOnLevel( 00244 nEntriesInLevel, 00245 i ? nEntriesPerNonLeaf : nEntriesPerLeaf); 00246 00247 if (i == getRootHeight()) { 00248 // Set up the root info, which can be fully determined ahead of 00249 // time. 00250 level.nEntriesPerNode = level.nEntriesTotal; 00251 if (getRootPageId() == NULL_PAGE_ID) { 00252 level.allocatePage(); 00253 treeDescriptor.rootPageId = level.pageId; 00254 } else { 00255 // We're from Berkeley, so we reuse the existing root rather 00256 // than allocating a new one. 00257 level.pageId = getRootPageId(); 00258 level.pageLock.lockExclusive(level.pageId); 00259 BTreeNode &node = level.pageLock.getNodeForWrite(); 00260 assert(!node.nEntries); 00261 level.nodeAccessor.clearNode( 00262 node,getSegment()->getUsablePageSize()); 00263 node.height = i; 00264 } 00265 } else { 00266 // Allocate the first empty page of a non-root level. 00267 level.allocatePage(); 00268 } 00269 if (i) { 00270 // Prepare the first page of a non-leaf level. 00271 // Calculate balancing for first child node. 00272 BTreeBuildLevel &childLevel = getLevel(i - 1); 00273 childLevel.nEntriesPerNode = calculateChildEntriesPerNode( 00274 level.nEntriesTotal, 00275 childLevel.nEntriesTotal, 00276 0); 00277 } 00278 } 00279 00280 // should end up with exactly one node at the root level, which corresponds 00281 // to one entry in an imaginary parent of the root 00282 assert(nEntriesInLevel == 1); 00283 00284 // feed data into the correct level 00285 getLevel(iInputLevel).processInput(sortedInputStream); 00286 00287 // finalize rightist fringe 00288 for (uint i = iInputLevel; i < levels.size(); ++i) { 00289 BTreeBuildLevel &level = getLevel(i); 00290 level.indexLastKey(true); 00291 assert(level.isFinished()); 00292 } 00293 }
void BTreeBuilder::buildTwoPass | ( | ByteInputStream & | sortedStream, | |
RecordNum | nEntries, | |||
double | fillFactor | |||
) | [private] |
Definition at line 87 of file BTreeBuilder.cpp.
References BTreeBuildLevel::allocatePage(), buildBalanced(), BTreeBuildLevel::cbReserved, getLevel(), BTreeAccessBase::getSegment(), BTreeNodeAccessor::hasFixedWidthEntries(), BTreeBuildLevel::indexLastKey(), BTreeBuildLevel::iNode, levels, BTreeBuildLevel::nEntriesTotal, BTreeAccessBase::pLeafNodeAccessor, BTreeBuildLevel::processInput(), swapRoot(), and VariableBuildLevel.
Referenced by build().
00091 { 00092 // calculate amount of space to reserve on each leaf from fillfactor 00093 uint cbReserved = getSegment()->getUsablePageSize() - sizeof(BTreeNode); 00094 cbReserved = uint(cbReserved*(1-fillFactor)); 00095 00096 levels.resize(1); 00097 BTreeNodeAccessor &nodeAccessor = *pLeafNodeAccessor; 00098 assert(!nodeAccessor.hasFixedWidthEntries()); 00099 VariableBuildLevel *pLeafLevel = new VariableBuildLevel(*this,nodeAccessor); 00100 levels[0].reset(pLeafLevel); 00101 00102 BTreeBuildLevel &level = getLevel(0); 00103 level.nEntriesTotal = nEntriesTotal; 00104 level.cbReserved = cbReserved; 00105 00106 level.allocatePage(); 00107 00108 // feed data into the leaf level; this will collect the entries for 00109 // level 1 (the parent of the leaf level) in a temp stream 00110 level.processInput(sortedInputStream); 00111 00112 level.indexLastKey(true); 00113 00114 // now we know how many entries to expect for level 1: the number of 00115 // leaf nodes just filled 00116 RecordNum nEntriesParent = level.iNode + 1; 00117 00118 if (nEntriesParent == 1) { 00119 // The leaf we just filled turns out to be the root. 00120 swapRoot(); 00121 return; 00122 } 00123 00124 // REVIEW: distinguish leaf fillFactor from non-leaf fillFactor? 00125 00126 SharedSegInputStream pParentInputStream = 00127 pLeafLevel->getParentKeyStream(); 00128 assert(pParentInputStream); 00129 // feed buffered entries into level 1, and build up balanced from there 00130 buildBalanced(*pParentInputStream,1,nEntriesParent,fillFactor); 00131 }
void BTreeBuilder::buildUnbalanced | ( | ByteInputStream & | sortedStream, | |
RecordNum | nEntries, | |||
double | fillFactor | |||
) | [private] |
Definition at line 154 of file BTreeBuilder.cpp.
References BTreeBuildLevel::cbReserved, getLevel(), BTreeAccessBase::getSegment(), growTree(), BTreeBuildLevel::indexLastKey(), levels, BTreeBuildLevel::nEntriesTotal, BTreeBuildLevel::processInput(), and swapRoot().
Referenced by build().
00158 { 00159 // TODO: common fcn 00160 // calculate amount of space to reserve on each leaf from fillfactor 00161 uint cbReserved = getSegment()->getUsablePageSize() - sizeof(BTreeNode); 00162 cbReserved = uint(cbReserved*(1-fillFactor)); 00163 00164 // start with just a leaf level 00165 growTree(); 00166 BTreeBuildLevel &level = getLevel(0); 00167 level.cbReserved = cbReserved; 00168 level.nEntriesTotal = nEntriesTotal; 00169 level.processInput(sortedInputStream); 00170 00171 // NOTE: It's important to realize that growTree() could be called inside 00172 // this loop, so it's necessary to recompute levels.size() after each 00173 // iteration. 00174 for (uint i = 0; i < levels.size(); ++i) { 00175 BTreeBuildLevel &level = getLevel(i); 00176 level.indexLastKey(true); 00177 } 00178 00179 swapRoot(); 00180 }
void BTreeBuilder::processInput | ( | ByteInputStream & | sortedStream | ) | [private] |
BTreeBuildLevel & BTreeBuilder::getLevel | ( | uint | i | ) | [inline, private] |
Definition at line 164 of file BTreeBuilder.h.
References levels.
Referenced by BTreeBuildLevel::allocateAndLinkNewNode(), buildBalanced(), buildTwoPass(), buildUnbalanced(), growTree(), BTreeBuildLevel::indexLastChild(), DynamicBuildLevel::indexLastKey(), FixedBuildLevel::indexLastKey(), and swapRoot().
00165 { 00166 return *(levels[i]); 00167 }
void BTreeBuilder::growTree | ( | ) | [private] |
Definition at line 335 of file BTreeBuilder.cpp.
References BTreeBuildLevel::allocatePage(), BTreeBuildLevel::cbReserved, DynamicBuildLevel, getLevel(), getRootHeight(), BTreeBuildLevel::iLevel, levels, BTreeAccessBase::pLeafNodeAccessor, and BTreeAccessBase::pNonLeafNodeAccessor.
Referenced by buildUnbalanced(), and DynamicBuildLevel::indexLastKey().
00336 { 00337 BTreeNodeAccessor &nodeAccessor = 00338 levels.size() ? *pNonLeafNodeAccessor : *pLeafNodeAccessor; 00339 levels.resize(levels.size() + 1); 00340 levels[getRootHeight()].reset(new DynamicBuildLevel(*this,nodeAccessor)); 00341 BTreeBuildLevel &level = *levels.back(); 00342 level.iLevel = getRootHeight(); 00343 if (level.iLevel) { 00344 // inherit cbReserved 00345 level.cbReserved = getLevel(level.iLevel - 1).cbReserved; 00346 } 00347 level.allocatePage(); 00348 }
void BTreeBuilder::swapRoot | ( | ) | [private] |
Definition at line 133 of file BTreeBuilder.cpp.
References SegPageLock::deallocateLockedPage(), getLevel(), SegNodeLock< Node >::getNodeForWrite(), getRootHeight(), BTreeAccessBase::getRootPageId(), SegPageLock::lockExclusive(), BTreeNode::nEntries, NULL_PAGE_ID, BTreeBuildLevel::pageId, BTreeBuildLevel::pageLock, BTreeDescriptor::rootPageId, BTreeDescriptor::segmentAccessor, SegPageLock::swapBuffers(), and BTreeAccessBase::treeDescriptor.
Referenced by buildTwoPass(), and buildUnbalanced().
00134 { 00135 BTreeBuildLevel &rootLevel = getLevel(getRootHeight()); 00136 if (getRootPageId() == NULL_PAGE_ID) { 00137 // No rootPageId has been assigned yet, so no need to copy. 00138 treeDescriptor.rootPageId = rootLevel.pageId; 00139 return; 00140 } 00141 00142 // We're supposed to preserve the PageId of the existing root, so 00143 // swap buffers with the original root. 00144 BTreePageLock reusedRootPageLock(treeDescriptor.segmentAccessor); 00145 reusedRootPageLock.lockExclusive(getRootPageId()); 00146 BTreeNode &reusedRoot = reusedRootPageLock.getNodeForWrite(); 00147 assert(!reusedRoot.nEntries); 00148 reusedRootPageLock.swapBuffers(rootLevel.pageLock); 00149 00150 // deallocate the abandonded tempRoot 00151 rootLevel.pageLock.deallocateLockedPage(); 00152 }
void BTreeBuilder::truncateChildren | ( | BTreeNode const & | node | ) | [private] |
Definition at line 389 of file BTreeBuilder.cpp.
References SegPageLock::accessSegment(), SegPageLock::deallocateUnlockedPage(), BTreeAccessBase::getChild(), SegNodeLock< Node >::getNodeForRead(), BTreeAccessBase::getRightSibling(), BTreeNode::height, SegPageLock::lockExclusive(), BTreeNode::nEntries, NULL_PAGE_ID, BTreeDescriptor::segmentAccessor, BTreeAccessBase::treeDescriptor, and SegPageLock::unlock().
Referenced by truncate().
00390 { 00391 assert(node.height); 00392 assert(node.nEntries); 00393 PageId pageId = getChild(node,0); 00394 BTreePageLock pageLock; 00395 pageLock.accessSegment(treeDescriptor.segmentAccessor); 00396 if (node.height > 1) { 00397 pageLock.lockExclusive(pageId); 00398 truncateChildren(pageLock.getNodeForRead()); 00399 pageLock.unlock(); 00400 } 00401 while (pageId != NULL_PAGE_ID) { 00402 PageId nextPageId = getRightSibling(pageId); 00403 pageLock.deallocateUnlockedPage(pageId); 00404 pageId = nextPageId; 00405 } 00406 }
void BTreeBuilder::truncateExternal | ( | TupleProjection const & | leafPageIdProj | ) | [private] |
Definition at line 408 of file BTreeBuilder.cpp.
References SegPageLock::accessSegment(), TupleProjectionAccessor::bind(), SegPageLock::deallocateUnlockedPage(), BTreeReader::getTupleAccessorForRead(), TupleDescriptor::projectFrom(), BTreeReader::searchFirst(), BTreeReader::searchNext(), BTreeDescriptor::segmentAccessor, BTreeAccessBase::treeDescriptor, BTreeDescriptor::tupleDescriptor, and TupleProjectionAccessor::unmarshal().
Referenced by truncate().
00409 { 00410 // REVIEW jvs 24-Dec-2005: Here we pre-scan the tree, dropping 00411 // the external pages. This scan could be combined with 00412 // the main truncate traversal for better efficiency. 00413 BTreeReader reader(treeDescriptor); 00414 TupleProjectionAccessor projAccessor; 00415 projAccessor.bind( 00416 reader.getTupleAccessorForRead(), 00417 leafPageIdProj); 00418 TupleDescriptor projDesc; 00419 projDesc.projectFrom(treeDescriptor.tupleDescriptor, leafPageIdProj); 00420 TupleData projData(projDesc); 00421 BTreePageLock pageLock; 00422 pageLock.accessSegment(treeDescriptor.segmentAccessor); 00423 if (reader.searchFirst()) { 00424 do { 00425 projAccessor.unmarshal(projData); 00426 for (uint i = 0; i < projData.size(); ++i) { 00427 if (!projData[i].pData) { 00428 continue; 00429 } 00430 PageId pageId = *reinterpret_cast<PageId const *>( 00431 projData[i].pData); 00432 pageLock.deallocateUnlockedPage(pageId); 00433 } 00434 } while (reader.searchNext()); 00435 } 00436 }
void BTreeBuilder::build | ( | ByteInputStream & | sortedStream, | |
RecordNum | nEntries, | |||
double | fillFactor = 1.0 | |||
) |
Builds the tree, which must be currently empty or non-existent.
Call getRootPageId() afterwards to find the root of a newly created tree.
sortedStream | stream containing tuples presorted by the tree's key | |
nEntries | number of tuples to be read from pSortedStream | |
fillFactor | fraction of each node to fill, where 1.0 (the default) represents 100% |
Definition at line 57 of file BTreeBuilder.cpp.
References buildBalanced(), buildTwoPass(), buildUnbalanced(), levels, BTreeAccessBase::pLeafNodeAccessor, and BTreeAccessBase::pNonLeafNodeAccessor.
Referenced by BTreeTest::testBulkLoad(), and BTreeReadersTest::testReaders().
00061 { 00062 assert(fillFactor <= 1.0); 00063 assert(fillFactor > 0); 00064 try { 00065 if (pLeafNodeAccessor->hasFixedWidthEntries() 00066 && pNonLeafNodeAccessor->hasFixedWidthEntries()) 00067 { 00068 buildBalanced(sortedInputStream,0,nEntriesTotal,fillFactor); 00069 } else if (pNonLeafNodeAccessor->hasFixedWidthEntries()) { 00070 buildTwoPass( 00071 sortedInputStream,nEntriesTotal,fillFactor); 00072 } else { 00073 assert(!pLeafNodeAccessor->hasFixedWidthEntries()); 00074 buildUnbalanced(sortedInputStream,nEntriesTotal,fillFactor); 00075 } 00076 } catch (...) { 00077 try { 00078 levels.clear(); 00079 } catch (...) { 00080 // TODO: trace suppressed excn 00081 } 00082 throw; 00083 } 00084 levels.clear(); 00085 }
void BTreeBuilder::createEmptyRoot | ( | ) |
Creates an empty tree (just a root node with no tuples).
On entry, the builder should have NULL_PAGE_ID for its root. Call getRootPageId() afterwards to get the new root.
Definition at line 324 of file BTreeBuilder.cpp.
References SegPageLock::accessSegment(), SegNodeLock< Node >::allocatePage(), SegNodeLock< Node >::getNodeForWrite(), BTreeAccessBase::getPageOwnerId(), BTreeAccessBase::getRootPageId(), BTreeAccessBase::getSegment(), NULL_PAGE_ID, BTreeAccessBase::pLeafNodeAccessor, BTreeDescriptor::rootPageId, BTreeDescriptor::segmentAccessor, and BTreeAccessBase::treeDescriptor.
Referenced by BTreeInsertExecStream::buildTree(), LbmSplicerExecStreamTest::createBTree(), LcsClusterReplaceExecStream::getTupleForLoad(), LbmSplicerExecStream::getValidatedTuple(), LcsClusterReplaceExecStreamTest::loadCluster(), LcsMultiClusterAppendTest::loadClusters(), LcsRowScanExecStreamTest::loadOneCluster(), LbmSearchTest::loadTableAndIndex(), ExecStreamTestSuite::testBTreeInsertExecStream(), BTreeTest::testBulkLoad(), BTreeTest::testInserts(), LbmLoadBitmapTest::testLoad(), LcsClusterAppendExecStreamTest::testLoadMultiCol(), LcsClusterAppendExecStreamTest::testLoadSingleCol(), BTreeTest::testMultiKeySearches(), BTreeReadersTest::testReaders(), LcsRowScanExecStreamTest::testScanOnEmptyCluster(), and CmdInterpreter::visit().
00325 { 00326 assert(getRootPageId() == NULL_PAGE_ID); 00327 BTreePageLock pageLock; 00328 pageLock.accessSegment(treeDescriptor.segmentAccessor); 00329 treeDescriptor.rootPageId = pageLock.allocatePage(getPageOwnerId()); 00330 BTreeNode &node = pageLock.getNodeForWrite(); 00331 pLeafNodeAccessor->clearNode( 00332 node,getSegment()->getUsablePageSize()); 00333 }
void BTreeBuilder::truncate | ( | bool | rootless, | |
TupleProjection const * | pLeafPageIdProj = NULL | |||
) |
Truncates or drops an existing tree.
rootless | if true, all nodes of the existing tree are deallocated; if false, the root is cleared but remains allocated while all other nodes are deallocated | |
pLeafPageIdProj | if non-NULL, leaf tuples will be read and non-null projected attributes will be interpreted as additional PageId's to be dropped |
Definition at line 351 of file BTreeBuilder.cpp.
References SegPageLock::accessSegment(), SegPageLock::deallocateLockedPage(), SegNodeLock< Node >::getNodeForRead(), SegNodeLock< Node >::getNodeForWrite(), BTreeAccessBase::getRootPageId(), BTreeAccessBase::getSegment(), BTreeNode::height, SegPageLock::lockExclusive(), BTreeNode::nEntries, NULL_PAGE_ID, BTreeAccessBase::pLeafNodeAccessor, BTreeDescriptor::rootPageId, BTreeDescriptor::segmentAccessor, BTreeAccessBase::treeDescriptor, truncateChildren(), and truncateExternal().
Referenced by CmdInterpreter::dropOrTruncateIndex(), BTreeTest::testBulkLoad(), BTreeReadersTest::testReaders(), and BTreeInsertExecStream::truncateTree().
00353 { 00354 if (pLeafPageIdProj) { 00355 truncateExternal(*pLeafPageIdProj); 00356 } 00357 BTreePageLock pageLock; 00358 pageLock.accessSegment(treeDescriptor.segmentAccessor); 00359 00360 pageLock.lockExclusive(getRootPageId()); 00361 00362 // Try a read-only access to see if we can skip dirtying a page. 00363 BTreeNode const &rootReadOnly = pageLock.getNodeForRead(); 00364 if (!rootReadOnly.height) { 00365 if (rootless) { 00366 pageLock.deallocateLockedPage(); 00367 treeDescriptor.rootPageId = NULL_PAGE_ID; 00368 return; 00369 } 00370 if (!rootReadOnly.nEntries) { 00371 // root is already empty 00372 return; 00373 } 00374 } 00375 00376 BTreeNode &root = pageLock.getNodeForWrite(); 00377 if (root.height) { 00378 truncateChildren(root); 00379 } 00380 if (rootless) { 00381 pageLock.deallocateLockedPage(); 00382 treeDescriptor.rootPageId = NULL_PAGE_ID; 00383 } else { 00384 pLeafNodeAccessor->clearNode( 00385 root,getSegment()->getUsablePageSize()); 00386 } 00387 }
FENNEL_BEGIN_NAMESPACE BTreeNodeAccessor & BTreeAccessBase::getLeafNodeAccessor | ( | BTreeNode const & | node | ) | [inline, protected, inherited] |
Gets the node accessor for a leaf node, asserting that the node really is a leaf.
node | leaf node to access |
Definition at line 32 of file BTreeAccessBaseImpl.h.
References BTreeNode::height, and BTreeAccessBase::pLeafNodeAccessor.
Referenced by BTreeReader::accessLeafTuple(), BTreeWriter::deleteCurrent(), and BTreeWriter::updateCurrent().
00034 { 00035 assert(!node.height); 00036 return *pLeafNodeAccessor; 00037 }
BTreeNodeAccessor & BTreeAccessBase::getNonLeafNodeAccessor | ( | BTreeNode const & | node | ) | [inline, protected, inherited] |
Gets the node accessor for a non-leaf node, asserting that the node really is a non-leaf.
node | non-leaf node to access |
Definition at line 39 of file BTreeAccessBaseImpl.h.
References BTreeNode::height, and BTreeAccessBase::pNonLeafNodeAccessor.
Referenced by BTreeAccessBase::getChild(), and BTreeWriter::grow().
00041 { 00042 assert(node.height); 00043 return *pNonLeafNodeAccessor; 00044 }
BTreeNodeAccessor & BTreeAccessBase::getNodeAccessor | ( | BTreeNode const & | node | ) | [inline, protected, inherited] |
Gets the node accessor for any node, using the node height to determine whether it's a leaf or not.
If you already know this from the context, call getLeafNodeAccessor or getNonLeafNodeAccessor instead.
node | node to access |
Definition at line 46 of file BTreeAccessBaseImpl.h.
References BTreeNode::height, BTreeAccessBase::pLeafNodeAccessor, and BTreeAccessBase::pNonLeafNodeAccessor.
Referenced by BTreeReader::accessTupleInline(), BTreeWriter::attemptInsertWithoutSplit(), BTreeReader::binarySearch(), BTreeWriter::compactNode(), BTreeReader::compareFirstKey(), BTreeWriter::grow(), BTreeWriter::lockParentPage(), BTreeWriter::splitCurrentNode(), BTreeVerifier::verifyChildren(), and BTreeVerifier::verifyNode().
00048 { 00049 if (node.height) { 00050 return *pNonLeafNodeAccessor; 00051 } else { 00052 return *pLeafNodeAccessor; 00053 } 00054 }
PageId BTreeAccessBase::getChildForCurrent | ( | ) | [inline, protected, inherited] |
Gets the child PageId corresponding to the current key in a non-leaf node.
Assumes that accessTuple has already been called on pNonLeafNodeAccessor (but can't assert this), so use with caution.
Reimplemented in BTreeNonLeafReader.
Definition at line 56 of file BTreeAccessBaseImpl.h.
References BTreeAccessBase::pChildAccessor, TupleDatum::pData, BTreeAccessBase::pNonLeafNodeAccessor, and AttributeAccessor::unmarshalValue().
Referenced by BTreeAccessBase::getChild(), BTreeNonLeafReader::getChildForCurrent(), and BTreeReader::searchForKeyTemplate().
00057 { 00058 TupleDatum &childDatum = pNonLeafNodeAccessor->tupleData.back(); 00059 pChildAccessor->unmarshalValue( 00060 pNonLeafNodeAccessor->tupleAccessor,childDatum); 00061 return *reinterpret_cast<PageId const *>(childDatum.pData); 00062 }
PageId BTreeAccessBase::getChild | ( | BTreeNode const & | node, | |
uint | iChild | |||
) | [inline, protected, inherited] |
Accesses a non-leaf tuple and gets its child PageId.
node | non-leaf node to access | |
iChild | 0-based index of tuple to access |
Definition at line 64 of file BTreeAccessBaseImpl.h.
References BTreeNodeAccessor::accessTuple(), BTreeAccessBase::getChildForCurrent(), and BTreeAccessBase::getNonLeafNodeAccessor().
Referenced by BTreeAccessBase::getFirstChild(), BTreeReader::searchExtremeInternal(), BTreeReader::searchForKeyTemplate(), truncateChildren(), and BTreeVerifier::verifyChildren().
00065 { 00066 getNonLeafNodeAccessor(node).accessTuple(node,iChild); 00067 return getChildForCurrent(); 00068 }
PageId BTreeAccessBase::getRightSibling | ( | PageId | pageId | ) | [inline, protected, inherited] |
Gets the right sibling of a node by consulting the containing segment's successor information.
Should only be used when the node is not already locked (e.g. during prefetch). When the node is already locked, its rightSibling field should be accessed instead.
pageId | PageId of node whose sibling is to be found |
Definition at line 70 of file BTreeAccessBaseImpl.h.
References BTreeAccessBase::getSegment().
Referenced by truncateChildren(), and BTreeVerifier::verifyNode().
00071 { 00072 return getSegment()->getPageSuccessor(pageId); 00073 }
void BTreeAccessBase::setRightSibling | ( | BTreeNode & | leftNode, | |
PageId | leftPageId, | |||
PageId | rightPageId | |||
) | [inline, protected, inherited] |
Sets the right sibling of a node.
leftNode | node whose right sibling is to be set | |
leftPageId | PageId corresponding to leftNode | |
rightPageId | PageId of new right sibling |
Definition at line 75 of file BTreeAccessBaseImpl.h.
References BTreeAccessBase::getSegment(), and BTreeNode::rightSibling.
Referenced by BTreeBuildLevel::allocateAndLinkNewNode(), and BTreeWriter::splitCurrentNode().
00077 { 00078 getSegment()->setPageSuccessor(leftPageId,rightPageId); 00079 leftNode.rightSibling = rightPageId; 00080 }
PageId BTreeAccessBase::getFirstChild | ( | PageId | pageId | ) | [protected, inherited] |
Gets the first child of a non-leaf node.
pageId | PageId of non-leaf node |
Definition at line 126 of file BTreeAccessBase.cpp.
References BTreeAccessBase::getChild(), SegNodeLock< Node >::getNodeForRead(), BTreeNode::height, SegPageLock::lockShared(), BTreeNode::nEntries, NULL_PAGE_ID, BTreeNode::rightSibling, BTreeDescriptor::segmentAccessor, and BTreeAccessBase::treeDescriptor.
Referenced by BTreeReader::searchForKeyTemplate(), and BTreeVerifier::verifyChildren().
00127 { 00128 BTreePageLock pageLock(treeDescriptor.segmentAccessor); 00129 while (parentPageId != NULL_PAGE_ID) { 00130 pageLock.lockShared(parentPageId); 00131 BTreeNode const &node = pageLock.getNodeForRead(); 00132 assert(node.height); 00133 if (node.nEntries) { 00134 return getChild(node,0); 00135 } 00136 parentPageId = node.rightSibling; 00137 } 00138 return NULL_PAGE_ID; 00139 }
SharedSegment BTreeAccessBase::getSegment | ( | ) | const [inline, inherited] |
Definition at line 234 of file BTreeAccessBase.h.
References SegmentAccessor::pSegment, BTreeDescriptor::segmentAccessor, and BTreeAccessBase::treeDescriptor.
Referenced by BTreeBuildLevel::allocatePage(), BTreeAccessBase::BTreeAccessBase(), buildBalanced(), buildTwoPass(), buildUnbalanced(), BTreeWriter::compactNode(), createEmptyRoot(), BTreeAccessBase::getRightSibling(), BTreeWriter::grow(), BTreeAccessBase::setRightSibling(), BTreeWriter::splitCurrentNode(), and truncate().
00235 { 00236 return treeDescriptor.segmentAccessor.pSegment; 00237 }
SharedCacheAccessor BTreeAccessBase::getCacheAccessor | ( | ) | const [inline, inherited] |
Definition at line 239 of file BTreeAccessBase.h.
References SegmentAccessor::pCacheAccessor, BTreeDescriptor::segmentAccessor, and BTreeAccessBase::treeDescriptor.
Referenced by BTreeBuildLevel::allocateAndLinkNewNode(), VariableBuildLevel::getParentKeyStream(), and VariableBuildLevel::VariableBuildLevel().
00240 { 00241 return treeDescriptor.segmentAccessor.pCacheAccessor; 00242 }
PageId BTreeAccessBase::getRootPageId | ( | ) | const [inline, inherited] |
Definition at line 244 of file BTreeAccessBase.h.
References BTreeDescriptor::rootPageId, and BTreeAccessBase::treeDescriptor.
Referenced by BTreeVerifier::BTreeVerifier(), buildBalanced(), BTreeInsertExecStream::buildTree(), LbmSplicerExecStreamTest::createBTree(), createEmptyRoot(), BTreeWriter::describeParticipant(), LcsClusterReplaceExecStream::getTupleForLoad(), LbmSplicerExecStream::getValidatedTuple(), BTreeNonLeafReader::isRootOnly(), LcsClusterReplaceExecStreamTest::loadCluster(), LcsMultiClusterAppendTest::loadClusters(), LcsRowScanExecStreamTest::loadOneCluster(), LbmSearchTest::loadTableAndIndex(), BTreeWriter::lockParentPage(), BTreeWriter::optimizeRootLockMode(), BTreeWriter::positionSearchKey(), BTreeReader::searchExtremeInternal(), BTreeReader::searchForKey(), BTreeNonLeafReader::searchForKey(), swapRoot(), ExecStreamTestSuite::testBTreeInsertExecStream(), BTreeTest::testBulkLoad(), BTreeTest::testInserts(), LbmLoadBitmapTest::testLoad(), LcsClusterAppendExecStreamTest::testLoadMultiCol(), LcsClusterAppendExecStreamTest::testLoadSingleCol(), BTreeTest::testMultiKeySearches(), BTreeReadersTest::testReaders(), BTreeReadersTest::testScan(), LcsRowScanExecStreamTest::testScanOnEmptyCluster(), BTreeReadersTest::testSearch(), truncate(), BTreeVerifier::verify(), and CmdInterpreter::visit().
00245 { 00246 return treeDescriptor.rootPageId; 00247 }
void BTreeAccessBase::setRootPageId | ( | PageId | rootPageId | ) | [inherited] |
Updates the BTree's root PageId.
Definition at line 141 of file BTreeAccessBase.cpp.
References BTreeDescriptor::rootPageId, and BTreeAccessBase::treeDescriptor.
00142 { 00143 treeDescriptor.rootPageId = rootPageId; 00144 }
SegmentId BTreeAccessBase::getSegmentId | ( | ) | const [inline, inherited] |
Definition at line 249 of file BTreeAccessBase.h.
References BTreeDescriptor::segmentId, and BTreeAccessBase::treeDescriptor.
00250 { 00251 return treeDescriptor.segmentId; 00252 }
PageOwnerId BTreeAccessBase::getPageOwnerId | ( | ) | const [inline, inherited] |
Definition at line 254 of file BTreeAccessBase.h.
References BTreeDescriptor::pageOwnerId, and BTreeAccessBase::treeDescriptor.
Referenced by BTreeBuildLevel::allocatePage(), createEmptyRoot(), BTreeWriter::grow(), and BTreeWriter::splitCurrentNode().
00255 { 00256 return treeDescriptor.pageOwnerId; 00257 }
TupleDescriptor const & BTreeAccessBase::getTupleDescriptor | ( | ) | const [inline, inherited] |
Definition at line 259 of file BTreeAccessBase.h.
References BTreeAccessBase::treeDescriptor, and BTreeDescriptor::tupleDescriptor.
Referenced by BTreeWriter::describeParticipant(), and BTreeAccessBase::validateTupleSize().
00260 { 00261 return treeDescriptor.tupleDescriptor; 00262 }
TupleDescriptor const & BTreeAccessBase::getKeyDescriptor | ( | ) | const [inline, inherited] |
Definition at line 264 of file BTreeAccessBase.h.
References BTreeAccessBase::keyDescriptor.
Referenced by BTreeTest::testBulkLoad(), BTreeTest::testInserts(), BTreeTest::testMultiKeySearches(), and BTreeReadersTest::testReaders().
00265 { 00266 return keyDescriptor; 00267 }
TupleProjection const & BTreeAccessBase::getKeyProjection | ( | ) | const [inline, inherited] |
Definition at line 269 of file BTreeAccessBase.h.
References BTreeDescriptor::keyProjection, and BTreeAccessBase::treeDescriptor.
Referenced by BTreeAccessBase::BTreeAccessBase(), and BTreeWriter::describeParticipant().
00270 { 00271 return treeDescriptor.keyProjection; 00272 }
void BTreeAccessBase::validateTupleSize | ( | TupleAccessor const & | tupleAccessor | ) | [inherited] |
Validates that a particular tuple can fit in this BTree, throwing a TupleOverflowExcn if not.
tupleAccessor | TupleAccessor referencing tuple to be inserted |
Definition at line 146 of file BTreeAccessBase.cpp.
References BTreeAccessBase::cbTupleMax, TupleAccessor::getCurrentByteCount(), BTreeAccessBase::getTupleDescriptor(), and TupleAccessor::unmarshal().
Referenced by BTreeWriter::insertTupleFromBuffer(), and BTreeBuildLevel::processInput().
00147 { 00148 uint cbTuple = tupleAccessor.getCurrentByteCount(); 00149 if (cbTuple > cbTupleMax) { 00150 TupleData tupleData(getTupleDescriptor()); 00151 tupleAccessor.unmarshal(tupleData); 00152 throw TupleOverflowExcn( 00153 getTupleDescriptor(), 00154 tupleData, 00155 cbTuple, 00156 cbTupleMax); 00157 } 00158 }
friend class BTreeBuildLevel [friend] |
Definition at line 53 of file BTreeBuilder.h.
friend class FixedBuildLevel [friend] |
friend class VariableBuildLevel [friend] |
friend class DynamicBuildLevel [friend] |
std::vector<SharedBTreeBuildLevel> BTreeBuilder::levels [private] |
Definition at line 58 of file BTreeBuilder.h.
Referenced by build(), buildBalanced(), buildTwoPass(), buildUnbalanced(), getLevel(), and growTree().
SharedSegment BTreeBuilder::pTempSegment [private] |
Definition at line 60 of file BTreeBuilder.h.
Referenced by BTreeBuilder(), VariableBuildLevel::getParentKeyStream(), and VariableBuildLevel::VariableBuildLevel().
BTreeDescriptor BTreeAccessBase::treeDescriptor [protected, inherited] |
Descriptor for tree being accessed.
Definition at line 51 of file BTreeAccessBase.h.
Referenced by BTreeBuildLevel::allocateAndLinkNewNode(), BTreeAccessBase::BTreeAccessBase(), BTreeBuildLevel::BTreeBuildLevel(), BTreeReader::BTreeReader(), buildBalanced(), createEmptyRoot(), BTreeAccessBase::getCacheAccessor(), BTreeAccessBase::getFirstChild(), BTreeAccessBase::getKeyProjection(), BTreeAccessBase::getPageOwnerId(), BTreeAccessBase::getRootPageId(), BTreeAccessBase::getSegment(), BTreeAccessBase::getSegmentId(), BTreeAccessBase::getTupleDescriptor(), BTreeWriter::grow(), BTreeWriter::lockParentPage(), BTreeAccessBase::setRootPageId(), BTreeWriter::splitCurrentNode(), swapRoot(), truncate(), truncateChildren(), truncateExternal(), and BTreeVerifier::verifyNode().
TupleDescriptor BTreeAccessBase::keyDescriptor [protected, inherited] |
Descriptor for pure keys (common across leaf and non-leaf tuples).
Definition at line 56 of file BTreeAccessBase.h.
Referenced by BTreeReader::binarySearch(), BTreeAccessBase::BTreeAccessBase(), BTreeReader::BTreeReader(), BTreeVerifier::BTreeVerifier(), BTreeWriter::checkMonotonicity(), BTreeReader::compareFirstKey(), BTreeAccessBase::getKeyDescriptor(), BTreeWriter::insertTupleFromBuffer(), BTreeWriter::lockParentPage(), BTreeReader::searchForKeyTemplate(), and BTreeVerifier::verifyNode().
AttributeAccessor const* BTreeAccessBase::pChildAccessor [protected, inherited] |
Accessor for the attribute of non-leaf tuples which stores the child PageId.
Definition at line 62 of file BTreeAccessBase.h.
Referenced by BTreeAccessBase::BTreeAccessBase(), BTreeAccessBase::getChildForCurrent(), and BTreeWriter::splitCurrentNode().
TupleProjectionAccessor BTreeAccessBase::leafKeyAccessor [protected, inherited] |
Accessor for keys of tuples stored in leaves.
Definition at line 67 of file BTreeAccessBase.h.
Referenced by BTreeAccessBase::BTreeAccessBase().
boost::scoped_ptr<BTreeNodeAccessor> BTreeAccessBase::pNonLeafNodeAccessor [protected, inherited] |
Accessor for non-leaf nodes.
Definition at line 72 of file BTreeAccessBase.h.
Referenced by BTreeAccessBase::BTreeAccessBase(), BTreeWriter::BTreeWriter(), build(), buildBalanced(), BTreeAccessBase::getChildForCurrent(), BTreeAccessBase::getNodeAccessor(), BTreeNonLeafReader::getNonLeafNodeAccessor(), BTreeAccessBase::getNonLeafNodeAccessor(), BTreeNonLeafReader::getTupleAccessorForRead(), growTree(), VariableBuildLevel::indexLastKey(), BTreeWriter::splitCurrentNode(), and BTreeBuildLevel::unmarshalLastKey().
boost::scoped_ptr<BTreeNodeAccessor> BTreeAccessBase::pLeafNodeAccessor [protected, inherited] |
Accessor for leaf nodes.
Definition at line 77 of file BTreeAccessBase.h.
Referenced by BTreeAccessBase::BTreeAccessBase(), BTreeWriter::BTreeWriter(), build(), buildBalanced(), buildTwoPass(), createEmptyRoot(), BTreeWriter::deleteLogged(), BTreeReader::endSearch(), BTreeAccessBase::getLeafNodeAccessor(), BTreeAccessBase::getNodeAccessor(), BTreeReader::getTupleAccessorForRead(), growTree(), BTreeWriter::insertTupleData(), BTreeWriter::insertTupleFromBuffer(), and truncate().
uint BTreeAccessBase::cbTupleMax [protected, inherited] |
Maximum size for a leaf-level tuple.
Definition at line 82 of file BTreeAccessBase.h.
Referenced by BTreeAccessBase::BTreeAccessBase(), and BTreeAccessBase::validateTupleSize().