00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00065 if (!adjustRootLockMode(lockMode)) {
00066
00067 continue;
00068 }
00069 if (!node.nEntries) {
00070 pageId = node.rightSibling;
00071 if (pageId == NULL_PAGE_ID) {
00072
00073
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
00097 lockMode = leafLockMode;
00098 break;
00099 default:
00100 lockMode = nonLeafLockMode;
00101 break;
00102 }
00103
00104 assert(node.nEntries);
00105 if (first) {
00106
00107 pageId = getChild(node,0);
00108 } else {
00109
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
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