示例#1
0
bool View::
InsertSubordinateView( ClassAdCollection *coll, ClassAd *viewInfo )
{
	View					*newView = new View( this );
	ViewMembers::iterator	vmi;
	string					key;
	ClassAd					*ad;
	string					name;;

	if( !newView ) {
		CondorErrno = ERR_MEM_ALLOC_FAILED;
		CondorErrMsg = "";
		return( false );
	}

	if( viewInfo ) {
		viewInfo->EvaluateAttrString( ATTR_VIEW_NAME, name );
		newView->evalEnviron.ReplaceLeftAd( viewInfo );
	} 

	newView->SetViewName( name );
	if( !coll->RegisterView( name, newView ) ) {
		CondorErrMsg += "; failed to insert new view";
		delete newView;
		return( false );
	}
	subordinateViews.push_front( newView );

		// insert current view content into new view
	for( vmi = viewMembers.begin( ); vmi != viewMembers.end( ); vmi++ ) {
		vmi->GetKey( key );
		if( ( ad = coll->GetClassAd( key ) ) == NULL ) {
			CLASSAD_EXCEPT( "internal error:  classad %s in view but not in collection",
				key.c_str( ) );
		}
		if( !newView->ClassAdInserted( coll, key, ad ) ) {
			CondorErrMsg += "; failed to insert content into new view";
			return( false );
		}
	}

	return( true );
}
示例#2
0
bool View::
ClassAdModified( ClassAdCollection *coll, const string &key, 
	ClassAd *mad )
{
	bool	match, wasMember, sameRank, rval = true;
	Value	rankValue, oldAdRank, equal;
	MemberIndex::iterator	itr = memberIndex.find( key );

		// check if classad is currently a member of this view
	if( itr == memberIndex.end( ) ) {
		wasMember = false;
	} else {
		wasMember = true;
		((ViewMember) *(itr->second)).GetRankValue( oldAdRank );
	}

		// evaluate constraint and get new rank value
	evalEnviron.ReplaceRightAd( mad );
	match = evalEnviron.EvaluateAttrBool("RightMatchesLeft",match) && match;
	if( !evalEnviron.EvaluateAttr( "LeftRankValue", rankValue ) ) {
		rankValue.SetUndefinedValue( );
	}
	evalEnviron.RemoveRightAd( );

	if( wasMember && match ) {
		string 	sig;
			// was and still is a member; check if rank has changed
		Operation::Operate( Operation::IS_OP, rankValue, oldAdRank, equal );
		if( !equal.IsBooleanValue( sameRank ) || !sameRank ) {
				// rank changed ... need to re-order
			ViewMember	vm;

				// remove old view member ...
			vm.SetRankValue( oldAdRank );
			vm.SetKey(key);
			viewMembers.erase( vm );
				// re-insert with new rank value and update member index
			vm.SetRankValue( rankValue );
			memberIndex[key] = viewMembers.insert( vm );
		}

			// check if the signature has changed
		sig = makePartitionSignature( mad );
		if( sig != oldAdSignature ) {
			PartitionedViews::iterator	mi;
			View						*newPartition;
				// yes ... remove from old partition and insert into new
			if( !oldAdSignature.empty( ) ) {
				mi = partitionedViews.find( oldAdSignature );
				if( mi == partitionedViews.end( ) ) {
						// partition of ad not found; some internal error
					CLASSAD_EXCEPT( "internal error:  partition of classad with "
						"signature %s not found", oldAdSignature.c_str( ) );
				}
					// delete from old partition
				mi->second->ClassAdDeleted( coll, key, mad );
			}

				// is there a partition with the new signature?
			if( !sig.empty( ) ) {
				mi = partitionedViews.find( sig );
				if( mi != partitionedViews.end( ) ) {
						// yes ... insert into this partition
					if( !mi->second->ClassAdInserted(coll, key, mad) ) {
						CondorErrMsg+="; failed to relocate ad on modification";
						return( false );
					}
				} else {
						// no ... create a new partition
					if( ( newPartition = new View( this ) ) == 0 ) {
						oldAdSignature.erase( oldAdSignature.begin( ), 
							oldAdSignature.end( ) );
						CondorErrno = ERR_MEM_ALLOC_FAILED;
						CondorErrMsg = "";
						return( false );
					} 
					if( !coll->RegisterView( viewName+":"+sig, newPartition ) ){
						delete newPartition;
						CondorErrMsg += "; failed to create new partition for "
							" modified ad";
						return( false );
					}
					newPartition->SetViewName( viewName + ":" + sig );
					if( !newPartition->ClassAdInserted(coll, key, mad) ) {
						CondorErrMsg+="; failed to relocate ad on modification";
						return( false );
					}
					partitionedViews[sig] = newPartition;
				}
			}
		}

			// send modification notification to all subordinate children
		SubordinateViews::iterator xi;
		for( xi=subordinateViews.begin( ); xi!=subordinateViews.end( ); xi++ ){
			if( !(*xi)->ClassAdModified( coll, key, mad ) ) {
				return( false );
			}
		}
	} else if( !wasMember && match ) {
			// wasn't a member, but now is --- insert the ad
		rval = ClassAdInserted( coll, key, mad );
	} else if( wasMember && !match ) {
			// was a member, but now isnt --- delete the ad
		ClassAdDeleted( coll, key, mad );
		rval = true;
	} else {
		// wasn't a member and still isn't --- nothing to do
	}

	oldAdSignature.erase( oldAdSignature.begin( ), oldAdSignature.end( ) );
	if( !rval ) {
		CondorErrMsg += "; failed to modify ad";
	}
	return( rval );
}
示例#3
0
// The convention is that each view verifies its constraint before accepting
// an ad.  However, the view assumes that in the case of view partitions, the
// parent view will have identified the correct child partition to use.
bool View::
ClassAdInserted( ClassAdCollection *coll, const string &key, 
	ClassAd *ad )
{
	PartitionedViews::iterator	partition;
	string						signature;
	ViewMember					vm;
	bool 						match;
	Value						rankValue;
	View						*childView;

		// check if the ad satisfies the view's constraint; if the constraint 
		// was not satisfied, the ad can be ignored
	evalEnviron.ReplaceRightAd( ad );
	match = evalEnviron.EvaluateAttrBool("RightMatchesLeft",match) && match;
	if( !match ) {
		evalEnviron.RemoveRightAd( );
		return( true );
	}

		// obtain the rank value of the ad
	if( !evalEnviron.EvaluateAttr( "LeftRankValue", rankValue ) ) {
		CondorErrMsg += "; could not get 'Rank' value; failed to insert "
			"classad " + key + "in view " + viewName;
		return( false );
	}
	evalEnviron.RemoveRightAd( );

		// insert into every subordinate child view
	SubordinateViews::iterator	xi;
	for( xi = subordinateViews.begin( ); xi != subordinateViews.end( ); xi++ ) {
		if( !(*xi)->ClassAdInserted( coll, key, ad ) ) {
			return( false );
		}
	}

		// find partition to insert into
	signature = makePartitionSignature( ad );
	if( !signature.empty( ) ) {
		partition = partitionedViews.find( signature );
		if( partition == partitionedViews.end( ) ) {
				// no appropriate partition --- create one and insert
			if( ( childView = new View( this ) ) == 0 ) {
				CondorErrno = ERR_MEM_ALLOC_FAILED;
				CondorErrMsg = "";
				return( false );
			}

			if( !coll->RegisterView( viewName + ":" + signature, childView ) ) {
				if( childView ) delete childView;
				CondorErrMsg += "; failed to create view; failed to insert "
					"classad " + key + "in view";
				return( false );
			}
			childView->SetViewName( viewName + ":" + signature );
			partitionedViews[signature] = childView;
		} else {
			childView = partitionedViews[signature];
		}

			// update the partition
		if( !childView->ClassAdInserted( coll, key, ad ) ) {
			return( false );
		}
	}

		// insert ad into list of view members and update index
	vm.SetKey( key );
	vm.SetRankValue( rankValue );
	memberIndex[key] = viewMembers.insert(vm);

	return( true );
}
示例#4
0
bool View::
SetPartitionExprs( ClassAdCollection *coll, ExprList *el )
{
		// insert expression list into view info
	ClassAd *ad = evalEnviron.GetLeftAd( );
	if( !el ) {
		CondorErrno = ERR_BAD_PARTITION_EXPRS;
		CondorErrMsg = "invalid 'PartitionExprs'; failed to partition";
		return( false );
	}
	if( !( ad->Insert( ATTR_PARTITION_EXPRS, (ExprTree* &)el ) ) ) {
		CondorErrMsg += "failed to set partition expressions on view";
		return( false );
	}

		// re-establish partition views; first delete all partition views
	PartitionedViews::iterator  mi;
	for( mi = partitionedViews.begin( ); mi != partitionedViews.end( ); mi++ ) {
		mi->second->DeleteView( coll );
		delete mi->second;
	}
	partitionedViews.clear( );

		// if the partition expressions list is empty, we're done
	vector<ExprTree*> components;
	el->GetComponents( components );
	if( components.size( ) == 0 ) return( true );
	
		// re-partition content
	ViewMembers::iterator	vmi;
	string					key, signature;
	View					*partition;

	for( vmi = viewMembers.begin( ); vmi != viewMembers.end( ); vmi++ ) {
			// get signature of this ad
		vmi->GetKey( key );
		if( ( ad = coll->GetClassAd( key ) ) == NULL ) {
			CLASSAD_EXCEPT( "internal error:  classad %s in view but not in collection",
				key.c_str( ) );
		}
		signature = makePartitionSignature( ad );

			// check if we have a partition with this signature
		if( partitionedViews.find( signature ) == partitionedViews.end( ) ) {
				// no partition ... make a new one
			if( ( partition = new View( this ) ) == NULL ) {
				CondorErrno = ERR_MEM_ALLOC_FAILED;
				CondorErrMsg = "";
				return( false );
			}
			if( !coll->RegisterView( viewName + ":" + signature, partition ) ) {
				CondorErrMsg += "; could not complete partitioning";
				return( false );
			}
			partition->SetViewName( viewName + ":" + signature );
			partitionedViews[signature] = partition;
		} else {
				// use the partition that's already there
			partition = partitionedViews[signature];
		}

			// add classad to the partition
		if( !partition->ClassAdInserted( coll, key, ad ) ) {
			CondorErrMsg += "; failed to set partition expressions";
			return( false );
		}
	}

	return( true );
}