00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef __ZTupleIndex_T__
00026 #define __ZTupleIndex_T__
00027 #include "zconfig.h"
00028
00029 #include "ZTupleIndex.h"
00030
00031
00032 #pragma mark -
00033 #pragma mark * ZTupleIndex_T
00034
00035 template <int kPropCount>
00036 class ZTupleIndex_T : public ZTupleIndex
00037 {
00038 private:
00039 class Key
00040 {
00041 public:
00042 bool operator<(const Key& iOther) const
00043 {
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 const ZTupleValue* const* otherIter = &iOther.fValues[0];
00057
00058 const ZTupleValue* const* thisIter = &fValues[0];
00059
00060 for (size_t x = kPropCount; x; --x)
00061 {
00062 if (!*otherIter || !*thisIter)
00063 {
00064
00065 return false;
00066 }
00067
00068 if (int compare = (*thisIter)->Compare(**otherIter))
00069 return compare < 0;
00070 ++thisIter;
00071 ++otherIter;
00072 }
00073 return fID < iOther.fID;
00074 }
00075
00076 uint64 fID;
00077 const ZTupleValue* fValues[kPropCount];
00078 };
00079
00080 public:
00081 ZTupleIndex_T(const ZTuplePropName* iPropNames)
00082 {
00083 std::copy(iPropNames, iPropNames + kPropCount, fPropNames);
00084 }
00085
00086 virtual void Add(uint64 iID, const ZTuple* iTuple)
00087 {
00088 Key theKey;
00089 if (this->pKeyFromTuple(iID, iTuple, theKey))
00090 fSet.insert(theKey);
00091 }
00092
00093 virtual void Remove(uint64 iID, const ZTuple* iTuple)
00094 {
00095 Key theKey;
00096 if (this->pKeyFromTuple(iID, iTuple, theKey))
00097 fSet.erase(theKey);
00098 }
00099
00100 virtual void Find(const std::set<uint64>& iSkipIDs,
00101 std::vector<const ZTBSpec::Criterion*>& ioCriteria, std::vector<uint64>& oIDs)
00102 {
00103 typename set<Key>::const_iterator lowerBound, upperBound;
00104 if (this->pSetupIterators(ioCriteria, lowerBound, upperBound))
00105 {
00106 if (iSkipIDs.empty())
00107 {
00108 for (; lowerBound != upperBound; ++lowerBound)
00109 oIDs.push_back((*lowerBound).fID);
00110 }
00111 else
00112 {
00113 for (; lowerBound != upperBound; ++lowerBound)
00114 {
00115 if (iSkipIDs.end() == iSkipIDs.find((*lowerBound).fID))
00116 oIDs.push_back((*lowerBound).fID);
00117 }
00118 }
00119 }
00120 }
00121
00122 virtual size_t CanHandle(const ZTBSpec::CriterionSect& iCriterionSect)
00123 {
00124 vector<const ZTBSpec::Criterion*> remainingCriteria;
00125 remainingCriteria.reserve(iCriterionSect.size());
00126 for (ZTBSpec::CriterionSect::const_iterator i = iCriterionSect.begin(),
00127 theEnd = iCriterionSect.end();
00128 i != theEnd; ++i)
00129 {
00130 remainingCriteria.push_back(&(*i));
00131 }
00132
00133 size_t likelyResultSize = fSet.size();
00134
00135 size_t propertyCount = 0;
00136
00137 const ZTupleValue* valueEqual;
00138 const ZTupleValue* bestValueLess;
00139 const ZTupleValue* bestValueLessEqual;
00140 const ZTupleValue* bestValueGreater;
00141 const ZTupleValue* bestValueGreaterEqual;
00142
00143
00144
00145 for (const ZTuplePropName* propNameIter = fPropNames;
00146 propertyCount < kPropCount; ++propertyCount)
00147 {
00148 if (!sGatherMergeConstraints(*propNameIter++, remainingCriteria,
00149 valueEqual,
00150 bestValueLess, bestValueLessEqual, bestValueGreater, bestValueGreaterEqual))
00151 {
00152
00153 return 1;
00154 }
00155
00156 if (!valueEqual)
00157 break;
00158
00159 ZAssertStop(ZCONFIG_TupleIndex_Debug, !bestValueLess && !bestValueLessEqual
00160 && !bestValueGreater && !bestValueGreaterEqual);
00161
00162 likelyResultSize /= 2;
00163 }
00164
00165 if (propertyCount != kPropCount)
00166 {
00167
00168 if (bestValueLess || bestValueLessEqual || bestValueGreater || bestValueGreaterEqual)
00169 {
00170
00171 likelyResultSize /= 2;
00172 ++propertyCount;
00173 }
00174 }
00175
00176 if (!propertyCount)
00177 {
00178
00179 return 0;
00180 }
00181
00182
00183 return likelyResultSize + 1;
00184 }
00185
00186
00187
00188 private:
00189 bool pSetupIterators(std::vector<const ZTBSpec::Criterion*>& ioCriteria,
00190 typename std::set<Key>::const_iterator& oLowerBound, typename std::set<Key>::const_iterator& oUpperBound)
00191 {
00192 Key theKey;
00193
00194 theKey.fValues[0] = nil;
00195
00196 if (kPropCount > 1)
00197 theKey.fValues[1] = nil;
00198 if (kPropCount > 2)
00199 theKey.fValues[2] = nil;
00200 if (kPropCount > 3)
00201 theKey.fValues[3] = nil;
00202 if (kPropCount > 4)
00203 theKey.fValues[4] = nil;
00204 if (kPropCount > 5)
00205 {
00206 for (size_t x = 5; x < kPropCount; ++x)
00207 theKey.fValues[x] = nil;
00208 }
00209
00210 size_t keyPropCount = 0;
00211
00212 const ZTupleValue* valueEqual;
00213 const ZTupleValue* bestValueLess;
00214 const ZTupleValue* bestValueLessEqual;
00215 const ZTupleValue* bestValueGreater;
00216 const ZTupleValue* bestValueGreaterEqual;
00217
00218
00219
00220 for (const ZTuplePropName* propNameIter = fPropNames;
00221 keyPropCount < kPropCount; ++propNameIter)
00222 {
00223 if (!sGatherMergeConstraints(*propNameIter, ioCriteria,
00224 valueEqual,
00225 bestValueLess, bestValueLessEqual, bestValueGreater, bestValueGreaterEqual))
00226 {
00227
00228 return false;
00229 }
00230
00231 if (!valueEqual)
00232 break;
00233
00234 ZAssertStop(ZCONFIG_TupleIndex_Debug, !bestValueLess && !bestValueLessEqual
00235 && !bestValueGreater && !bestValueGreaterEqual);
00236 theKey.fValues[keyPropCount++] = valueEqual;
00237 }
00238
00239 if (bestValueGreater)
00240 {
00241 ZAssertStop(ZCONFIG_TupleIndex_Debug, !bestValueGreaterEqual);
00242 theKey.fID = kMaxID;
00243 theKey.fValues[keyPropCount] = bestValueGreater;
00244 oLowerBound = fSet.upper_bound(theKey);
00245 theKey.fValues[keyPropCount] = nil;
00246 }
00247 else if (bestValueGreaterEqual)
00248 {
00249 theKey.fID = 0;
00250 theKey.fValues[keyPropCount] = bestValueGreaterEqual;
00251 oLowerBound = fSet.lower_bound(theKey);
00252 theKey.fValues[keyPropCount] = nil;
00253 }
00254 else
00255 {
00256
00257
00258 theKey.fID = 0;
00259 oLowerBound = fSet.lower_bound(theKey);
00260 }
00261
00262 if (bestValueLess)
00263 {
00264 ZAssertStop(ZCONFIG_TupleIndex_Debug, !bestValueLessEqual);
00265 theKey.fID = 0;
00266 theKey.fValues[keyPropCount] = bestValueLess;
00267 oUpperBound = fSet.lower_bound(theKey);
00268 }
00269 else if (bestValueLessEqual)
00270 {
00271 theKey.fID = kMaxID;
00272 theKey.fValues[keyPropCount] = bestValueLessEqual;
00273 oUpperBound = fSet.upper_bound(theKey);
00274 }
00275 else
00276 {
00277
00278
00279 theKey.fID = kMaxID;
00280 oUpperBound = fSet.upper_bound(theKey);
00281 }
00282
00283 return true;
00284 }
00285
00286 bool pKeyFromTuple(uint64 iID, const ZTuple* iTuple, Key& oKey)
00287 {
00288 ZTuple::const_iterator tupleIter = iTuple->IteratorOf(fPropNames[0]);
00289 if (tupleIter == iTuple->end())
00290 {
00291
00292
00293 return false;
00294 }
00295
00296 oKey.fValues[0] = &iTuple->GetValue(tupleIter);
00297
00298 for (size_t x = 1; x < kPropCount; ++x)
00299 oKey.fValues[x] = &iTuple->GetValue(fPropNames[x]);
00300
00301 oKey.fID = iID;
00302 return true;
00303 }
00304
00305 ZTuplePropName fPropNames[kPropCount];
00306 std::set<Key> fSet;
00307 };
00308
00309
00310 #pragma mark -
00311 #pragma mark * ZTupleIndexFactory_T
00312
00313 template <int kPropCount>
00314 class ZTupleIndexFactory_T : public ZTupleIndexFactory
00315 {
00316 public:
00317 ZTupleIndexFactory_T(const std::string* iPropNames)
00318 {
00319 std::copy(iPropNames, iPropNames + kPropCount, fPropNames);
00320 }
00321
00322
00323 virtual ZTupleIndex* Make()
00324 { return new ZTupleIndex_T<kPropCount>(fPropNames); }
00325
00326 private:
00327 ZTuplePropName fPropNames[kPropCount];
00328 };
00329
00330 #endif // __ZTupleIndex_T__