BTreeReader.cpp

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/btree/BTreeReader.cpp#13 $
00003 // Fennel is a library of data storage and processing components.
00004 // Copyright (C) 2005-2009 The Eigenbase Project
00005 // Copyright (C) 2005-2009 SQLstream, Inc.
00006 // Copyright (C) 2005-2009 LucidEra, Inc.
00007 // Portions Copyright (C) 1999-2009 John V. Sichi
00008 //
00009 // This program is free software; you can redistribute it and/or modify it
00010 // under the terms of the GNU General Public License as published by the Free
00011 // Software Foundation; either version 2 of the License, or (at your option)
00012 // any later version approved by The Eigenbase Project.
00013 //
00014 // This program is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU General Public License
00020 // along with this program; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 */
00023 
00024 #include "fennel/common/CommonPreamble.h"
00025 #include "fennel/btree/BTreeReader.h"
00026 #include "fennel/btree/BTreeAccessBaseImpl.h"
00027 #include "fennel/btree/BTreeReaderImpl.h"
00028 
00029 FENNEL_BEGIN_CPPFILE("$Id: //open/dev/fennel/btree/BTreeReader.cpp#13 $");
00030 
00031 BTreeReader::BTreeReader(BTreeDescriptor const &descriptor)
00032     : BTreeAccessBase(descriptor)
00033 {
00034     pageLock.accessSegment(treeDescriptor.segmentAccessor);
00035     pSearchKey = NULL;
00036     rootLockMode = LOCKMODE_S;
00037     nonLeafLockMode = LOCKMODE_S;
00038     leafLockMode = LOCKMODE_S;
00039     comparisonKeyData.compute(keyDescriptor);
00040     searchKeyData = comparisonKeyData;
00041     singular = true;
00042 }
00043 
00044 BTreeReader::~BTreeReader()
00045 {
00046     endSearch();
00047 }
00048 
00049 bool BTreeReader::searchExtreme(bool first)
00050 {
00051     return searchExtremeInternal(first, READ_ALL);
00052 }
00053 
00054 bool BTreeReader::searchExtremeInternal(bool first, ReadMode readMode)
00055 {
00056     singular = false;
00057     pageId = getRootPageId();
00058     LockMode lockMode = rootLockMode;
00059     for (;;) {
00060         pageLock.lockPage(pageId,lockMode);
00061         BTreeNode const &node = pageLock.getNodeForRead();
00062         switch (node.height) {
00063         case 0:
00064             // at leaf level
00065             if (!adjustRootLockMode(lockMode)) {
00066                 // Retry with correct lock mode
00067                 continue;
00068             }
00069             if (!node.nEntries) {
00070                 pageId = node.rightSibling;
00071                 if (pageId == NULL_PAGE_ID) {
00072                     // FIXME jvs 11-Nov-2005:  see note in method documentation
00073                     // for searchLast.
00074                     singular = true;
00075                     return false;
00076                 }
00077                 continue;
00078             }
00079             if (first) {
00080                 iTupleOnLowestLevel = 0;
00081             } else {
00082                 iTupleOnLowestLevel = node.nEntries - 1;
00083             }
00084             accessLeafTuple();
00085             return true;
00086         case 1:
00087             if (readMode == READ_NONLEAF_ONLY) {
00088                 if (first) {
00089                     iTupleOnLowestLevel = 0;
00090                 } else {
00091                     iTupleOnLowestLevel = node.nEntries - 1;
00092                 }
00093                 accessTupleInline(node, iTupleOnLowestLevel);
00094                 return true;
00095             }
00096             // next level down is leaf, so take the correct lock
00097             lockMode = leafLockMode;
00098             break;
00099         default:
00100             lockMode = nonLeafLockMode;
00101             break;
00102         }
00103 
00104         assert(node.nEntries);
00105         if (first) {
00106             // continue searching on first child
00107             pageId = getChild(node,0);
00108         } else {
00109             // continue searching on last child
00110             pageId = getChild(node,node.nEntries - 1);
00111        }
00112     }
00113 }
00114 
00115 bool BTreeReader::searchNext()
00116 {
00117     assert(pageLock.isLocked());
00118     assert(!pageLock.getNodeForRead().height);
00119     return searchNextInternal();
00120 }
00121 
00122 bool BTreeReader::searchNextInternal()
00123 {
00124     assert(!singular);
00125     ++iTupleOnLowestLevel;
00126     for (;;) {
00127         BTreeNode const &node = pageLock.getNodeForRead();
00128         if (iTupleOnLowestLevel < node.nEntries) {
00129             accessTupleInline(node, iTupleOnLowestLevel);
00130             break;
00131         }
00132         pageId = node.rightSibling;
00133         if (pageId == NULL_PAGE_ID) {
00134             // might as well preserve position
00135             --iTupleOnLowestLevel;
00136             singular = true;
00137             return false;
00138         }
00139         pageLock.lockPage(pageId,leafLockMode);
00140         iTupleOnLowestLevel = 0;
00141     }
00142     return true;
00143 }
00144 
00145 bool BTreeReader::searchForKey(
00146     TupleData const &key, DuplicateSeek dupSeek, bool leastUpper)
00147 {
00148     return
00149         searchForKeyInternal(
00150             key, dupSeek, leastUpper, getRootPageId(), rootLockMode, READ_ALL);
00151 }
00152 
00153 bool BTreeReader::searchForKeyInternal(
00154     TupleData const &key, DuplicateSeek dupSeek, bool leastUpper,
00155     PageId startPageId, LockMode initialLockMode, ReadMode readMode)
00156 {
00157     singular = false;
00158     NullPageStack nullPageStack;
00159     bool found = searchForKeyTemplate<false,NullPageStack>(
00160         key,dupSeek,leastUpper,nullPageStack,startPageId,initialLockMode,
00161         readMode);
00162     pSearchKey = NULL;
00163     return found;
00164 }
00165 
00166 void BTreeReader::endSearch()
00167 {
00168     pLeafNodeAccessor->tupleAccessor.resetCurrentTupleBuf();
00169     pageLock.unlock();
00170     singular = true;
00171 }
00172 
00173 TupleAccessor const &BTreeReader::getTupleAccessorForRead() const
00174 {
00175     return pLeafNodeAccessor->tupleAccessor;
00176 }
00177 
00178 FENNEL_END_CPPFILE("$Id: //open/dev/fennel/btree/BTreeReader.cpp#13 $");
00179 
00180 // End BTreeReader.cpp

Generated on Mon Jun 22 04:00:13 2009 for Fennel by  doxygen 1.5.1