00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "fennel/common/CommonPreamble.h"
00024 #include "fennel/tuple/UnalignedAttributeAccessor.h"
00025 #include "fennel/tuple/TupleData.h"
00026
00027 FENNEL_BEGIN_CPPFILE("$Id: //open/dev/fennel/tuple/UnalignedAttributeAccessor.cpp#8 $");
00028
00029 UnalignedAttributeAccessor::UnalignedAttributeAccessor()
00030 {
00031 cbStorage = MAXU;
00032 }
00033
00034 UnalignedAttributeAccessor::UnalignedAttributeAccessor(
00035 TupleAttributeDescriptor const &attrDescriptor)
00036 {
00037 compute(attrDescriptor);
00038 }
00039
00040 void UnalignedAttributeAccessor::compute(
00041 TupleAttributeDescriptor const &attrDescriptor)
00042 {
00043 cbStorage = attrDescriptor.cbStorage;
00044 StoredTypeDescriptor::Ordinal typeOrdinal =
00045 attrDescriptor.pTypeDescriptor->getOrdinal();
00046 isCompressedInt64 =
00047 (typeOrdinal == STANDARD_TYPE_INT_64) ||
00048 (typeOrdinal == STANDARD_TYPE_UINT_64);
00049 omitLengthIndicator =
00050 !attrDescriptor.isNullable
00051 && !isCompressedInt64
00052 && (typeOrdinal != STANDARD_TYPE_VARCHAR)
00053 && (typeOrdinal != STANDARD_TYPE_VARBINARY)
00054 && (typeOrdinal != STANDARD_TYPE_UNICODE_VARCHAR);
00055 }
00056
00057 bool UnalignedAttributeAccessor::isInitialized() const
00058 {
00059 return !isMAXU(cbStorage);
00060 }
00061
00062 inline void UnalignedAttributeAccessor::compressInt64(
00063 TupleDatum const &datum,
00064 PBuffer pDest) const
00065 {
00066
00067
00068
00069
00070
00071
00072
00073 assert(datum.cbData == 8);
00074 int64_t intVal = *reinterpret_cast<int64_t const *> (datum.pData);
00075 uint len;
00076
00077 if (intVal >= 0) {
00078 FixedBuffer tmpBuf[8];
00079 PBuffer pTmpBuf = tmpBuf + 8;
00080 len = 0;
00081 do {
00082 *(--pTmpBuf) = intVal & 0xff;
00083 len++;
00084 intVal >>= 8;
00085 } while (intVal);
00086
00087
00088
00089 if (*pTmpBuf & 0x80) {
00090 *(--pTmpBuf) = 0;
00091 len++;
00092 }
00093 *pDest = static_cast<uint8_t>(len);
00094 memcpy(pDest + 1, pTmpBuf, len);
00095 } else {
00096
00097 if (intVal >= -(0x80)) {
00098 len = 1;
00099 } else if (intVal >= -(0x8000)) {
00100 len = 2;
00101 } else if (intVal >= -(0x800000)) {
00102 len = 3;
00103 } else if (intVal >= -(0x80000000LL)) {
00104 len = 4;
00105 } else if (intVal >= -(0x8000000000LL)) {
00106 len = 5;
00107 } else if (intVal >= -(0x800000000000LL)) {
00108 len = 6;
00109 } else if (intVal >= -(0x80000000000000LL)) {
00110 len = 7;
00111 } else {
00112 len = 8;
00113 }
00114 *pDest = static_cast<uint8_t>(len);
00115 PBuffer pTmpBuf = pDest + 1 + len;
00116 while (len--) {
00117 *(--pTmpBuf) = intVal & 0xff;
00118 intVal >>= 8;
00119 }
00120 }
00121 }
00122
00123 inline void UnalignedAttributeAccessor::uncompressInt64(
00124 TupleDatum &datum,
00125 PConstBuffer pDataWithLen) const
00126 {
00127 uint len = *pDataWithLen;
00128 assert(len != 0);
00129 PConstBuffer pSrcBuf = pDataWithLen + 1;
00130 uint signByte = *(pSrcBuf++);
00131
00132 int64_t intVal =
00133 int64_t(signByte) | ((signByte & 0x80) ? 0xffffffffffffff00LL : 0);
00134 while (--len > 0) {
00135 intVal <<= 8;
00136 intVal |= *(pSrcBuf++);
00137 }
00138 datum.cbData = 8;
00139
00140
00141
00142 memcpy(const_cast<PBuffer>(datum.pData), &intVal, 8);
00143 }
00144
00145 void UnalignedAttributeAccessor::storeValue(
00146 TupleDatum const &datum,
00147 PBuffer pDataWithLen) const
00148 {
00149 assert(isInitialized());
00150
00151 PBuffer tmpDataPtr = pDataWithLen;
00152
00153 if (!datum.pData) {
00154
00155
00156
00157 *tmpDataPtr = 0x00;
00158 } else {
00159
00160
00161
00162
00163 assert(datum.cbData <= TWO_BYTE_MAX_LENGTH);
00164
00165 if (isCompressedInt64) {
00166
00167 compressInt64(datum, tmpDataPtr);
00168 } else {
00169
00170
00171 if (!omitLengthIndicator) {
00172 if (datum.cbData && (datum.cbData <= ONE_BYTE_MAX_LENGTH)) {
00173 *tmpDataPtr = static_cast<uint8_t>(datum.cbData);
00174 tmpDataPtr++;
00175 } else {
00176 uint8_t higherByte =
00177 (datum.cbData & TWO_BYTE_LENGTH_MASK1) >> 8 |
00178 TWO_BYTE_LENGTH_BIT;
00179 uint8_t lowerByte = datum.cbData & TWO_BYTE_LENGTH_MASK2;
00180 *tmpDataPtr = higherByte;
00181 tmpDataPtr++;
00182 *tmpDataPtr = lowerByte;
00183 tmpDataPtr++;
00184 }
00185 }
00186
00187
00188 memcpy(tmpDataPtr, datum.pData, datum.cbData);
00189 }
00190 }
00191 }
00192
00193 void UnalignedAttributeAccessor::loadValue(
00194 TupleDatum &datum,
00195 PConstBuffer pDataWithLen) const
00196 {
00197 assert(isInitialized());
00198 assert(datum.pData);
00199
00200
00201 if (omitLengthIndicator) {
00202 datum.cbData = cbStorage;
00203 memcpy(const_cast<PBuffer>(datum.pData), pDataWithLen, datum.cbData);
00204 } else {
00205 uint8_t firstByte = *pDataWithLen;
00206 if (!firstByte) {
00207
00208 datum.pData = NULL;
00209 } else if (firstByte & TWO_BYTE_LENGTH_BIT) {
00210
00211
00212 datum.cbData =
00213 ((firstByte & ONE_BYTE_LENGTH_MASK) << 8)
00214 | *(pDataWithLen + 1);
00215 memcpy(
00216 const_cast<PBuffer>(datum.pData),
00217 pDataWithLen + 2,
00218 datum.cbData);
00219 } else {
00220 if (isCompressedInt64) {
00221
00222 uncompressInt64(datum, pDataWithLen);
00223 } else {
00224
00225 datum.cbData = firstByte;
00226 memcpy(
00227 const_cast<PBuffer>(datum.pData),
00228 pDataWithLen + 1,
00229 datum.cbData);
00230 }
00231 }
00232 }
00233 }
00234
00235 TupleStorageByteLength UnalignedAttributeAccessor::getStoredByteCount(
00236 PConstBuffer pDataWithLen) const
00237 {
00238 assert(isInitialized());
00239 assert(pDataWithLen);
00240
00241 if (omitLengthIndicator) {
00242 return cbStorage;
00243 }
00244
00245 if (*pDataWithLen & TWO_BYTE_LENGTH_BIT) {
00246 return
00247 (((*pDataWithLen & ONE_BYTE_LENGTH_MASK) << 8)
00248 | *(pDataWithLen + 1))
00249 + 2;
00250 } else {
00251 return (*pDataWithLen + 1);
00252 }
00253 }
00254
00255 TupleStorageByteLength UnalignedAttributeAccessor::getMaxByteCount() const
00256 {
00257 assert(isInitialized());
00258
00259 if (omitLengthIndicator) {
00260 return cbStorage;
00261 } else {
00262 return cbStorage + 2;
00263 }
00264 }
00265
00266 FENNEL_END_CPPFILE("$Id: //open/dev/fennel/tuple/UnalignedAttributeAccessor.cpp#8 $");
00267
00268