00001 /* 00002 // $Id: //open/dev/fennel/lucidera/bitmap/LbmSegmentWriter.cpp#8 $ 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/lucidera/bitmap/LbmSegmentWriter.h" 00024 00025 FENNEL_BEGIN_CPPFILE("$Id: //open/dev/fennel/lucidera/bitmap/LbmSegmentWriter.cpp#8 $"); 00026 00027 void LbmSegmentWriter::init( 00028 PBuffer scratchBufferInit, uint scratchBufferSizeInit, 00029 TupleDescriptor const &bitmapTupleDesc, 00030 bool removeZerosInit) 00031 { 00032 segmentEntry.init( 00033 scratchBufferInit, NULL, scratchBufferSizeInit, bitmapTupleDesc); 00034 bitmapTuple.compute(bitmapTupleDesc); 00035 removeZeros = removeZerosInit; 00036 reset(); 00037 } 00038 00039 void LbmSegmentWriter::reset() 00040 { 00041 firstWrite = true; 00042 } 00043 00044 bool LbmSegmentWriter::isEmpty() 00045 { 00046 return firstWrite; 00047 } 00048 00049 bool LbmSegmentWriter::addSegment( 00050 LcsRid &startRid, PBuffer &pByteSeg, uint &len) 00051 { 00052 uint8_t segDescByte; 00053 00054 if (removeZeros) { 00055 // remove trailing zeros; note that they're trailing because the 00056 // segments in pByteSeg are backwards 00057 while (len > 0 && *pByteSeg == 0) { 00058 pByteSeg++; 00059 len--; 00060 } 00061 00062 // remove leading zeros 00063 PBuffer bufPtr = pByteSeg + len - 1; 00064 while (len > 0 && *bufPtr == 0) { 00065 bufPtr--; 00066 len--; 00067 startRid += LbmSegment::LbmOneByteSize; 00068 } 00069 } 00070 00071 while (len > 0) { 00072 // determine if there are any intermediate zeros 00073 uint subLen; 00074 if (!removeZeros) { 00075 subLen = len; 00076 } else { 00077 for (subLen = 0; subLen < len; subLen++) { 00078 if (pByteSeg[len - 1 - subLen] == 0) { 00079 break; 00080 } 00081 } 00082 } 00083 00084 // write out the first set of segments up to the first intermediate 00085 // zero, if there is one; otherwise, we just end up writing out 00086 // all of the segments passed in 00087 00088 bitmapTuple[0].pData = (PConstBuffer) &startRid; 00089 // if the length can't be encoded in a segment descriptor, then 00090 // we have to treat this bitmap as a single bitmap 00091 if (LbmSegment::setSegLength(segDescByte, subLen)) { 00092 bitmapTuple[1].pData = &segDescByte; 00093 bitmapTuple[1].cbData = 1; 00094 } else { 00095 bitmapTuple[1].pData = NULL; 00096 bitmapTuple[1].cbData = 0; 00097 } 00098 bitmapTuple[2].pData = pByteSeg + len - subLen; 00099 bitmapTuple[2].cbData = subLen; 00100 00101 if (firstWrite) { 00102 segmentEntry.setEntryTuple(bitmapTuple); 00103 firstWrite = false; 00104 } else { 00105 if (!segmentEntry.mergeEntry(bitmapTuple)) { 00106 return false; 00107 } 00108 } 00109 00110 if (subLen == len) { 00111 break; 00112 } 00113 00114 // figure out how many more intermediate zeros there are 00115 while (pByteSeg[len - 1 - subLen] == 0) { 00116 subLen++; 00117 } 00118 00119 // adjust the next segment forward, past the intermediate zeros 00120 startRid += subLen * LbmSegment::LbmOneByteSize; 00121 len -= subLen; 00122 } 00123 00124 return true; 00125 } 00126 00127 TupleData const &LbmSegmentWriter::produceSegmentTuple() 00128 { 00129 return segmentEntry.produceEntryTuple(); 00130 } 00131 00132 FENNEL_END_CPPFILE("$Id: //open/dev/fennel/lucidera/bitmap/LbmSegmentWriter.cpp#8 $"); 00133 00134 // End LbmSegmentWriter.cpp