Commit 79f1892d authored by David Thompson's avatar David Thompson
Browse files

Add a multi-index-container for node storage.

This requires Ryan's branch for smtk::graph::Resource changes.
parent 4aad98ed
......@@ -315,7 +315,7 @@ nodeClasses = {
'type': { 'type': 'smtk::string::Token' }, # scalar, vector, tensor, bigfoot
'order': { 'type': 'std::vector<int>' }, # dimension of each tuple
'ids': { 'type': 'std::weak_ptr<smtk::markup::AssignedIds>' },
'index': { 'type': 'std::weak_ptr<smtk::markup::Index>' },
'lookup': { 'type': 'std::weak_ptr<smtk::markup::Index>' }, # reverse lookup table
},
'methods': {
'name': {
......
......@@ -41,6 +41,8 @@ list(APPEND classes
Comment
Feature
Landmark
detail/NodeContainer
# arcs/Children<NodeType, bool Hold>
# arcs/Parents<NodeType>
# arcs/DerivedData
......
......@@ -19,6 +19,8 @@ class Label;
class SMTKMARKUP_EXPORT Component : public smtk::graph::Component
{
public:
using Index = std::size_t;
smtkTypeMacro(smtk::markup::Component);
smtkSuperclassMacro(smtk::graph::Component);
......@@ -30,6 +32,14 @@ public:
~Component() override;
/// A unique integer corresponding to the component type.
static const Component::Index type_index;
/**\brief The index is a compile-time intrinsic of the derived resource;
* as such, it cannot be set.
*/
virtual Index index() const { return std::type_index(typeid(*this)).hash_code(); }
ArcEditor<SelfType, smtk::markup::Group> groups() const;
ArcEditor<SelfType, smtk::markup::Label> labels() const;
......
......@@ -88,26 +88,26 @@ std::weak_ptr<smtk::markup::AssignedIds>& Field::ids()
return m_ids;
}
bool Field::setIndex(const std::weak_ptr<smtk::markup::Index>& index)
bool Field::setLookup(const std::weak_ptr<smtk::markup::Index>& lookup)
{
auto mlocked = m_index.lock();
auto vlocked = index.lock();
auto mlocked = m_lookup.lock();
auto vlocked = lookup.lock();
if (mlocked == vlocked)
{
return false;
}
m_index = vlocked;
m_lookup = vlocked;
return true;
}
const std::weak_ptr<smtk::markup::Index>& Field::index() const
const std::weak_ptr<smtk::markup::Index>& Field::lookup() const
{
return m_index;
return m_lookup;
}
std::weak_ptr<smtk::markup::Index>& Field::index()
std::weak_ptr<smtk::markup::Index>& Field::lookup()
{
return m_index;
return m_lookup;
}
......
......@@ -45,19 +45,19 @@ public:
const std::weak_ptr<smtk::markup::AssignedIds>& ids() const;
std::weak_ptr<smtk::markup::AssignedIds>& ids();
bool setIndex(const std::weak_ptr<smtk::markup::Index>& index);
const std::weak_ptr<smtk::markup::Index>& index() const;
std::weak_ptr<smtk::markup::Index>& index();
bool setLookup(const std::weak_ptr<smtk::markup::Index>& lookup);
const std::weak_ptr<smtk::markup::Index>& lookup() const;
std::weak_ptr<smtk::markup::Index>& lookup();
protected:
smtk::string::Token m_name;
smtk::string::Token m_type;
std::vector<int> m_order;
std::weak_ptr<smtk::markup::AssignedIds> m_ids;
std::weak_ptr<smtk::markup::Index> m_index;
std::weak_ptr<smtk::markup::Index> m_lookup;
};
} // namespace markup
} // namespace smtk
#endif // smtk_markup_Field_h
\ No newline at end of file
#endif // smtk_markup_Field_h
......@@ -47,6 +47,7 @@
#include "smtk/markup/Subset.h"
#include "smtk/markup/SurfaceGrid.h"
#include "smtk/markup/VolumeGrid.h"
#include "smtk/markup/detail/NodeContainer.h"
#include <tuple>
......@@ -109,6 +110,7 @@ struct SMTKMARKUP_EXPORT Traits
ParentsAs<Edge>, Parents>
ArcTypes;
*/
using NodeStorage = detail::NodeContainer;
};
}
}
......
// Copyright © Kitware Inc under the [BSD-3-clause license](https://opensource.org/licenses/BSD-3-Clause).
#include "smtk/markup/detail/NodeContainer.h"
namespace smtk
{
namespace markup
{
namespace detail
{
void NodeContainer::visit(Visitor visitor) const
{
const auto& nodesById = m_nodes.get<IdTag>();
for (const auto& node : nodesById)
{
auto component = std::dynamic_pointer_cast<smtk::resource::Component>(node);
visitor(component);
}
}
smtk::resource::ComponentPtr NodeContainer::find(const smtk::common::UUID& uuid) const
{
smtk::resource::ComponentPtr result;
const auto& nodesById = m_nodes.get<IdTag>();
auto it = nodesById.find(uuid);
if (it != nodesById.end())
{
result = *it;
}
return result;
}
bool NodeContainer::eraseNode(const smtk::resource::ComponentPtr& node)
{
bool didErase = false;
auto graphNode = std::dynamic_pointer_cast<Component>(node);
if (!graphNode)
{
return didErase;
}
auto& nodesById = m_nodes.get<IdTag>();
auto it = nodesById.find(graphNode->id());
if (it != nodesById.end())
{
nodesById.erase(node->id());
didErase = true;
}
return didErase;
}
bool NodeContainer::insertNode(const smtk::resource::ComponentPtr& node)
{
bool didInsert = false;
auto graphNode = std::dynamic_pointer_cast<Component>(node);
if (!graphNode)
{
return didInsert;
}
auto& nodesById = m_nodes.get<IdTag>();
auto result = nodesById.insert(graphNode);
return result.second;
}
} // namespace detail
} // namespace markup
} // namespace smtk
// Copyright © Kitware Inc under the [BSD-3-clause license](https://opensource.org/licenses/BSD-3-Clause).
#ifndef smtk_markup_detail_NodeContainer_h
#define smtk_markup_detail_NodeContainer_h
#include "smtk/markup/Component.h"
#include "smtk/common/UUID.h"
#include "boost/multi_index/global_fun.hpp"
#include "boost/multi_index/mem_fun.hpp"
#include "boost/multi_index/ordered_index.hpp"
#include "boost/multi_index_container.hpp"
#include <memory>
#include <string>
namespace smtk
{
namespace markup
{
namespace detail
{
/// Unique index of markup nodes by their UUID.
struct SMTKMARKUP_EXPORT IdTag
{
};
/// Non-unique index of markup nodes by their user-assigned name.
struct SMTKMARKUP_EXPORT NameTag
{
};
/// Non-unique index of markup nodes by their type-name.
struct SMTKMARKUP_EXPORT TypeNameTag
{
};
/// Non-unique index of markup nodes by their type-index.
struct SMTKMARKUP_EXPORT TypeIndexTag
{
};
/// Extract a component's UUID for indexing.
inline const smtk::common::UUID& id(const Component::Ptr& c)
{
return c->id();
}
/// Extract a component's type-index for indexing.
inline smtk::markup::Component::Index typeIndex(const Component::Ptr& c)
{
return c->index();
}
/// Extract a component's type-name for indexing.
inline std::string typeName(const Component::Ptr& c)
{
return c->typeName();
}
/// Extract a component's user-assigned name for indexing.
inline std::string name(const Component::Ptr& c)
{
return c->name();
}
/**\brief Storage for markup graph nodes.
*/
class SMTKMARKUP_EXPORT NodeContainer
{
public:
using Visitor = std::function<void(smtk::resource::ComponentPtr&)>;
/// Call a visitor function on each node in the graph
void visit(Visitor visitor) const;
/// Find the node with a given \a uuid, or return nullptr.
smtk::resource::ComponentPtr find(const smtk::common::UUID& uuid) const;
protected:
/**\brief Erase the given \a node from the container without updating any arcs.
*
* This internal method may be used for temporary removal, modification, and
* re-insertion in cases where \a node data that is indexed must be changed.
* In that case, arcs must not be modified.
*/
bool eraseNode(const smtk::resource::ComponentPtr& node);
/**\brief Unconditionally insert the given \a node into the container.
*
* Do not check against NodeTypes to see whether the node type is
* allowed; this has already been done.
*/
bool insertNode(const smtk::resource::ComponentPtr& node);
/// The node-container typename, which specifies how to index nodes.
using Container =
boost::multi_index_container<
std::shared_ptr<smtk::markup::Component>,
boost::multi_index::indexed_by<
boost::multi_index::ordered_unique< // Should be hashed
boost::multi_index::tag<IdTag>,
boost::multi_index::global_fun<const Component::Ptr&, const smtk::common::UUID&, &detail::id>
>,
boost::multi_index::ordered_non_unique<
boost::multi_index::tag<NameTag>,
boost::multi_index::global_fun<const Component::Ptr&, std::string, &detail::name>
>,
boost::multi_index::ordered_non_unique< // Should be hashed
boost::multi_index::tag<TypeIndexTag>,
boost::multi_index::global_fun<const Component::Ptr&, smtk::markup::Component::Index, &detail::typeIndex>
>,
boost::multi_index::ordered_non_unique< // Should be hashed
boost::multi_index::tag<TypeNameTag>,
boost::multi_index::global_fun<const Component::Ptr&, std::string, &detail::typeName>
>
>
>;
Container m_nodes;
};
} // namespace detail
} // namespace markup
} // namespace smtk
#endif // smtk_markup_detail_NodeContainer_h
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment