Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Protected Types | Protected Member Functions | Protected Attributes

mitk::StandaloneDataStorage Class Reference

Data management class that handles 'was created by' relations. More...

#include <mitkStandaloneDataStorage.h>

Inheritance diagram for mitk::StandaloneDataStorage:
Inheritance graph
[legend]
Collaboration diagram for mitk::StandaloneDataStorage:
Collaboration graph
[legend]

List of all members.

Public Types

typedef StandaloneDataStorage Self
typedef mitk::DataStorage Superclass
typedef itk::SmartPointer< SelfPointer
typedef itk::SmartPointer
< const Self
ConstPointer

Public Member Functions

virtual const char * GetClassName () const
void Add (mitk::DataNode *node, const mitk::DataStorage::SetOfObjects *parents=NULL)
 Adds a DataNode containing a data object to its internal storage.
void Remove (const mitk::DataNode *node)
 Removes node from the StandaloneDataStorage.
virtual bool Exists (const mitk::DataNode *node) const
 Checks if a node exists in the StandaloneDataStorage.
SetOfObjects::ConstPointer GetSources (const mitk::DataNode *node, const NodePredicateBase *condition=NULL, bool onlyDirectSources=true) const
 returns a set of source objects for a given node that meet the given condition(s).
SetOfObjects::ConstPointer GetDerivations (const mitk::DataNode *node, const NodePredicateBase *condition=NULL, bool onlyDirectDerivations=true) const
 returns a set of derived objects for a given node.
SetOfObjects::ConstPointer GetAll () const
 returns a set of all data objects that are stored in the data storage

Static Public Member Functions

static Pointer New ()

Public Attributes

itk::SimpleFastMutexLock m_Mutex

Protected Types

typedef std::map
< mitk::DataNode::ConstPointer,
SetOfObjects::ConstPointer > 
AdjacencyList
 noncyclical directed graph data structure to store the nodes with their relation

Protected Member Functions

 StandaloneDataStorage ()
 Standard Constructor for New() instantiation.
virtual ~StandaloneDataStorage ()
 Standard Destructor.
bool IsInitialized () const
 convenience method to check if the object has been initialized (i.e. a data tree has been set)
SetOfObjects::ConstPointer GetRelations (const mitk::DataNode *node, const AdjacencyList &relation, const NodePredicateBase *condition=NULL, bool onlyDirectlyRelated=true) const
 Traverses the Relation graph and extracts a list of related elements (e.g. Sources or Derivations)
void RemoveFromRelation (const mitk::DataNode *node, AdjacencyList &relation)
 deletes all references to a node in a given relation (used in Remove() and TreeListener)
virtual void PrintSelf (std::ostream &os, itk::Indent indent) const
 Prints the contents of the StandaloneDataStorage to os. Do not call directly, call ->Print() instead.

Protected Attributes

AdjacencyList m_SourceNodes
 Nodes and their relation are stored in m_SourceNodes.
AdjacencyList m_DerivedNodes
 Nodes are stored in reverse relation for easier traversal in the opposite direction of the relation.

Detailed Description

Data management class that handles 'was created by' relations.

The StandaloneDataStorage provides data storage and management functionality. It handles a 'was created by' relation by associating each data object with a set of source objects that were used to create the new object was created from. Thus, nodes are stored in a noncyclical directed graph data structure. It is derived from mitk::DataStorage and implements its interface, including AddNodeEvent and RemoveNodeEvent.

Definition at line 42 of file mitkStandaloneDataStorage.h.


Member Typedef Documentation

typedef std::map<mitk::DataNode::ConstPointer, SetOfObjects::ConstPointer> mitk::StandaloneDataStorage::AdjacencyList [protected]

noncyclical directed graph data structure to store the nodes with their relation

Definition at line 99 of file mitkStandaloneDataStorage.h.

typedef itk::SmartPointer<const Self> mitk::StandaloneDataStorage::ConstPointer

Reimplemented from mitk::DataStorage.

Reimplemented in mitk::TestStandaloneDataStorage.

Definition at line 45 of file mitkStandaloneDataStorage.h.

typedef itk::SmartPointer<Self> mitk::StandaloneDataStorage::Pointer

Reimplemented from mitk::DataStorage.

Reimplemented in mitk::TestStandaloneDataStorage.

Definition at line 45 of file mitkStandaloneDataStorage.h.

Reimplemented from mitk::DataStorage.

Reimplemented in mitk::TestStandaloneDataStorage.

Definition at line 45 of file mitkStandaloneDataStorage.h.

Reimplemented from mitk::DataStorage.

Reimplemented in mitk::TestStandaloneDataStorage.

Definition at line 45 of file mitkStandaloneDataStorage.h.


Constructor & Destructor Documentation

mitk::StandaloneDataStorage::StandaloneDataStorage (  ) [protected]

Standard Constructor for New() instantiation.

Definition at line 29 of file mitkStandaloneDataStorage.cpp.

mitk::StandaloneDataStorage::~StandaloneDataStorage (  ) [protected, virtual]

Standard Destructor.

Definition at line 35 of file mitkStandaloneDataStorage.cpp.

{
  for(AdjacencyList::iterator it = m_SourceNodes.begin();
    it != m_SourceNodes.end(); it++)
  {
    this->RemoveListeners(it->first);
  }
}

Member Function Documentation

void mitk::StandaloneDataStorage::Add ( mitk::DataNode node,
const mitk::DataStorage::SetOfObjects parents = NULL 
) [virtual]

Adds a DataNode containing a data object to its internal storage.

This Method adds a new data object to the StandaloneDataStorage. The new object is passed in the first parameter. The second parameter is a set of source objects, that were used to create this object. The new object will have a 'was created from' relation to its source objects. the addition of a new object will fire the notification mechanism. If the node parameter is NULL or if the DataNode has already been added, an exception will be thrown.

Implements mitk::DataStorage.

Definition at line 53 of file mitkStandaloneDataStorage.cpp.

{
  {
    itk::MutexLockHolder<itk::SimpleFastMutexLock> locked(m_Mutex);
    if (!IsInitialized())
      throw std::logic_error("DataStorage not initialized");
    /* check if node is in its own list of sources */
    if ((parents != NULL) && (std::find(parents->begin(), parents->end(), node) != parents->end()))
      throw std::invalid_argument("Node is it's own parent");
    /* check if node already exists in StandaloneDataStorage */
    if (m_SourceNodes.find(node) != m_SourceNodes.end())
      throw std::invalid_argument("Node is already in DataStorage");

    /* create parent list if it does not exist */
    mitk::DataStorage::SetOfObjects::ConstPointer sp;
    if (parents != NULL)
      sp = parents;
    else
      sp = mitk::DataStorage::SetOfObjects::New();
    /* Store node and parent list in sources adjacency list */
    m_SourceNodes.insert(std::make_pair(node, sp));

    /* Store node and an empty children list in derivations adjacency list */
    mitk::DataStorage::SetOfObjects::Pointer children = mitk::DataStorage::SetOfObjects::New();
    m_DerivedNodes.insert(std::make_pair(node, children));

    /* create entry in derivations adjacency list for each parent of the new node */
    for (SetOfObjects::ConstIterator it = sp->Begin(); it != sp->End(); it++)
    {
      mitk::DataNode::ConstPointer parent = it.Value().GetPointer();
      mitk::DataStorage::SetOfObjects::ConstPointer derivedObjects = m_DerivedNodes[parent]; // get or create pointer to list of derived objects for that parent node
      if (derivedObjects.IsNull())
        m_DerivedNodes[parent] = mitk::DataStorage::SetOfObjects::New();  // Create a set of Objects, if it does not already exist
      mitk::DataStorage::SetOfObjects* deob = const_cast<mitk::DataStorage::SetOfObjects*>(m_DerivedNodes[parent].GetPointer());  // temporarily get rid of const pointer to insert new element
      deob->InsertElement(deob->Size(), node); // node is derived from parent. Insert it into the parents list of derived objects
    }

    // register for ITK changed events
    this->AddListeners(node);
  }

  /* Notify observers */
  EmitAddNodeEvent(node);

}
bool mitk::StandaloneDataStorage::Exists ( const mitk::DataNode node ) const [virtual]

Checks if a node exists in the StandaloneDataStorage.

Implements mitk::DataStorage.

Definition at line 128 of file mitkStandaloneDataStorage.cpp.

{
  itk::MutexLockHolder<itk::SimpleFastMutexLock> locked(m_Mutex);
  return (m_SourceNodes.find(node) != m_SourceNodes.end());
}
mitk::DataStorage::SetOfObjects::ConstPointer mitk::StandaloneDataStorage::GetAll (  ) const [virtual]

returns a set of all data objects that are stored in the data storage

Implements mitk::DataStorage.

Definition at line 152 of file mitkStandaloneDataStorage.cpp.

{
  itk::MutexLockHolder<itk::SimpleFastMutexLock > locked(m_Mutex);
  if (!IsInitialized())
    throw std::logic_error("DataStorage not initialized");

  mitk::DataStorage::SetOfObjects::Pointer resultset = mitk::DataStorage::SetOfObjects::New();
  /* Fill resultset with all objects that are managed by the StandaloneDataStorage object */
  unsigned int index = 0;
  for (AdjacencyList::const_iterator it = m_SourceNodes.begin(); it != m_SourceNodes.end(); ++it)
    if (it->first.IsNull())
      continue;
    else
      resultset->InsertElement(index++, const_cast<mitk::DataNode*>(it->first.GetPointer()));

  return SetOfObjects::ConstPointer(resultset);
}
virtual const char* mitk::StandaloneDataStorage::GetClassName (  ) const [virtual]

Reimplemented from mitk::DataStorage.

Reimplemented in mitk::TestStandaloneDataStorage.

mitk::DataStorage::SetOfObjects::ConstPointer mitk::StandaloneDataStorage::GetDerivations ( const mitk::DataNode node,
const NodePredicateBase condition = NULL,
bool  onlyDirectDerivations = true 
) const [virtual]

returns a set of derived objects for a given node.

GetDerivations() returns a set of objects that are derived from the DataNode node. This means, that node was used to create the returned objects. If the parameter onlyDirectDerivations is set to true (default value), only objects that directly have node as one of their source objects will be returned. Otherwise, objects that are derived from derivations of node are returned too. The derived objects can be filtered with a predicate object as described in the GetSubset() method by providing a predicate as the condition parameter.

Implements mitk::DataStorage.

Definition at line 239 of file mitkStandaloneDataStorage.cpp.

{
  itk::MutexLockHolder<itk::SimpleFastMutexLock>locked(m_Mutex);
  return this->GetRelations(node, m_DerivedNodes, condition, onlyDirectDerivations);
}
mitk::DataStorage::SetOfObjects::ConstPointer mitk::StandaloneDataStorage::GetRelations ( const mitk::DataNode node,
const AdjacencyList relation,
const NodePredicateBase condition = NULL,
bool  onlyDirectlyRelated = true 
) const [protected]

Traverses the Relation graph and extracts a list of related elements (e.g. Sources or Derivations)

Definition at line 171 of file mitkStandaloneDataStorage.cpp.

References mitk::NodePredicateBase::CheckNode().

{
  if (node == NULL)
    throw std::invalid_argument("invalid node");

  /* Either read direct relations directly from adjacency list */
  if (onlyDirectlyRelated)
  {
    AdjacencyList::const_iterator it = relation.find(node); // get parents of current node
    if ((it == relation.end()) || (it->second.IsNull())) // node not found in list or no set of parents
      return SetOfObjects::ConstPointer(mitk::DataStorage::SetOfObjects::New());  // return an empty set
    else
      return this->FilterSetOfObjects(it->second, condition);
  }

  /* Or traverse adjacency list to collect all related nodes */
  std::vector<mitk::DataNode::ConstPointer> resultset;
  std::vector<mitk::DataNode::ConstPointer> openlist;

  /* Initialize openlist with node. this will add node to resultset,
     but that is necessary to detect circular relations that would lead to endless recursion */
  openlist.push_back(node);

  while (openlist.size() > 0)
  {
    mitk::DataNode::ConstPointer current = openlist.back();  // get element that needs to be processed
    openlist.pop_back();                      // remove last element, because it gets processed now
    resultset.push_back(current);             // add current element to resultset
    AdjacencyList::const_iterator it = relation.find(current); // get parents of current node
    if (   (it == relation.end())             // if node not found in list
        || (it->second.IsNull())              // or no set of parents available
        || (it->second->Size() == 0))         // or empty set of parents
      continue;                               // then continue with next node in open list
    else
      for (SetOfObjects::ConstIterator parentIt = it->second->Begin(); parentIt != it->second->End(); ++parentIt) // for each parent of current node
      {
        mitk::DataNode::ConstPointer p = parentIt.Value().GetPointer();
        if (   !(std::find(resultset.begin(), resultset.end(), p) != resultset.end())   // if it is not already in resultset
            && !(std::find(openlist.begin(), openlist.end(), p) != openlist.end()))     // and not already in openlist
          openlist.push_back(p);                                                        // then add it to openlist, so that it can be processed
      }
  }

  /* now finally copy the results to a proper SetOfObjects variable exluding the initial node and checking the condition if any is given */
  mitk::DataStorage::SetOfObjects::Pointer realResultset = mitk::DataStorage::SetOfObjects::New();
  if (condition != NULL)
  {
    for (std::vector<mitk::DataNode::ConstPointer>::iterator resultIt = resultset.begin(); resultIt != resultset.end(); resultIt++)
      if ((*resultIt != node) && (condition->CheckNode(*resultIt) == true))
        realResultset->InsertElement(realResultset->Size(), mitk::DataNode::Pointer(const_cast<mitk::DataNode*>((*resultIt).GetPointer())));
  }
  else
  {
    for (std::vector<mitk::DataNode::ConstPointer>::iterator resultIt = resultset.begin(); resultIt != resultset.end(); resultIt++)
      if (*resultIt != node)
        realResultset->InsertElement(realResultset->Size(), mitk::DataNode::Pointer(const_cast<mitk::DataNode*>((*resultIt).GetPointer())));
  }
  return SetOfObjects::ConstPointer(realResultset);
}
mitk::DataStorage::SetOfObjects::ConstPointer mitk::StandaloneDataStorage::GetSources ( const mitk::DataNode node,
const NodePredicateBase condition = NULL,
bool  onlyDirectSources = true 
) const [virtual]

returns a set of source objects for a given node that meet the given condition(s).

Implements mitk::DataStorage.

Definition at line 232 of file mitkStandaloneDataStorage.cpp.

{
  itk::MutexLockHolder<itk::SimpleFastMutexLock> locked(m_Mutex);
  return this->GetRelations(node, m_SourceNodes, condition, onlyDirectSources);
}
bool mitk::StandaloneDataStorage::IsInitialized (  ) const [protected]

convenience method to check if the object has been initialized (i.e. a data tree has been set)

Definition at line 47 of file mitkStandaloneDataStorage.cpp.

{
  return true;
}
static Pointer mitk::StandaloneDataStorage::New (  ) [static]
void mitk::StandaloneDataStorage::PrintSelf ( std::ostream &  os,
itk::Indent  indent 
) const [protected, virtual]

Prints the contents of the StandaloneDataStorage to os. Do not call directly, call ->Print() instead.

Reimplemented from mitk::DataStorage.

Definition at line 246 of file mitkStandaloneDataStorage.cpp.

{
  os << indent << "StandaloneDataStorage:\n";
  Superclass::PrintSelf(os, indent);
}
void mitk::StandaloneDataStorage::Remove ( const mitk::DataNode node ) [virtual]

Removes node from the StandaloneDataStorage.

Implements mitk::DataStorage.

Definition at line 100 of file mitkStandaloneDataStorage.cpp.

{
  if (!IsInitialized())
    throw std::logic_error("DataStorage not initialized");
  if (node == NULL)
    return;

  // remove ITK modified event listener
  this->RemoveListeners(node);

  // muellerm, 22.9.10: add additional reference count to ensure
  // that the node is not deleted when removed from the relation map
  // while m_Mutex is locked. This would cause the an itk::DeleteEvent
  // is thrown and a deadlock will occur when event receivers
  // access the DataStorage again in their event processing function
  //
  mitk::DataNode::ConstPointer nodeGuard(node);

  /* Notify observers of imminent node removal */
  EmitRemoveNodeEvent(node);
  {
    itk::MutexLockHolder<itk::SimpleFastMutexLock> locked(m_Mutex);
    /* remove node from both relation adjacency lists */
    this->RemoveFromRelation(node, m_SourceNodes);
    this->RemoveFromRelation(node, m_DerivedNodes);
  }
}
void mitk::StandaloneDataStorage::RemoveFromRelation ( const mitk::DataNode node,
AdjacencyList relation 
) [protected]

deletes all references to a node in a given relation (used in Remove() and TreeListener)

Definition at line 134 of file mitkStandaloneDataStorage.cpp.

{
  for (AdjacencyList::const_iterator mapIter = relation.begin(); mapIter != relation.end(); ++mapIter)  // for each node in the relation
    if (mapIter->second.IsNotNull())      // if node has a relation list
    {
      SetOfObjects::Pointer s = const_cast<SetOfObjects*>(mapIter->second.GetPointer());   // search for node to be deleted in the relation list
      SetOfObjects::STLContainerType::iterator relationListIter = std::find(s->begin(),  s->end(), node);   // this assumes, that the relation list does not contain duplicates (which should be safe to assume)
      if (relationListIter != s->end())     // if node to be deleted is in relation list
        s->erase(relationListIter);         // remove it from parentlist
    }
  /* now remove node from the relation */
  AdjacencyList::iterator adIt;
  adIt = relation.find(node);
  if (adIt != relation.end())
    relation.erase(adIt);
}

Member Data Documentation

Nodes are stored in reverse relation for easier traversal in the opposite direction of the relation.

Definition at line 129 of file mitkStandaloneDataStorage.h.

itk::SimpleFastMutexLock mitk::StandaloneDataStorage::m_Mutex [mutable]

Definition at line 93 of file mitkStandaloneDataStorage.h.

Nodes and their relation are stored in m_SourceNodes.

Definition at line 126 of file mitkStandaloneDataStorage.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines