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<false>();
00160 } else if (nBits) {
00161 if (bNullable) {
00162 pNewAccessor = new NullableAccessor<BitAccessor>;
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<FixedWidthNetworkAccessor16>;
00180 } else {
00181 pNewAccessor =
00182 new NullableAccessor<FixedWidthAccessor>;
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<FixedWidthNetworkAccessor32>;
00197 } else {
00198 pNewAccessor =
00199 new NullableAccessor<FixedWidthAccessor>;
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<FixedWidthNetworkAccessor64>;
00214 } else {
00215 pNewAccessor =
00216 new NullableAccessor<FixedWidthAccessor>;
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<FixedWidthAccessor>;
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<true> >;
00279 } else {
00280 pNewAccessor =
00281 new NullableAccessor< VarOffsetAccessor<false> >;
00282 }
00283 } else {
00284 if (format == TUPLE_FORMAT_NETWORK) {
00285 pNewAccessor = new VarOffsetAccessor<true>;
00286 } else {
00287 pNewAccessor = new VarOffsetAccessor<false>;
00288 }
00289 }
00290 } else {
00291 if (bNullable) {
00292 if (format == TUPLE_FORMAT_NETWORK) {
00293 pFirstVariableAccessor =
00294 new NullableAccessor<
00295 FixedOffsetVarWidthAccessor<true> >;
00296 } else {
00297 pFirstVariableAccessor =
00298 new NullableAccessor<
00299 FixedOffsetVarWidthAccessor<false> >;
00300 }
00301 } else {
00302 if (format == TUPLE_FORMAT_NETWORK) {
00303 pFirstVariableAccessor =
00304 new FixedOffsetVarWidthAccessor<true>;
00305 } else {
00306 pFirstVariableAccessor =
00307 new FixedOffsetVarWidthAccessor<false>;
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<PBuffer>(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<StoredValueOffset>(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