Fennel: /home/pub/open/dev/fennel/tuple/TupleAccessor.cpp Source File (original) (raw)

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/tuple/TupleAccessor.h" 00026 #include "fennel/tuple/TupleDescriptor.h" 00027 #include "fennel/tuple/TupleData.h" 00028 #include "fennel/tuple/AttributeAccessorImpl.h" 00029 #include "fennel/tuple/StoredTypeDescriptor.h" 00030 #include <boost/lambda/bind.hpp> 00031 #include <boost/lambda/construct.hpp> 00032 00033 FENNEL_BEGIN_CPPFILE("$Id: //open/dev/fennel/tuple/TupleAccessor.cpp#18 $"); 00034 00035 const bool TupleAccessor::BOOL_TRUE = true; 00036 00037 const bool TupleAccessor::BOOL_FALSE = false; 00038 00039 00040 00041 00042 00043 00044 00045 00046 00047 00048 #define DEBUG_TUPLE_ACCESS 0 00049 00053 static const MagicNumber TUPLE_MAGIC_NUMBER = 0x9897ab509de7dcf5LL; 00054 00055 TupleAccessor::TupleAccessor() 00056 { 00057 pTupleBuf = NULL; 00058 } 00059 00060 TupleAccessor::~TupleAccessor() 00061 { 00062 clear(); 00063 } 00064 00065 void TupleAccessor::clear() 00066 { 00067 using namespace boost::lambda; 00068 std::for_each( 00069 ppAttributeAccessors.begin(), 00070 ppAttributeAccessors.end(), 00071 bind(delete_ptr(),_1)); 00072 ppAttributeAccessors.clear(); 00073 pVarWidthAttrIndices.clear(); 00074 marshalOrder.clear(); 00075 pTupleBuf = NULL; 00076 bAlignedVar = false; 00077 } 00078 00079 00080 00081 00082 00083 00084 00085 void TupleAccessor::compute( 00086 TupleDescriptor const &tuple,TupleFormat formatInit) 00087 { 00088 clear(); 00089 format = formatInit; 00090 00091
00092
00093 VectorOfUint aligned8; 00094 VectorOfUint aligned4; 00095 VectorOfUint aligned2; 00096 VectorOfUint unalignedFixed; 00097 VectorOfUint unalignedVar; 00098 VectorOfUint alignedVar2; 00099 00100
00101
00102 AttributeAccessor *pFirstVariableAccessor = NULL; 00103 00104
00105 nBitFields = 0; 00106 00107
00108 uint cbVarDataMax = 0; 00109 00110
00111
00112 cbMaxStorage = 0; 00113 00114 #if DEBUG_TUPLE_ACCESS 00115 cbMaxStorage += sizeof(MagicNumber); 00116 #endif 00117 00118
00119
00120 for (uint iAttr = 0; iAttr < tuple.size(); iAttr++) { 00121 AttributeAccessor *pNewAccessor; 00122 TupleAttributeDescriptor const &attr = tuple[iAttr]; 00123 uint cbFixed = attr.pTypeDescriptor->getFixedByteCount(); 00124 uint cbMin = attr.pTypeDescriptor->getMinByteCount(attr.cbStorage); 00125 if (cbFixed) { 00126 assert(cbFixed == attr.cbStorage); 00127 assert(cbFixed == cbMin); 00128 } 00129 bool bFixedWidth = (cbMin == attr.cbStorage); 00130 if (bFixedWidth && !attr.cbStorage) { 00131 if (!attr.pTypeDescriptor->getMinByteCount(1)) { 00132
00133
00134 bFixedWidth = false; 00135 } 00136 } 00137 bool bNullable = attr.isNullable; 00138 uint nBits = (attr.pTypeDescriptor->getBitCount()); 00139 assert(nBits <= 1); 00140 if (format == TUPLE_FORMAT_ALL_FIXED) { 00141 bFixedWidth = true; 00142 nBits = 0; 00143 } 00144 uint iAlign = attr.pTypeDescriptor->getAlignmentByteCount( 00145 attr.cbStorage); 00146 if (!bFixedWidth) { 00147 cbVarDataMax += attr.cbStorage; 00148 if (iAlign == 2) { 00149 alignedVar2.push_back(iAttr); 00150 bAlignedVar = true; 00151 } else { 00152 assert(iAlign == 1); 00153 unalignedVar.push_back(iAttr); 00154 } 00155
00156
00157
00158
00159 pNewAccessor = new VarOffsetAccessor(); 00160 } else if (nBits) { 00161 if (bNullable) { 00162 pNewAccessor = new NullableAccessor; 00163 } else { 00164 pNewAccessor = new BitAccessor; 00165 } 00166 pNewAccessor->iValueBit = nBitFields; 00167 nBitFields++; 00168 } else { 00169 assert((cbMin % iAlign) == 0); 00170 bool bArray = 00171 StandardTypeDescriptor::isArray( 00172 StandardTypeDescriptorOrdinal( 00173 attr.pTypeDescriptor->getOrdinal())); 00174 switch (iAlign) { 00175 case 2: 00176 if (bNullable) { 00177 if ((format == TUPLE_FORMAT_NETWORK) && !bArray) { 00178 pNewAccessor = 00179 new NullableAccessor; 00180 } else { 00181 pNewAccessor = 00182 new NullableAccessor; 00183 } 00184 } else { 00185 if ((format == TUPLE_FORMAT_NETWORK) && !bArray) { 00186 pNewAccessor = new FixedWidthNetworkAccessor16; 00187 } else { 00188 pNewAccessor = new FixedWidthAccessor; 00189 } 00190 } 00191 break; 00192 case 4: 00193 if (bNullable) { 00194 if (format == TUPLE_FORMAT_NETWORK) { 00195 pNewAccessor = 00196 new NullableAccessor; 00197 } else { 00198 pNewAccessor = 00199 new NullableAccessor; 00200 } 00201 } else { 00202 if (format == TUPLE_FORMAT_NETWORK) { 00203 pNewAccessor = new FixedWidthNetworkAccessor32; 00204 } else { 00205 pNewAccessor = new FixedWidthAccessor; 00206 } 00207 } 00208 break; 00209 case 8: 00210 if (bNullable) { 00211 if (format == TUPLE_FORMAT_NETWORK) { 00212 pNewAccessor = 00213 new NullableAccessor; 00214 } else { 00215 pNewAccessor = 00216 new NullableAccessor; 00217 } 00218 } else { 00219 if (format == TUPLE_FORMAT_NETWORK) { 00220 pNewAccessor = new FixedWidthNetworkAccessor64; 00221 } else { 00222 pNewAccessor = new FixedWidthAccessor; 00223 } 00224 } 00225 break; 00226 default: 00227 if (bNullable) { 00228 pNewAccessor = new NullableAccessor; 00229 } else { 00230 pNewAccessor = new FixedWidthAccessor; 00231 } 00232 break; 00233 } 00234 switch (iAlign) { 00235 case 1: 00236 unalignedFixed.push_back(iAttr); 00237 break; 00238 case 2: 00239 aligned2.push_back(iAttr); 00240 break; 00241 case 4: 00242 aligned4.push_back(iAttr); 00243 break; 00244 case 8: 00245 aligned8.push_back(iAttr); 00246 break; 00247 default: 00248 permAssert(false); 00249 } 00250 } 00251 if (bNullable) { 00252 pNewAccessor->iNullBit = nBitFields; 00253 nBitFields++; 00254 } 00255 pNewAccessor->cbStorage = attr.cbStorage; 00256 ppAttributeAccessors.push_back(pNewAccessor); 00257 } 00258 bitFields.resize(nBitFields); 00259 00260
00261
00262 pVarWidthAttrIndices.resize(alignedVar2.size() + unalignedVar.size()); 00263 std::copy( 00264 alignedVar2.begin(), alignedVar2.end(), 00265 pVarWidthAttrIndices.begin()); 00266 std::copy( 00267 unalignedVar.begin(), unalignedVar.end(), 00268 pVarWidthAttrIndices.begin() + alignedVar2.size()); 00269 for (uint i = 0; i < pVarWidthAttrIndices.size(); ++i) { 00270 uint iAttr = pVarWidthAttrIndices[i]; 00271 TupleAttributeDescriptor const &attr = tuple[iAttr]; 00272 bool bNullable = attr.isNullable; 00273 AttributeAccessor *pNewAccessor; 00274 if (pFirstVariableAccessor) { 00275 if (bNullable) { 00276 if (format == TUPLE_FORMAT_NETWORK) { 00277 pNewAccessor = 00278 new NullableAccessor< VarOffsetAccessor >; 00279 } else { 00280 pNewAccessor = 00281 new NullableAccessor< VarOffsetAccessor >; 00282 } 00283 } else { 00284 if (format == TUPLE_FORMAT_NETWORK) { 00285 pNewAccessor = new VarOffsetAccessor; 00286 } else { 00287 pNewAccessor = new VarOffsetAccessor; 00288 } 00289 } 00290 } else { 00291 if (bNullable) { 00292 if (format == TUPLE_FORMAT_NETWORK) { 00293 pFirstVariableAccessor = 00294 new NullableAccessor< 00295 FixedOffsetVarWidthAccessor >; 00296 } else { 00297 pFirstVariableAccessor = 00298 new NullableAccessor< 00299 FixedOffsetVarWidthAccessor >; 00300 } 00301 } else { 00302 if (format == TUPLE_FORMAT_NETWORK) { 00303 pFirstVariableAccessor = 00304 new FixedOffsetVarWidthAccessor; 00305 } else { 00306 pFirstVariableAccessor = 00307 new FixedOffsetVarWidthAccessor; 00308 } 00309 } 00310 pNewAccessor = pFirstVariableAccessor; 00311 } 00312 AttributeAccessor *pPlaceholder = ppAttributeAccessors[iAttr]; 00313 pNewAccessor->cbStorage = attr.cbStorage; 00314 pNewAccessor->iNullBit = pPlaceholder->iNullBit; 00315
00316 ppAttributeAccessors[iAttr] = pNewAccessor; 00317 delete pPlaceholder; 00318 } 00319 00320
00321
00322 initFixedAccessors(tuple,aligned8); 00323 initFixedAccessors(tuple,aligned4); 00324 initFixedAccessors(tuple,aligned2); 00325 00326 if (pFirstVariableAccessor) { 00327 iFirstVarEndIndirectOffset = cbMaxStorage; 00328 } else { 00329 iFirstVarEndIndirectOffset = MAXU; 00330 } 00331 00332 for (uint i = 0; i < pVarWidthAttrIndices.size(); i++) { 00333 ppAttributeAccessors[pVarWidthAttrIndices[i]]->iEndIndirectOffset = 00334 cbMaxStorage; 00335 cbMaxStorage += sizeof(StoredValueOffset); 00336 } 00337 00338 if (pFirstVariableAccessor) { 00339 iLastVarEndIndirectOffset = cbMaxStorage - sizeof(StoredValueOffset); 00340 } else { 00341 iLastVarEndIndirectOffset = MAXU; 00342 } 00343 00344 initFixedAccessors(tuple,unalignedFixed); 00345 00346 if (nBitFields) { 00347 iBitFieldOffset = cbMaxStorage; 00348 } else { 00349 iBitFieldOffset = MAXU; 00350 } 00351 cbMaxStorage += bytesForBits(nBitFields); 00352 if (pFirstVariableAccessor) { 00353 if (bAlignedVar) { 00354
00355
00356 if (cbMaxStorage & 1) { 00357 ++cbMaxStorage; 00358 } 00359 } 00360 pFirstVariableAccessor->iFixedOffset = cbMaxStorage; 00361 iFirstVarOffset = cbMaxStorage; 00362 } else { 00363 iFirstVarOffset = MAXU; 00364 } 00365 cbMinStorage = cbMaxStorage; 00366 cbMaxStorage += cbVarDataMax; 00367 00368
00369
00370
00371 if (cbMaxStorage) { 00372 cbMinStorage = 1; 00373 cbMaxStorage = 1; 00374 } 00375 00376
00377
00378
00379 cbMinStorage = alignRoundUp(cbMinStorage); 00380 cbMaxStorage = alignRoundUp(cbMaxStorage); 00381 00382
00383
00384 if (bAlignedVar) { 00385
00386 for (uint i = 0; i < tuple.size(); ++i) { 00387 AttributeAccessor const &accessor = getAttributeAccessor(i); 00388 if (isMAXU(accessor.iEndIndirectOffset)) { 00389 marshalOrder.push_back(i); 00390 } 00391 } 00392 uint nFixed = marshalOrder.size(); 00393 assert(nFixed + pVarWidthAttrIndices.size() == tuple.size()); 00394 marshalOrder.resize(tuple.size()); 00395
00396 std::copy( 00397 pVarWidthAttrIndices.begin(), 00398 pVarWidthAttrIndices.end(), 00399 marshalOrder.begin() + nFixed); 00400 } 00401 } 00402 00403 void TupleAccessor::initFixedAccessors( 00404 TupleDescriptor const &tuple,VectorOfUint &v) 00405 { 00406 for (uint i = 0; i < v.size(); i++) { 00407 uint iAttr = v[i]; 00408 TupleAttributeDescriptor const &attr = tuple[iAttr]; 00409 AttributeAccessor &accessor = *(ppAttributeAccessors[iAttr]); 00410 accessor.iFixedOffset = cbMaxStorage; 00411 cbMaxStorage += attr.cbStorage; 00412 } 00413 } 00414 00415 uint TupleAccessor::getBufferByteCount(PConstBuffer pBuf) const 00416 { 00417 if (isFixedWidth()) { 00418 return cbMaxStorage; 00419 } else { 00420
00421
00422 StoredValueOffset cb = 00423 *referenceIndirectOffset( 00424 const_cast(pBuf), 00425 iLastVarEndIndirectOffset); 00426 if (format == TUPLE_FORMAT_NETWORK) { 00427 cb = ntohs(cb); 00428 } 00429
00430 return alignRoundUp(cb); 00431 } 00432 } 00433 00434 uint TupleAccessor::getByteCount(TupleData const &tuple) const 00435 { 00436 if (isFixedWidth()) { 00437 return cbMaxStorage; 00438 } else { 00439
00440 uint cb = iFirstVarOffset; 00441 for (uint i = 0; i < pVarWidthAttrIndices.size(); ++i) { 00442 TupleDatum const &datum = tuple[pVarWidthAttrIndices[i]]; 00443 if (datum.pData) { 00444 cb += datum.cbData; 00445 } 00446 } 00447
00448 return alignRoundUp(cb); 00449 } 00450 } 00451 00452 bool TupleAccessor::isBufferSufficient( 00453 TupleData const &tuple,uint cbBuffer) const 00454 { 00455
00456 if (getMaxByteCount() <= cbBuffer) { 00457 return true; 00458 } 00459
00460 return getByteCount(tuple) <= cbBuffer; 00461 } 00462 00463 void TupleAccessor::setCurrentTupleBuf(PConstBuffer pTupleBufInit, bool valid) 00464 { 00465 assert(pTupleBufInit); 00466 pTupleBuf = pTupleBufInit;
00467 if (isMAXU(iBitFieldOffset)) { 00468
00469 if (valid) { 00470 #if DEBUG_TUPLE_ACCESS 00471 assert( 00472 *reinterpret_cast<MagicNumber const *>(pTupleBuf) 00473 == TUPLE_MAGIC_NUMBER); 00474 #endif 00475
00476 boost::from_block_range( 00477 pTupleBuf + iBitFieldOffset, 00478 pTupleBuf + iBitFieldOffset + bitFields.num_blocks(), 00479 bitFields); 00480 } 00481 } 00482 } 00483 00484 void TupleAccessor::resetCurrentTupleBuf() 00485 { 00486 pTupleBuf = NULL; 00487 } 00488 00489 void TupleAccessor::unmarshal(TupleData &tuple,uint iFirstDatum) const 00490 { 00491 uint n = std::min(tuple.size() - iFirstDatum,ppAttributeAccessors.size()); 00492 00493 if ((format == TUPLE_FORMAT_NETWORK) || bAlignedVar) { 00494
00495 for (uint i = 0; i < n; ++i) { 00496 getAttributeAccessor(i).unmarshalValue( 00497 *this,tuple[iFirstDatum + i]); 00498 } 00499 return; 00500 } 00501 00502
00503
00504 00505 uint iNextVarOffset = iFirstVarOffset; 00506 StoredValueOffset const *pNextVarEndOffset = 00507 referenceIndirectOffset(iFirstVarEndIndirectOffset); 00508 00509 for (uint i = 0; i < n; i++) { 00510 TupleDatum &value = tuple[i + iFirstDatum]; 00511 AttributeAccessor const &accessor = getAttributeAccessor(i); 00512 if (isMAXU(accessor.iNullBit)) { 00513 if (bitFields[accessor.iNullBit]) { 00514 value.pData = NULL; 00515 if (isMAXU(accessor.iEndIndirectOffset)) { 00516 pNextVarEndOffset++; 00517 } 00518 continue; 00519 } 00520 } 00521 if (isMAXU(accessor.iFixedOffset)) { 00522 value.pData = getCurrentTupleBuf() + accessor.iFixedOffset; 00523 } else if (isMAXU(accessor.iValueBit)) { 00524 value.pData = getCurrentTupleBuf() + iNextVarOffset; 00525 } else { 00526 static_cast<BitAccessor const &>(accessor).unmarshalValue( 00527 *this,value); 00528 } 00529 if (isMAXU(accessor.iEndIndirectOffset)) { 00530 assert(pNextVarEndOffset == 00531 referenceIndirectOffset(accessor.iEndIndirectOffset)); 00532 uint iEndOffset = *pNextVarEndOffset; 00533 pNextVarEndOffset++; 00534 value.cbData = iEndOffset - iNextVarOffset; 00535 iNextVarOffset = iEndOffset; 00536 } 00537 assert(value.cbData <= accessor.cbStorage); 00538 } 00539 } 00540 00541 void TupleAccessor::marshal(TupleData const &tuple,PBuffer pTupleBufDest) 00542 { 00543 #if DEBUG_TUPLE_ACCESS 00544 *reinterpret_cast<MagicNumber *>(pTupleBufDest) = TUPLE_MAGIC_NUMBER; 00545 #endif 00546 00547 pTupleBuf = pTupleBufDest; 00548 00549 uint iNextVarOffset = iFirstVarOffset; 00550 StoredValueOffset *pNextVarEndOffset = 00551 referenceIndirectOffset(pTupleBufDest,iFirstVarEndIndirectOffset); 00552 00553 for (uint i = 0; i < tuple.size(); i++) { 00554 uint iAttr; 00555 if (bAlignedVar) { 00556 iAttr = marshalOrder[i]; 00557 } else { 00558 iAttr = i; 00559 } 00560 TupleDatum const &value = tuple[iAttr]; 00561 AttributeAccessor const &accessor = getAttributeAccessor(iAttr); 00562 if (isMAXU(accessor.iNullBit)) { 00563 bitFields[accessor.iNullBit] = value.pData ? false : true; 00564 } 00565 if (value.pData) { 00566 if (isMAXU(accessor.iValueBit)) { 00567 uint iOffset; 00568 if (isMAXU(accessor.iFixedOffset)) { 00569 iOffset = accessor.iFixedOffset; 00570 } else { 00571 iOffset = iNextVarOffset; 00572 } 00573 assert(value.cbData <= accessor.cbStorage); 00574 accessor.marshalValueData( 00575 pTupleBufDest + iOffset, 00576 value); 00577 } else { 00578 bitFields[accessor.iValueBit] = 00579 *reinterpret_cast<bool const *>(value.pData); 00580 } 00581 } else { 00582
00583
00584
00585 assert(isMAXU(accessor.iNullBit)); 00586 } 00587 if (isMAXU(accessor.iEndIndirectOffset)) { 00588 assert(pNextVarEndOffset == 00589 referenceIndirectOffset(accessor.iEndIndirectOffset)); 00590 if (value.pData) { 00591 iNextVarOffset += value.cbData; 00592 } 00593
00594
00595
00596 if (format == TUPLE_FORMAT_NETWORK) { 00597 *pNextVarEndOffset = 00598 htons(static_cast(iNextVarOffset)); 00599 } else { 00600 *pNextVarEndOffset = iNextVarOffset; 00601 } 00602 pNextVarEndOffset++; 00603 } 00604 } 00605 if (isMAXU(iBitFieldOffset)) { 00606
00607 boost::to_block_range( 00608 bitFields, 00609 pTupleBufDest + iBitFieldOffset); 00610 } 00611 } 00612 00613 FENNEL_END_CPPFILE("$Id: //open/dev/fennel/tuple/TupleAccessor.cpp#18 $"); 00614 00615