/* * Class: org_zoolib_tuplebase_ZTBSpec * Method: sImp_AsString * Signature: (I)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_org_zoolib_tuplebase_ZTBSpec_sAsString (JNIEnv* iEnv, jclass, jint iNativeSpec) { ZTBSpec* theSpec = reinterpret_cast<ZTBSpec*>(iNativeSpec); string theString = ZUtil_Tuple::sAsString(theSpec->AsTuple(), true); return iEnv->NewStringUTF(theString.c_str()); }
ZTBSpec ZTBSpec::operator|(const ZTBSpec& iOther) const { if (this->IsAny() || iOther.IsNone()) return *this; if (this->IsNone() || iOther.IsAny()) return iOther; CriterionUnion theCriterionUnion = fRep->fCriterionUnion; theCriterionUnion.insert(theCriterionUnion.end(), iOther.fRep->fCriterionUnion.begin(), iOther.fRep->fCriterionUnion.end()); sSimplify(theCriterionUnion); return ZTBSpec(theCriterionUnion, true); }
ZTBSpec ZTBSpec::operator&(const ZTBSpec& iOther) const { if (this->IsNone() || iOther.IsAny()) return *this; if (this->IsAny() || iOther.IsNone()) return iOther; CriterionUnion crossProduct; sCrossProduct(fRep->fCriterionUnion, iOther.fRep->fCriterionUnion, crossProduct); sSimplify(crossProduct); // Here we use our special constructor that swaps its empty list // with the passed in list. return ZTBSpec(crossProduct, true); }
/** Returns a new ZTBQuery whose extension is the current query's extension additionally filtered by \a iSpec. Any sort or first applied to the current query will be preserved in the new query. */ ZTBQuery ZTBQuery::operator&(const ZTBSpec& iSpec) const { if (!fNode || !iSpec) return ZTBQuery(); if (iSpec.IsAny()) return *this; if (ZRef<ZTBQueryNode_Combo> qnc = ZRefDynamicCast<ZTBQueryNode_Combo>(fNode)) { vector<ZTBQueryNode_Combo::Intersection> newVectorSect; const vector<ZTBQueryNode_Combo::Intersection>& src = qnc->GetIntersections(); for (vector<ZTBQueryNode_Combo::Intersection>::const_iterator i = src.begin(); i != src.end(); ++i) { if (ZTBSpec newSpec = (*i).fFilter & iSpec) newVectorSect.push_back(ZTBQueryNode_Combo::Intersection(newSpec, (*i).fNodes)); } vector<SortSpec> theSort = qnc->GetSort(); return new ZTBQueryNode_Combo(theSort, newVectorSect); } else { vector<SortSpec> theSort; vector<ZTBQueryNode_Combo::Intersection> theIntersections(1, ZTBQueryNode_Combo::Intersection(iSpec, fNode)); return new ZTBQueryNode_Combo(theSort, theIntersections); } }
/* * Class: org_zoolib_tuplebase_ZTBSpec * Method: sImp_Matches * Signature: (ILjava/util/Map;)Z */ JNIEXPORT jboolean JNICALL Java_org_zoolib_tuplebase_ZTBSpec_sMatches (JNIEnv* iEnv, jclass, jint iNativeSpec, jobject iMap) { ZTBSpec* theSpec = reinterpret_cast<ZTBSpec*>(iNativeSpec); return theSpec->Matches(ZTuple_Java::sMapToTuple(iEnv, iMap)); }
void ZTS_RAM::Search(const ZTBSpec& iSpec, const set<uint64>& iSkipIDs, set<uint64>& oIDs) { ZAssertStop(kDebug_TS_RAM, fRWLock.CanRead()); ZAssertStop(kDebug_TS_RAM, oIDs.empty()); #if ZCONFIG_TS_RAM_Logging ZTime startTime = ZTime::sSystem(); const ZLog::S& s = ZLog::S(ZLog::eInfo, "ZTS_RAM::Search"); s << iSpec.AsTuple(); #endif // Find the best index to satisfy iSpec. const ZTBSpec::CriterionUnion& theCriterionUnion = iSpec.GetCriterionUnion(); vector<ZTupleIndex*> indicesToUse; if (!ZTupleIndex::sMatchIndices(theCriterionUnion, fIndices, indicesToUse)) { #if ZCONFIG_TS_RAM_Logging s << "\nAt least one clause doesn't have a usable index\n"; size_t resultSize = 0; #endif if (iSpec.IsAny()) { ZDebugLogf(0, ("ZTS_RAM::Search was passed an 'any' ZTBSpec, which would produce 2^64 IDs. Returning none instead")); return; } // At least one of iSpec's OR clauses could not be accelerated by // an index, so we're going to have to walk every tuple for that // clause, so we might as well do so for all of them. if (iSkipIDs.empty()) { for (map<uint64, ZTuple>::iterator i = fTuples.begin(); i != fTuples.end(); ++i) { if (iSpec.Matches((*i).second)) { #if ZCONFIG_TS_RAM_Logging ++resultSize; #endif oIDs.insert((*i).first); } } } else { for (map<uint64, ZTuple>::iterator i = fTuples.begin(); i != fTuples.end(); ++i) { uint64 theID = (*i).first; if (iSkipIDs.end() == iSkipIDs.find(theID)) { if (iSpec.Matches((*i).second)) { #if ZCONFIG_TS_RAM_Logging ++resultSize; #endif oIDs.insert(theID); } } } } #if ZCONFIG_TS_RAM_Logging s.Writef("\nResult size: %d, of %d, overall elapsed: %gms.", resultSize, fTuples.size(), 1000*(ZTime::sSystem() - startTime)); #endif } else { // We found an index for each clause of iSpec. So now use them. ZTBSpec::CriterionUnion::const_iterator iterCriterionUnion = theCriterionUnion.begin(); vector<ZTupleIndex*>::const_iterator iterIndex = indicesToUse.begin(); #if ZCONFIG_TS_RAM_Logging if (indicesToUse.size() > 1) s << "\nUsing multiple indices"; #endif for (/*no init*/;iterIndex != indicesToUse.end(); ++iterIndex, ++iterCriterionUnion) { #if ZCONFIG_TS_RAM_Logging s << "\nSearching for criteria: "; for (ZTBSpec::CriterionSect::const_iterator i = (*iterCriterionUnion).begin(); i != (*iterCriterionUnion).end(); ++i) { s << (*i).AsTuple() << " "; } s << "\nUsing index:\n"; (*iterIndex)->WriteDescription(s); ZTime startOfThisSearch = ZTime::sSystem(); #endif vector<const ZTBSpec::Criterion*> uncheckedCriteria; vector<uint64> currentResults; currentResults.reserve(100); (*iterIndex)->Find(*iterCriterionUnion, iSkipIDs, uncheckedCriteria, currentResults); if (uncheckedCriteria.empty()) { #if ZCONFIG_TS_RAM_Logging s.Writef("\nResult size: %d, of %d, elapsed: %gms, no unchecked criteria.", currentResults.size(), fTuples.size(), 1000 * (ZTime::sSystem() - startOfThisSearch)); #endif oIDs.insert(currentResults.begin(), currentResults.end()); } else { #if ZCONFIG_TS_RAM_Logging s.Writef("\nInitial result size: %d, Unchecked criteria: ", currentResults.size()); for (vector<const ZTBSpec::Criterion*>::iterator i = uncheckedCriteria.begin(); i != uncheckedCriteria.end(); ++i) s << (*i)->AsTuple() << " "; size_t finalResultSize = 0; #endif vector<const ZTBSpec::Criterion*>::const_iterator critBegin = uncheckedCriteria.begin(); vector<const ZTBSpec::Criterion*>::const_iterator critEnd = uncheckedCriteria.end(); for (vector<uint64>::iterator resultIter = currentResults.begin(); resultIter != currentResults.end(); /*no increment*/) { uint64 currentID = *resultIter++; map<uint64, ZTuple>::iterator mapIter = fTuples.find(currentID); ZAssertStop(kDebug_TS_RAM, mapIter != fTuples.end()); const ZTuple& theTuple = (*mapIter).second; bool allOkay = true; for (vector<const ZTBSpec::Criterion*>::const_iterator critIter = critBegin; allOkay && critIter != critEnd; ++critIter) { allOkay = (*critIter)->Matches(theTuple); } if (allOkay) { oIDs.insert(currentID); #if ZCONFIG_TS_RAM_Logging ++finalResultSize; #endif } } #if ZCONFIG_TS_RAM_Logging s.Writef("\nFinal result size: %d, of %d, elapsed: %gms", finalResultSize, fTuples.size(), 1000*(ZTime::sSystem() - startOfThisSearch)); #endif } } #if ZCONFIG_TS_RAM_Logging s.Writef("\nOverall elapsed: %gms.", 1000*(ZTime::sSystem() - startTime)); #endif } }