// Disconnects steps connected with specified connection object and removes it from the workflow void GaWorkflow::RemoveConnection(GaFlowConnection* connection, bool destory) { GA_ARG_ASSERT( Exceptions::GaNullArgumentException, connection != NULL, "connection", "Connection object must be specified.", "Workflows" ); // is this connection branch group? if( _branchGroups.find( connection ) != _branchGroups.end() ) { // check whether the removing of the branch group has breaken validity of branch group transitions GA_ASSERT( Exceptions::GaInvalidOperationException, CheckBranchGroupTransitionConnections( (GaBranchGroup*)connection ), "Disconnecting specified steps can make some of the branch group transition connections invalid.", "Workflows" ); // disconnect attached steps and removes branch group from the workflow connection->DisconnectSteps(); _branchGroups.erase( connection ); if( destory ) delete connection; } // is this connection branch group transition? else if( _branchGroupTransitions.find( connection ) != _branchGroupTransitions.end() ) { // disconnect attached steps and removes branch group transition connection from the workflow connection->DisconnectSteps(); _branchGroupTransitions.erase( connection ); if( destory ) delete connection; } else GA_ARG_THROW( Exceptions::GaArgumentException, "connection", "Specified connection does not belong to this flow.", "Workflows" ); }
// Removes data from the storage object void GaDataStorage::RemoveData(int dataID, GaDataStorageLevel level) { GA_ARG_ASSERT( Exceptions::GaArgumentException, level <= _level, "storageLevel", "Trying to remove data from level below this storage object.", "Workflows" ); GA_LOCK_THIS_OBJECT( lock ); // trying to remove data from level which is equal to level of this object if( level == _level ) { STLEXT::hash_map<int, GaDataEntryBase*>::iterator it = _data.find( dataID ); if( it != _data.end() ) { GaDataEntryBase* data = it->second; GA_ASSERT( Exceptions::GaInvalidOperationException, data->GetReferenceCount() == 0, "Entry with valid references to it cannot be removed from the storage.", "Workflows" ); _data.erase( it ); GA_UNLOCK( lock ); delete data; } } else { // forward deletion to higher level object if( _levelTable[ level ] ) _levelTable[ level ]->RemoveData( dataID, level ); } }
// Sets combiner object void GaValueHistoryBase::SetCombiner(GaValueCombiner* combiner) { GA_ASSERT( Common::Exceptions::GaInvalidOperationException, _evaluator == NULL, "Cannot set combiner for value which is evaluated automatically.", "Statistics" ); GA_ARG_ASSERT( Common::Exceptions::GaNullArgumentException, combiner != NULL, "combiner", "Combiner must be specifed.", "Statistics" ); _combiner = combiner; }
// Inserts new chromosome after the last chromosome currently in the group int GaChromosomeGroup::Add(GaChromosomeStorage* chromosome) { // is chromosome already a member of this group if( _membershipFlag && chromosome->GetFlags().IsFlagSetAll( _membershipFlag ) ) // if membership flag is used, single chromosome cannot inserted in the same group multiple times return -1; _hasShuffleBackup = false; // group is full? if( _count == _array.GetSize() ) { GA_ASSERT( Common::Exceptions::GaInvalidOperationException, _sizable, "This chromosome group is full.", "Population" ); // increase size of the group so it can accommodate new chromosome IncreaseSize(); } // insert chromosome and mark it as a member int pos = _count++; _chromosomes[ pos ] = chromosome; chromosome->GetFlags().SetFlags( _membershipFlag ); return pos; }
// Attaches outgoing branch group void GaBranchGroupTransition::AttachNextStep(GaFlowConnection* nextStep) { GA_ARG_ASSERT( Exceptions::GaNullArgumentException, nextStep != NULL, "nextStep", "Connection object must be specified.", "Workflows" ); GA_ARG_ASSERT( Exceptions::GaArgumentException, nextStep->GetOutboundStep() == this, "nextStep", "Wrong connection object.", "Workflows" ); GA_ASSERT( Exceptions::GaInvalidOperationException, !HasOutboundConnections(), "Outbound point of the step is already connected.", "Workflows" ); // attach outgoing branch group AddOutboundConnection( nextStep ); }
// Attaches next step void GaSimpleWorkStep::AttachNextStep(GaFlowConnection* nextStep) { GA_ARG_ASSERT( Exceptions::GaNullArgumentException, nextStep != NULL, "nextStep", "Connection object must be specified.", "Workflows" ); GA_ARG_ASSERT( Exceptions::GaArgumentException, nextStep->GetOutboundStep() == this, "nextStep", "Wrong connection object.", "Workflows" ); GA_ASSERT( Exceptions::GaInvalidOperationException, !HasOutboundConnections(), "Outbound point of the step is already connected.", "Workflows" ); // attach and add to list of outbound connections AddOutboundConnection( nextStep ); }
// Removes node's child void GaTreeNodeBase::DetachChild(GaTreeNodeBase* node) { GaListNode<GaTreeNodeBase*>* position = _children.Find( node ); GA_ASSERT( Exceptions::GaInvalidOperationException, position != NULL, "Specified node is not child of this node.", "Data" ); // detach child from this node _children.Remove( position ); node->_parent = NULL; }
// Removes step from the workflow void GaWorkflow::RemoveStep(GaFlowStep* step, bool disconnect, bool destroy) { GA_ARG_ASSERT( Exceptions::GaNullArgumentException, step != NULL, "step", "Step must be specified.", "Workflows" ); GA_ARG_ASSERT( Exceptions::GaArgumentException, step->GetFlow() == this, "step", "Step does not belong to this flow.", "Workflows" ); GA_ASSERT( Exceptions::GaInvalidOperationException, step != _firstStep && step != _lastStep, "Cannot remove start and finish steps of the workflow.", "Workflows" ); GA_ASSERT( Exceptions::GaInvalidOperationException, disconnect || !step->HasConnections(), "Trying to remove step which is connected to the other steps of this flow without disconnecting it.", "Workflows" ); // disconnect step from all other steps if( disconnect ) step->DisconnectAllConnections(); // disconnect step from all other steps step->UnbindFromFlow(); _steps.erase( (GaAbstractBarrier*)step ); if( destroy ) delete step; }
// Restores chromosomes in oreder prior they were shuffled void GaChromosomeGroup::RestoreShuffle() { GA_ASSERT( Common::Exceptions::GaInvalidOperationException, _hasShuffleBackup, "Group does not contains backup of shuffle operation.", "Population" ); // restore from backup GaChromosomeStorage** helper = _array.GetArray() == _chromosomes ? _helper.GetArray() : _array.GetArray(); for( int i = _count - 1; i >= 0; i-- ) _chromosomes[ i ] = _helper[ i ]; _hasShuffleBackup = false; }
// Attaches next step void GaDecision::AttachNextStep(GaFlowConnection* nextStep) { GA_ARG_ASSERT( Exceptions::GaNullArgumentException, nextStep != NULL, "nextStep", "Connection object must be specified.", "Workflows" ); GA_ARG_ASSERT( Exceptions::GaArgumentException, nextStep->GetOutboundStep() == this, "nextStep", "Wrong connection object.", "Workflows" ); int branch = nextStep->GetConnectionID(); GA_ASSERT( Exceptions::GaInvalidOperationException, _branches.find( branch ) == _branches.end(), "Outbound point of the step is already connected.", "Workflows" ); // add connection to decision table _branches[ branch ] = nextStep; AddOutboundConnection( nextStep ); }
// Sets evaluator object void GaValueHistoryBase::SetEvaluator(GaValueEvaluator* evaluator) { GA_ASSERT( Common::Exceptions::GaInvalidOperationException, _combiner == NULL, "Cannot set evaluator for value which is created as independent value.", "Statistics" ); GA_ARG_ASSERT( Common::Exceptions::GaNullArgumentException, evaluator != NULL, "evaluator", "Evaluator must be specifed.", "Statistics" ); // removes dependencies established by the previous evaluator RemoveAllDependencies(); // establishe new dependencies and reevaluate value useing new evaluator _evaluator = evaluator; _evaluator->Bind( this ); Evaluate(); }
// Removes step from the flow void GaBranchGroupFlow::RemoveStep(GaFlowStep* step, bool disconnect, bool destroy) { GA_ARG_ASSERT( Exceptions::GaNullArgumentException, step != NULL, "step", "Step must be specified.", "Workflows" ); GA_ARG_ASSERT( Exceptions::GaArgumentException, step->GetFlow() == this, "step", "Step does not belong to this flow.", "Workflows" ); GA_ASSERT( Exceptions::GaInvalidOperationException, disconnect || !step->HasConnections(), "Trying to remove step which is connected to the other steps of this flow without disconnecting it.", "Workflows" ); // disconnect step from all other steps if( disconnect ) step->DisconnectAllConnections(); // clear mark that the step is a memeber of this flow and removes it step->UnbindFromFlow(); _steps.erase( step ); if( destroy ) delete step; }
// Attaches connection to inbound step void GaFlowConnection::ConnectInboundStep(GaFlowStep* inboundStep) { GA_ARG_ASSERT( Exceptions::GaNullArgumentException, inboundStep != NULL, "inboundStep", "Outbound step must be specified.", "Workflows" ); GA_ASSERT( Exceptions::GaInvalidOperationException, _inboundStep == NULL, "Connection is already inbound to outbound step.", "Workflows" ); GA_ARG_ASSERT( Exceptions::GaArgumentException, !_outboundStep || CheckConnectionValidity( inboundStep, _outboundStep ), "inboundStep", "The connection is not valid.", "Workflows" ); try { // store inbound step and attach connection to outbound and inboud steps if both are available _inboundStep = inboundStep; _inboundStep->AttachPreviousStep( this ); } catch( ... ) { _inboundStep = NULL; throw; } }
// Updates decision table when ID of connection object is changed void GaDecision::ConnectionIDChanged(GaFlowConnection* connection, int oldConnectionID) { GA_ARG_ASSERT( Exceptions::GaNullArgumentException, connection != NULL, "connection", "Connection object must be specified.", "Workflows" ); if( !HasOutboundConnection( connection ) ) { if( HasInboundConnection( connection ) ) return; GA_ARG_THROW( Exceptions::GaArgumentException, "connection", "Wrong connection object.", "Workflows" ); } int newBranch = connection->GetConnectionID(); GA_ARG_ASSERT( Exceptions::GaArgumentException, _branches[ oldConnectionID ] == connection, "connection", "Wrong connection object.", "Workflows" ); GA_ASSERT( Exceptions::GaInvalidOperationException, _branches.find( newBranch ) == _branches.end(), "Outbound point of the step is already connected.", "Workflows" ); // update decision table _branches[ newBranch ] = _branches[ oldConnectionID ]; _branches.erase( oldConnectionID ); }
// Sets new size of array that stores chromosomes void GaChromosomeGroup::SetSize(int size) { if( size != _array.GetSize() ) { GA_ASSERT( Common::Exceptions::GaInvalidOperationException, !_sizable, "This chromosome group manage its size automatically.", "Population" ); GA_ARG_ASSERT( Common::Exceptions::GaArgumentOutOfRangeException, size >= 0, "size", "Group size cannot be negative value.", "Population" ); // with new size of group cannot store chromosmes? if( !size ) // removes all chromosomes from the group Clear(); else { int limit = 0; if( !_array.IsEmpty() ) { limit = _array.GetSize() < _count ? _array.GetSize() : _count; if( _recycleObjects && _population ) { // recycle chromosome objects using provided pool for( int i = limit; i < _count; i++ ) _population->ReleaseStorageObject( _chromosomes[ i ] ); } else if( _membershipFlag ) { // chromosome objects are not recycled - just clear mebership flags for( int i = limit; i < _count; i++ ) _chromosomes[ i ]->GetFlags().SetFlags( _membershipFlag ); } } _count = limit; ResizeArray( size ); } } }