diff --git a/Plugins/org.mitk.core.jobs/src/internal/mitkDataStorageAccessRule.cpp b/Plugins/org.mitk.core.jobs/src/internal/mitkDataStorageAccessRule.cpp
index 15cc85a95c..d7160aa205 100644
--- a/Plugins/org.mitk.core.jobs/src/internal/mitkDataStorageAccessRule.cpp
+++ b/Plugins/org.mitk.core.jobs/src/internal/mitkDataStorageAccessRule.cpp
@@ -1,197 +1,197 @@
/*=========================================================================
Program: Medical Imaging & Interaction Toolkit
Language: C++
Date: $Date$
Version: $Revision: 18503 $
Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "mitkDataStorageAccessRule.h"
#include
mitk::DataStorageAccessRule
::DataStorageAccessRule (mitk::DataStorage::Pointer myDataStorage, mitk::DataNode::Pointer myDataNode,
mitk::DataStorageAccessRule::RuleType myRule)
:m_Rule(myRule),
m_sptrMyDataStorage(myDataStorage),
m_sptrMyDataNode(myDataNode)
{
mitk::DataStorage::SetOfObjects::ConstPointer
sptr_parentsNodesFirstRule = m_sptrMyDataStorage->GetSources(m_sptrMyDataNode);
// checks if the DataNode does exists within the specified DataTree, if not an
// Poco NotFoundException is thrown since the rule is useless
bool exsists = false ;
for(mitk::DataStorage::SetOfObjects::const_iterator it =
sptr_parentsNodesFirstRule->begin(); it != sptr_parentsNodesFirstRule->end(); ++ it)
{
if (*it == m_sptrMyDataNode ) exsists = true ;
}
if (exsists == false) throw Poco::NotFoundException() ;
}
bool
mitk::DataStorageAccessRule
- ::Contains(berry::ISchedulingRule::Pointer rule)
+ ::Contains(berry::ISchedulingRule::Pointer rule) const
{
DataStorageAccessRule::Pointer sptr_temp = rule.Cast();
// test if the ISchedulingRule is a DataStorageAccessRule
if( sptr_temp == 0 ) return false ;
// test if the DataStorageAccessRule object is exactly the instance
else {
if ( this == sptr_temp.GetPointer() ) return true ;
return false ;
}
}
bool
mitk::DataStorageAccessRule
- ::IsConflicting(berry::ISchedulingRule::Pointer sptr_otherISchedulingRule)
+ ::IsConflicting(berry::ISchedulingRule::Pointer sptr_otherISchedulingRule) const
{
// test if the stored dataNode
// cast to check if the ISchedulingRule is a DataStorageAccessRule
DataStorageAccessRule::Pointer sptr_DataStorageAccessRule = sptr_otherISchedulingRule.Cast();
// checks if the Rule of the type ISchedulingRule is a DataStorageAccessRule
if(sptr_DataStorageAccessRule == 0) return false ;
// the rule to be compared with is a DataStorageAccessRule
else
{
// testing if both jobs holding each rule do operate on the same DataStorage if not false is returned
if( !CompareDataStorages(sptr_DataStorageAccessRule->GetDataStorage()) ) return false ;
// checks if to rules to be compared are two add rules
if (m_Rule == ADD_RULE && m_Rule == sptr_DataStorageAccessRule->GetRuleType())
return CompareTwoAddorRemoveRules() ;
// checks if to the two rules to be compared are two remove rules
if(m_Rule == REMOVE_RULE && m_Rule == sptr_DataStorageAccessRule->GetRuleType())
return CompareTwoAddorRemoveRules() ;
// an add and remove rule needs to be compared
else
{
return CompareAddandRemoveRules(sptr_DataStorageAccessRule) ;
}
}
}
bool
mitk::DataStorageAccessRule
::CompareAddandRemoveRules(mitk::DataStorageAccessRule::Pointer sptr_otherDataStorageAccessRule) const
{
mitk::DataStorage::SetOfObjects::ConstPointer
sptr_parentsNodesFirstRule = m_sptrMyDataStorage->GetSources(m_sptrMyDataNode);
// checks if the DataStorageNode of to be compared DataStorageAccessRule is a parent node
// if so the job holding this DataStorageAccessRule need to wait until the operation on the parent node is performed
for(mitk::DataStorage::SetOfObjects::const_iterator it =
sptr_parentsNodesFirstRule->begin(); it != sptr_parentsNodesFirstRule->end(); ++ it)
{
if (*it == sptr_otherDataStorageAccessRule->GetDataNode()) return true ;
}
mitk::DataStorage::SetOfObjects::ConstPointer
sptr_derivedNodesRule = m_sptrMyDataStorage->GetDerivations(m_sptrMyDataNode);
// checks if the DataStorage node of to be compared DataStorageAccessRule is a child node
// if so the job holding this DataStorageAccessRule needs to wait until the operation on the parent node is performed
for(mitk::DataStorage::SetOfObjects::const_iterator it =
sptr_derivedNodesRule->begin(); it != sptr_derivedNodesRule->end(); ++it)
{
if(*it == sptr_otherDataStorageAccessRule->GetDataNode()) return true ;
}
// jobs operating on nodes on different branches do not cause conflicts thus they can be performed in different
// threads concurrently
return false ;
}
bool
mitk::DataStorageAccessRule
::CompareDataStorages(mitk::DataStorage::Pointer otherDataStorage) const
{
if(m_sptrMyDataStorage == otherDataStorage) return true ;
else return false;
}
bool
mitk::DataStorageAccessRule
::CompareTwoAddorRemoveRules() const
{
return false ;
}
bool
mitk::DataStorageAccessRule
::TestDataNode(mitk::DataNode::Pointer /*dataTreeToBeStored*/) const
{
mitk::DataStorage::SetOfObjects::ConstPointer tempAllNodes = m_sptrMyDataStorage->GetAll();
for(mitk::DataStorage::SetOfObjects::const_iterator it = tempAllNodes->begin(); it !=tempAllNodes->end(); ++ it){
if (m_sptrMyDataNode == *it ) return true ;
}
return false ;
}
mitk::DataNode::Pointer
mitk::DataStorageAccessRule
::GetDataNode() const
{
return mitk::DataStorageAccessRule::m_sptrMyDataNode ;
}
mitk::DataStorage::Pointer
mitk::DataStorageAccessRule
::GetDataStorage() const
{
return mitk::DataStorageAccessRule::m_sptrMyDataStorage ;
}
mitk::DataStorageAccessRule::RuleType
mitk::DataStorageAccessRule
::GetRuleType() const
{
if (m_Rule == ADD_RULE)
return ( mitk::DataStorageAccessRule::ADD_RULE ) ;
else {
return ( mitk::DataStorageAccessRule::REMOVE_RULE ) ;
}
}
diff --git a/Plugins/org.mitk.core.jobs/src/mitkDataStorageAccessRule.h b/Plugins/org.mitk.core.jobs/src/mitkDataStorageAccessRule.h
index 124bf2ee61..a77a81d62f 100644
--- a/Plugins/org.mitk.core.jobs/src/mitkDataStorageAccessRule.h
+++ b/Plugins/org.mitk.core.jobs/src/mitkDataStorageAccessRule.h
@@ -1,159 +1,159 @@
/*=========================================================================
Program: Medical Imaging & Interaction Toolkit
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef MITKDATASTORAGEACCESSRULE_H_HEADER_INCLUDED_
#define MITKDATASTORAGEACCESSRULE_H_HEADER_INCLUDED_
#include
#include "berryISchedulingRule.h"
#include "berryObject.h"
#include "mitkDataNode.h"
#include "mitkDataStorage.h"
#include "mitkStandaloneDataStorage.h"
namespace mitk {
/**
*@class DataStorageAccessRule
*
*@brief The DataStorageAccessRule inherits from the ISchedulingRule class. DataStorageAccessRule are used to restrict the adding and
* removing of DataStorage nodes in multi-threaded scenarios. Only DataStorageNodes within different branches can be modified
* concurrently. The idea and its restrictions is explained in the sections and diagrams below.
*
*
the IsScheduling(...) method :
* returns true or false depending if conflictions with another rule are found
*
*
*
*
* the rule behavior if jobs holing add rules of an DataTree node
*
* two add rules are always allowed since there are no conflictions when adding nodes concurrently. The final order the nodes are finally added has
* to be checked by the programmer of the particular job
*
*
* the rule behavior when two jobs holding remove rules of a DataNode
*
* two jobs holding remove rules can be executed concurrently since all removing scenarios do not cause conflictions. If two jobs are
* trying to remove the same DataTree node the job by itself needs to check if the node is still available before executing the removing
* command
*
*
* the rule behavior of a jobs that is holding an add rule compared with a job that is holding a remove rule on a
* DataNode
*
* adding and removing of DataTree nodes concurrently can cause serious errors and needs to be restricted. Performing add and remove
* operations on different DataStorage branches can be done concurrently since no conflictions are expected.
* the performing of add and remove operation on the same DataNode, its parent nodes or child nodes of the same branch
* by different jobs is not allowed. Jobs holding rules that are trying to perform such operations are blocked until the running job is done.
*
*
*
*
*
the Contains method (...) method :
* only necessary for a specific type of scheduling rules. Has to be used if IScheduling rules are composed into hierarchies.
* In such scenarios the contains(...) method specifies the hierarchical relationships among the locks. For example if a method tries to acquire a specific * rule to lock a specific directory it needs to check if no job is holding a rule for one or more subdirectories. For all cases in which no composing of
* IScheduling rules is needed the Contains(...) method only needs to check if two jobs are holding exactly the same IScheduling rule on the same object.
* Normally this can be achieved by just calling the IsConflicting(...) method.
*
*
*@author Jan Woerner
*/
class MITK_JOBS_EXPORT DataStorageAccessRule : public berry::ISchedulingRule {
public:
enum RuleType {ADD_RULE = 0, REMOVE_RULE} ;
RuleType m_Rule;
berryObjectMacro(DataStorageAccessRule)
DataStorageAccessRule (mitk::DataStorage::Pointer myDataStorage, mitk::DataNode::Pointer myDataNode,
DataStorageAccessRule::RuleType myRule) ;
- bool Contains (berry::ISchedulingRule::Pointer otherISchedulingRule) ;
- bool IsConflicting (berry::ISchedulingRule::Pointer otherISchedulingRule) ;
+ bool Contains (berry::ISchedulingRule::Pointer otherISchedulingRule) const;
+ bool IsConflicting (berry::ISchedulingRule::Pointer otherISchedulingRule) const;
private:
/**
* Returns false, identifying no conflictions between two DataStorageAccessRules.
* Two add and remove rules do work together. From importance is that jobs using this rule need to check if the
* node operating on is still available or already deleted by another job. The DataStorageAccessRule only checks if conflictions could
* occur if the removing or adding of nodes is performed currently.
*/
bool CompareTwoAddorRemoveRules() const ;
/**
* searches for conflictions of an add DataStorageAccessRule with a remove DataStorageAccess rule
* if the add and remove rule do operate in different branches, no conflictions are expected and false is returned
*/
bool CompareAddandRemoveRules(mitk::DataStorageAccessRule::Pointer sptr_otherDataStorageAccessRule) const;
/**
* for internal use only,
* checks if the jobs that are to be compared do hold DataStorageAccessRule on the same
* DataStorage. Jobs that do operate on different DataStorage do not conflict and false is returned
*/
bool CompareDataStorages(mitk::DataStorage::Pointer otherDataStorage) const;
/**
* for internal use only
* validates if the DataTree node of a particular DataStorageAccess rule belongs to the DataStorage specified within the particular rule.
* if not the rule is invalid and false is returned. No conflictions can be expected
*/
bool TestDataNode(mitk::DataNode::Pointer dataTreeToBeStored) const;
/**
* returns a pointer to the specified DataStorage node
*/
mitk::DataNode::Pointer GetDataNode() const;
/**
* returns a pointer to the specified DataStorage
*/
mitk::DataStorage::Pointer GetDataStorage() const;
mitk::DataStorageAccessRule::RuleType GetRuleType() const;
DataStorage::Pointer m_sptrMyDataStorage ;
DataNode::Pointer m_sptrMyDataNode ;
};
}
#endif /*MITKDATASTORAGEACCESSRULE_H_HEADER_INCLUDED_ */