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/TupleDescriptor.h"
00026 #include "fennel/tuple/TupleData.h"
00027 #include "fennel/tuple/StandardTypeDescriptor.h"
00028 #include "fennel/tuple/StoredTypeDescriptor.h"
00029 #include "fennel/tuple/StoredTypeDescriptorFactory.h"
00030 #include "fennel/common/DataVisitor.h"
00031 #include "fennel/common/ByteInputStream.h"
00032 #include "fennel/common/ByteOutputStream.h"
00033
00034
00035
00036 #include "fennel/tuple/AttributeAccessorImpl.h"
00037
00038 FENNEL_BEGIN_CPPFILE("$Id: //open/dev/fennel/tuple/TupleDescriptor.cpp#23 $");
00039
00040 TupleAttributeDescriptor::TupleAttributeDescriptor()
00041 {
00042 pTypeDescriptor = NULL;
00043 isNullable = false;
00044 cbStorage = 0;
00045 }
00046
00047 TupleAttributeDescriptor::TupleAttributeDescriptor(
00048 StoredTypeDescriptor const &typeDescriptor,
00049 bool isNullableInit,
00050 TupleStorageByteLength cbStorageInit)
00051 {
00052 pTypeDescriptor = &typeDescriptor;
00053 isNullable = isNullableInit;
00054 if (cbStorageInit) {
00055 uint cbFixed = typeDescriptor.getFixedByteCount();
00056 assert(!cbFixed || (cbFixed == cbStorageInit));
00057 cbStorage = cbStorageInit;
00058 } else {
00059 cbStorage = typeDescriptor.getFixedByteCount();
00060 }
00061 }
00062
00063 bool TupleAttributeDescriptor::operator == (
00064 TupleAttributeDescriptor const &other) const
00065 {
00066 return
00067 (pTypeDescriptor->getOrdinal() == other.pTypeDescriptor->getOrdinal())
00068 && (isNullable == other.isNullable)
00069 && (cbStorage == other.cbStorage);
00070 }
00071
00072 void TupleDescriptor::projectFrom(
00073 TupleDescriptor const &tupleDescriptor,
00074 TupleProjection const &tupleProjection)
00075 {
00076 clear();
00077 for (uint i = 0; i < tupleProjection.size(); ++i) {
00078 push_back(tupleDescriptor[tupleProjection[i]]);
00079 }
00080 }
00081
00082 int TupleDescriptor::compareTuples(
00083 TupleData const &tuple1,
00084 TupleData const &tuple2) const
00085 {
00086 int keyComp;
00087
00088 size_t keyCount = std::min(tuple1.size(),tuple2.size());
00089 keyCount = std::min(keyCount,size());
00090 keyComp = compareTuplesKey(tuple1, tuple2, keyCount);
00091 return keyComp;
00092 }
00093
00094 int TupleDescriptor::compareTuples(
00095 TupleData const &tuple1, TupleProjection const &proj1,
00096 TupleData const &tuple2, TupleProjection const &proj2,
00097 bool *containsNullKey) const
00098 {
00099 size_t keyCount = std::min(proj1.size(), proj2.size());
00100
00101 if (containsNullKey) {
00102 *containsNullKey = false;
00103 }
00104 for (uint i = 0; i < keyCount; ++i) {
00105 TupleDatum const &datum1 = tuple1[proj1[i]];
00106 TupleDatum const &datum2 = tuple2[proj2[i]];
00107
00108 if (!datum1.pData) {
00109 if (containsNullKey) {
00110 *containsNullKey = true;
00111 }
00112 if (!datum2.pData) {
00113 continue;
00114 }
00115 return -(i + 1);
00116 } else if (!datum2.pData) {
00117 if (containsNullKey) {
00118 *containsNullKey = true;
00119 }
00120 return (i + 1);
00121 }
00122 int c = (*this)[i].pTypeDescriptor->compareValues(
00123 datum1.pData,
00124 datum1.cbData,
00125 datum2.pData,
00126 datum2.cbData);
00127 if (c > 0) {
00128 return (i + 1);
00129 } else if (c < 0) {
00130 return -(i + 1);
00131 }
00132 }
00133 return 0;
00134
00135 }
00136
00137 int TupleDescriptor::compareTuplesKey(
00138 TupleData const &tuple1,
00139 TupleData const &tuple2,
00140 uint keyCount) const
00141 {
00142 assert(keyCount <= std::min(tuple1.size(), tuple2.size()));
00143
00144 for (uint i = 0; i < keyCount; ++i) {
00145 TupleDatum const &datum1 = tuple1[i];
00146 TupleDatum const &datum2 = tuple2[i];
00147
00148 if (!datum1.pData) {
00149 if (!datum2.pData) {
00150 continue;
00151 }
00152 return -(i + 1);
00153 } else if (!datum2.pData) {
00154 return (i + 1);
00155 }
00156 int c = (*this)[i].pTypeDescriptor->compareValues(
00157 datum1.pData,
00158 datum1.cbData,
00159 datum2.pData,
00160 datum2.cbData);
00161 if (c > 0) {
00162 return (i + 1);
00163 } else if (c < 0) {
00164 return -(i + 1);
00165 }
00166 }
00167 return 0;
00168 }
00169
00170 void TupleDescriptor::visit(
00171 TupleData const &tuple,
00172 DataVisitor &dataVisitor,
00173 bool visitLengths) const
00174 {
00175 for (uint i = 0; i < tuple.size(); ++i) {
00176 if (!tuple[i].pData) {
00177 if (visitLengths) {
00178 dataVisitor.visitUnsignedInt(0);
00179 }
00180 dataVisitor.visitBytes(NULL,0);
00181 } else {
00182 if (visitLengths) {
00183 dataVisitor.visitUnsignedInt(tuple[i].cbData);
00184 }
00185 (*this)[i].pTypeDescriptor->visitValue(
00186 dataVisitor,
00187 tuple[i].pData,
00188 tuple[i].cbData);
00189 }
00190 }
00191 }
00192
00193
00194
00195
00196
00197
00198
00199 void TupleDescriptor::writePersistent(ByteOutputStream &stream) const
00200 {
00201 uint32_t iData = htonl(size());
00202 stream.writeValue(iData);
00203 for (uint i = 0; i < size(); ++i) {
00204 TupleAttributeDescriptor const &attrDesc = (*this)[i];
00205 iData = htonl(attrDesc.pTypeDescriptor->getOrdinal());
00206 stream.writeValue(iData);
00207 iData = htonl(attrDesc.isNullable);
00208 stream.writeValue(iData);
00209
00210 iData = htonl(attrDesc.cbStorage);
00211 stream.writeValue(iData);
00212 }
00213 }
00214
00215 void TupleDescriptor::readPersistent(
00216 ByteInputStream &stream,
00217 StoredTypeDescriptorFactory const &typeFactory)
00218 {
00219 clear();
00220 uint32_t n;
00221 stream.readValue(n);
00222 n = ntohl(n);
00223 for (uint i = 0; i < n; ++i) {
00224 uint32_t iData;
00225 stream.readValue(iData);
00226 StoredTypeDescriptor const &typeDescriptor =
00227 typeFactory.newDataType(ntohl(iData));
00228 stream.readValue(iData);
00229 bool isNullable = ntohl(iData);
00230 stream.readValue(iData);
00231 TupleStorageByteLength cbStorage = ntohl(iData);
00232 push_back(
00233 TupleAttributeDescriptor(
00234 typeDescriptor,isNullable,cbStorage));
00235 }
00236 }
00237
00238 void TupleProjection::writePersistent(
00239 ByteOutputStream &stream) const
00240 {
00241 uint32_t iData = htonl(size());
00242 stream.writeValue(iData);
00243 for (uint i = 0; i < size(); ++i) {
00244 iData = htonl((*this)[i]);
00245 stream.writeValue(iData);
00246 }
00247 }
00248
00249 void TupleProjection::readPersistent(
00250 ByteInputStream &stream)
00251 {
00252 clear();
00253 uint32_t n;
00254 stream.readValue(n);
00255 n = ntohl(n);
00256 for (uint i = 0; i < n; ++i) {
00257 uint32_t iData;
00258 stream.readValue(iData);
00259 push_back(ntohl(iData));
00260 }
00261 }
00262
00263 void TupleProjection::projectFrom(
00264 TupleProjection const &sourceProjection,
00265 TupleProjection const &tupleProjection)
00266 {
00267 clear();
00268 for (uint i = 0; i < tupleProjection.size(); ++i) {
00269 push_back(sourceProjection[tupleProjection[i]]);
00270 }
00271 }
00272
00273 bool TupleDescriptor::containsNullable() const
00274 {
00275 for (uint i = 0; i < size(); ++i) {
00276 if ((*this)[i].isNullable) {
00277 return true;
00278 }
00279 }
00280 return false;
00281 }
00282
00283 bool TupleDescriptor::storageEqual(
00284 TupleDescriptor const &other) const
00285 {
00286 uint sz = size();
00287 if (other.size() != sz) {
00288 return false;
00289 }
00290
00291 TupleAttributeDescriptor const * us;
00292 TupleAttributeDescriptor const * them;
00293
00294 for (uint i = 0; i < sz; ++i) {
00295 us = &(*this)[i];
00296 them = &other[i];
00297 if ((us->pTypeDescriptor->getOrdinal() !=
00298 them->pTypeDescriptor->getOrdinal()) ||
00299 us->cbStorage != them->cbStorage) {
00300 return false;
00301 }
00302 }
00303 return true;
00304 }
00305
00306 TupleStorageByteLength TupleDescriptor::getMaxByteCount() const
00307 {
00308 TupleStorageByteLength length = 0;
00309
00310 for (uint i = 0; i < size(); i ++) {
00311 length += (*this)[i].cbStorage;
00312 }
00313 return length;
00314 }
00315
00316 std::ostream &operator<<(std::ostream &str,TupleDescriptor const &tupleDesc)
00317 {
00318 str << "{" << std::endl;
00319 for (uint i = 0; i < tupleDesc.size(); ++i) {
00320 str << "\t" << i << ": ";
00321 str << tupleDesc[i];
00322 str << std::endl;
00323 }
00324 str << "}" << std::endl;
00325 return str;
00326 }
00327
00328 std::ostream &operator<<(
00329 std::ostream &str,
00330 TupleAttributeDescriptor const &attrDesc)
00331 {
00332 StoredTypeDescriptor::Ordinal ordinal =
00333 attrDesc.pTypeDescriptor->getOrdinal();
00334
00335 if (ordinal < STANDARD_TYPE_END) {
00336 str << "type = " << StandardTypeDescriptor::toString(
00337 StandardTypeDescriptorOrdinal(ordinal));
00338 } else {
00339 str << "type ordinal = " << ordinal;
00340 }
00341 str << ", isNullable = " << attrDesc.isNullable;
00342 str << ", cbStorage = " << attrDesc.cbStorage;
00343 return str;
00344 }
00345
00346 FENNEL_END_CPPFILE("$Id: //open/dev/fennel/tuple/TupleDescriptor.cpp#23 $");
00347
00348