LbmRidReader.cpp

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/lucidera/bitmap/LbmRidReader.cpp#10 $
00003 // Fennel is a library of data storage and processing components.
00004 // Copyright (C) 2006-2009 LucidEra, Inc.
00005 // Copyright (C) 2006-2009 The Eigenbase Project
00006 //
00007 // This program is free software; you can redistribute it and/or modify it
00008 // under the terms of the GNU General Public License as published by the Free
00009 // Software Foundation; either version 2 of the License, or (at your option)
00010 // any later version approved by The Eigenbase Project.
00011 //
00012 // This program is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with this program; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 */
00021 
00022 #include "fennel/common/CommonPreamble.h"
00023 #include "fennel/exec/ExecStreamBufAccessor.h"
00024 #include "fennel/lucidera/bitmap/LbmRidReader.h"
00025 
00026 FENNEL_BEGIN_CPPFILE("$Id: //open/dev/fennel/lucidera/bitmap/LbmRidReader.cpp#10 $");
00027 
00035 static const uint firstOneBit[256] = {
00036 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00037 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00038 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00039 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00040 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00041 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00042 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00043 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00044 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00045 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00046 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00047 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00048 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00049 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00050 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00051 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
00052 };
00053 
00054 void LbmRidReaderBase::initCommon()
00055 {
00056     firstReadDone = false;
00057     nextRid = LcsRid(0);
00058     resetState();
00059 }
00060 
00061 void LbmRidReaderBase::resetState()
00062 {
00063     // set state information so that next call to readRidAndAdvance
00064     // will read "nextRid"
00065     moveNext = false;
00066     curByte = 0;
00067     curRid = LcsRid(7);
00068 }
00069 
00070 ExecStreamResult LbmRidReaderBase::searchForNextRid()
00071 {
00072     // recompute bitOffset in current byte base on current rid
00073     uint bitOffset = opaqueToInt(curRid) % LbmOneByteSize;
00074 
00075     // get current byte (local copy)
00076     uint b = curByte;
00077 
00078     // if the moveNext flag is set, it means that we are still positioned
00079     // at the bit the user already read, so move forward one bit
00080     if (moveNext) {
00081         bitOffset++;
00082         b >>= 1;
00083         moveNext = false;
00084     }
00085 
00086     while (true) {
00087         // scan forward until we hit a bit that is set, or until we've
00088         // used up all the set bits
00089 
00090         uint shift = firstOneBit[b];
00091         b >>= shift;
00092         bitOffset += shift;
00093 
00094         // if we didn't find anything, then get another byte and try again
00095         if (b == 0) {
00096             bitOffset = 0;
00097 
00098             ExecStreamResult rc = segmentReader.advanceToRid(nextRid);
00099             if (rc != EXECRC_YIELD) {
00100                 resetState();
00101                 return rc;
00102             }
00103             firstReadDone = true;
00104 
00105             // get start rid of the segment just read
00106             uint len;
00107             PBuffer pB;
00108             segmentReader.readCurrentByteSegment(curRid, pB, len);
00109             b = *pB;
00110 
00111             nextRid = curRid + LbmOneByteSize;
00112         } else {
00113             break;
00114         }
00115     }
00116 
00117     // compute current rid, now that we've found a set bit
00118     curRid = roundToByteBoundary(curRid) + bitOffset;
00119     curByte = b;
00120 
00121     return EXECRC_YIELD;
00122 }
00123 
00124 ExecStreamResult LbmRidReaderBase::advanceToRid(LcsRid rid)
00125 {
00126     assert(firstReadDone);
00127 
00128     // if we are marked for an advance, then treat this rid
00129     // as at least curRid + 1
00130     if (moveNext) {
00131         if (rid < curRid + 1) {
00132             rid = curRid + 1;
00133         }
00134         moveNext = false;
00135     }
00136 
00137     // do we need a new byte?
00138     if (rid >= roundToByteBoundary(curRid) + LbmOneByteSize) {
00139         // mark current byte as invalid, so that call to search
00140         // will read in a new byte with the desired rid
00141         curByte = 0;
00142         nextRid = rid;
00143 
00144         // read in the new byte
00145         ExecStreamResult rc = searchForNextRid();
00146         if (rc != EXECRC_YIELD) {
00147             return rc;
00148         }
00149     }
00150 
00151     // first, move forward to current byte in desired rid
00152     if (rid > curRid) {
00153         curByte >>= opaqueToInt(rid - curRid);
00154         curRid = rid;
00155     }
00156 
00157     // then, advance to first bit that is set
00158     return searchForNextRid();
00159 }
00160 
00161 ExecStreamResult LbmRidReaderBase::readRidAndAdvance(LcsRid &rid)
00162 {
00163     // advance to position we are supposed to be at, and then keep
00164     // advancing until we hit a set bit
00165     ExecStreamResult rc = searchForNextRid();
00166     if (rc != EXECRC_YIELD) {
00167         return rc;
00168     }
00169 
00170     // set return value
00171     rid = curRid;
00172 
00173     // remember to advance the next time this method is called
00174     moveNext = true;
00175 
00176     return EXECRC_YIELD;
00177 }
00178 
00179 void LbmRidReader::init(
00180     SharedExecStreamBufAccessor &pInAccessor,
00181     TupleData &bitmapSegTuple)
00182 {
00183     segmentReader.init(pInAccessor, bitmapSegTuple);
00184     initCommon();
00185 }
00186 
00187 void LbmIterableRidReader::initCommon()
00188 {
00189     LbmRidReaderBase::initCommon();
00190     buffered = false;
00191 }
00192 
00193 void LbmTupleRidReader::init(TupleData &bitmapSegTuple)
00194 {
00195     if (!pSharedReader) {
00196         pReader = new LbmSingleTupleReader();
00197         pSharedReader.reset(pReader);
00198     }
00199     pReader->init(bitmapSegTuple);
00200 
00201     segmentReader.init(pSharedReader, bitmapSegTuple);
00202     LbmIterableRidReader::initCommon();
00203 }
00204 
00205 LbmDeletionIndexReader::~LbmDeletionIndexReader()
00206 {
00207     endSearch();
00208 }
00209 
00210 void LbmDeletionIndexReader::init(
00211     SharedBTreeReader &btreeReaderInit,
00212     TupleData &bitmapSegTuple)
00213 {
00214     // the btree must be a deletion index
00215     assert(btreeReaderInit->getTupleDescriptor().size() == 3);
00216     assert(bitmapSegTuple.size() == 3);
00217 
00218     btreeReader = btreeReaderInit;
00219     pBitmapSegTuple = &bitmapSegTuple;
00220     searchEntry.compute(btreeReader->getKeyDescriptor());
00221     emptyIndexUnknown = true;
00222     currTuple = false;
00223 }
00224 
00225 void LbmDeletionIndexReader::initRidReader()
00226 {
00227     currTuple = true;
00228     ridReader.init(*pBitmapSegTuple);
00229     btreeRid = ridReader.getNext();
00230 }
00231 
00232 void LbmDeletionIndexReader::endSearch()
00233 {
00234     if (btreeReader) {
00235         btreeReader->endSearch();
00236     }
00237 }
00238 
00239 bool LbmDeletionIndexReader::isEmpty()
00240 {
00241     if (emptyIndexUnknown) {
00242         emptyIndex = !btreeReader->searchFirst();
00243         emptyIndexUnknown = false;
00244     }
00245     return emptyIndex;
00246 }
00247 
00248 bool LbmDeletionIndexReader::searchForRid(LcsRid rid)
00249 {
00250     if (isEmpty()) {
00251         return false;
00252     }
00253 
00254     LcsRid prevSrid = LcsRid(0);
00255     if (currTuple) {
00256         prevSrid = LbmEntry::getStartRid(*pBitmapSegTuple);
00257     }
00258 
00259     searchEntry[0].pData = reinterpret_cast<PConstBuffer>(&rid);
00260     btreeReader->searchForKey(searchEntry, DUP_SEEK_BEGIN, false);
00261     btreeReader->getTupleAccessorForRead().unmarshal(*pBitmapSegTuple);
00262     LcsRid foundSrid = LbmEntry::getStartRid(*pBitmapSegTuple);
00263 
00264     // determine whether the tuple rid reader must be restarted. it should
00265     // be restarted if the tuple has changed or if the rid we are searching
00266     // for would be positioned before the last rid read.
00267     bool sameTuple = (currTuple && prevSrid == foundSrid);
00268     if (!sameTuple || (rid < btreeRid)) {
00269         initRidReader();
00270     }
00271 
00272     // advance within a tuple to search for the rid
00273     while (btreeRid < rid) {
00274         if (ridReader.hasNext()) {
00275             btreeRid = ridReader.getNext();
00276         } else {
00277             break;
00278         }
00279     }
00280     return (btreeRid == rid);
00281 }
00282 
00283 FENNEL_END_CPPFILE("$Id: //open/dev/fennel/lucidera/bitmap/LbmRidReader.cpp#10 $");
00284 
00285 // End LbmRidReader.cpp

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