bool LocalCollectionQuery:: Query( const string &viewName, ExprTree *expr, bool two_way_matching ) { ViewRegistry::iterator vri; ViewMembers::iterator vmi; MatchClassAd mad; View *view; ClassAd *ad=0; const ClassAd *parent; string key; bool match; bool given_classad=false; if (expr && expr->isClassad(&ad)) { given_classad = true; } parent = NULL; // get the view to query if( !collection || ( vri = collection->viewRegistry.find( viewName ) ) == collection->viewRegistry.end( ) ) { return( false ); } view = vri->second; if( expr ) { if (given_classad) { mad.ReplaceLeftAd(ad); } else { // setup evluation environment if a constraint was supplied parent = expr->GetParentScope( ); if( !( ad=mad.GetLeftAd() ) || !ad->Insert(ATTR_REQUIREMENTS,expr,false ) ) { expr->SetParentScope( parent ); return( false ); } } } keys.clear( ); // iterate over the view members for( vmi=view->viewMembers.begin(); vmi!=view->viewMembers.end(); vmi++ ) { // ... and insert keys into local list in same order vmi->GetKey( key ); if( expr ) { // if a constraint was supplied, make sure its satisfied ad = collection->GetClassAd( key ); mad.ReplaceRightAd( ad ); if( mad.EvaluateAttrBool( "RightMatchesLeft", match ) && match ) { bool add_key; if (!given_classad || !two_way_matching) { add_key = true; } else if (mad.EvaluateAttrBool( "LeftMatchesRight", match ) && match) { add_key = true; } else { add_key = false; } if (add_key) { keys.push_back( key ); } } mad.RemoveRightAd( ); } else { keys.push_back( key ); } } // initialize local iterator itr = keys.begin( ); // clean up and return if( expr ) { if (given_classad) { mad.RemoveLeftAd(); } expr->SetParentScope( parent ); ad = mad.GetLeftAd(); if (ad != NULL) { ad->Remove(ATTR_REQUIREMENTS); } } return( true ); }