Commit 46454b3d authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

Implement reindexing of property maps after vertex purge

After the removal of filtered vertices via Graph.purge_vertices(), the
values of known property maps are now kept consistent with the
unmodified graph.
parent 0595e4f3
...@@ -91,11 +91,12 @@ public: ...@@ -91,11 +91,12 @@ public:
// graph modification // graph modification
void InsertPropertyMap(string name, boost::any map); void InsertPropertyMap(string name, boost::any map);
void ReIndexEdges(); void ReIndexEdges();
void PurgeVertices(); // removes filtered vertices void PurgeVertices(boost::any old_index); // removes filtered vertices
void PurgeEdges(); // removes filtered edges void PurgeEdges(); // removes filtered edges
void Clear(); void Clear();
void ClearEdges(); void ClearEdges();
void ShiftVertexProperty(boost::any map, size_t index) const; void ShiftVertexProperty(boost::any map, size_t index) const;
void ReIndexVertexProperty(boost::any map, boost::any old_index) const;
void CopyVertexProperty(const GraphInterface& src, boost::any prop_src, void CopyVertexProperty(const GraphInterface& src, boost::any prop_src,
boost::any prop_tgt); boost::any prop_tgt);
void CopyEdgeProperty(const GraphInterface& src, boost::any prop_src, void CopyEdgeProperty(const GraphInterface& src, boost::any prop_src,
......
...@@ -362,6 +362,7 @@ BOOST_PYTHON_MODULE(libgraph_tool_core) ...@@ -362,6 +362,7 @@ BOOST_PYTHON_MODULE(libgraph_tool_core)
.def("PurgeVertices", &GraphInterface::PurgeVertices) .def("PurgeVertices", &GraphInterface::PurgeVertices)
.def("PurgeEdges", &GraphInterface::PurgeEdges) .def("PurgeEdges", &GraphInterface::PurgeEdges)
.def("ShiftVertexProperty", &GraphInterface::ShiftVertexProperty) .def("ShiftVertexProperty", &GraphInterface::ShiftVertexProperty)
.def("ReIndexVertexProperty", &GraphInterface::ReIndexVertexProperty)
.def("WriteToFile", &GraphInterface::WriteToFile) .def("WriteToFile", &GraphInterface::WriteToFile)
.def("ReadFromFile",&GraphInterface::ReadFromFile) .def("ReadFromFile",&GraphInterface::ReadFromFile)
.def("DegreeMap", &GraphInterface::DegreeMap) .def("DegreeMap", &GraphInterface::DegreeMap)
......
...@@ -243,19 +243,25 @@ void GraphInterface::PurgeEdges() ...@@ -243,19 +243,25 @@ void GraphInterface::PurgeEdges()
} }
// this will definitively remove all the verticess from the graph, which are // this will definitively remove all the vertices from the graph, which are
// being currently filtered out. This will also disable the vertex filter // being currently filtered out. This will also disable the vertex filter
void GraphInterface::PurgeVertices() void GraphInterface::PurgeVertices(boost::any aold_index)
{ {
if (!IsVertexFilterActive()) if (!IsVertexFilterActive())
return; return;
typedef property_map_type::apply<int32_t,
GraphInterface::vertex_index_map_t>::type
index_prop_t;
index_prop_t old_index = any_cast<index_prop_t>(aold_index);
MaskFilter<vertex_filter_t> filter(_vertex_filter_map, MaskFilter<vertex_filter_t> filter(_vertex_filter_map,
_vertex_filter_invert); _vertex_filter_invert);
size_t N = num_vertices(_state->_mg); size_t N = num_vertices(_state->_mg);
vector<bool> deleted(N, false); vector<bool> deleted(N, false);
for (size_t i = 0; i < N; ++i) for (size_t i = 0; i < N; ++i)
deleted[i] = !filter(vertex(i, _state->_mg)); deleted[i] = !filter(vertex(i, _state->_mg));
vector<int> old_indexes;
vector<graph_traits<multigraph_t>::edge_descriptor> edges; vector<graph_traits<multigraph_t>::edge_descriptor> edges;
...@@ -278,6 +284,16 @@ void GraphInterface::PurgeVertices() ...@@ -278,6 +284,16 @@ void GraphInterface::PurgeVertices()
remove_vertex(v, _state->_mg); remove_vertex(v, _state->_mg);
edges.clear(); edges.clear();
} }
else
{
old_indexes.push_back(i);
}
}
N = old_indexes.size();
for (int i = N-1; i >= 0; --i)
{
old_index[vertex((N - 1) - i, _state->_mg)] = old_indexes[i];
} }
} }
......
...@@ -74,6 +74,43 @@ void GraphInterface::ShiftVertexProperty(boost::any prop, size_t index) const ...@@ -74,6 +74,43 @@ void GraphInterface::ShiftVertexProperty(boost::any prop, size_t index) const
throw GraphException("invalid writable property map"); throw GraphException("invalid writable property map");
} }
struct reindex_vertex_property
{
template <class PropertyMap, class IndexMap>
void operator()(PropertyMap, const GraphInterface::multigraph_t& g,
boost::any map, IndexMap old_index, bool& found) const
{
try
{
PropertyMap pmap = any_cast<PropertyMap>(map);
for (size_t i = 0; i < num_vertices(g); ++i)
{
GraphInterface::vertex_t v = vertex(i, g);
pmap[v] = pmap[vertex(old_index[v], g)];
}
found = true;
}
catch (bad_any_cast&) {}
}
};
void GraphInterface::ReIndexVertexProperty(boost::any map,
boost::any aold_index) const
{
typedef property_map_type::apply<int32_t,
GraphInterface::vertex_index_map_t>::type
index_prop_t;
index_prop_t old_index = any_cast<index_prop_t>(aold_index);
bool found = false;
mpl::for_each<writable_vertex_properties>
(bind<void>(reindex_vertex_property(), _1, ref(_state->_mg),
map, old_index, ref(found)));
if (!found)
throw GraphException("invalid writable property map");
}
} // graph_tool namespace } // graph_tool namespace
......
...@@ -1463,13 +1463,19 @@ class Graph(object): ...@@ -1463,13 +1463,19 @@ class Graph(object):
def purge_vertices(self): def purge_vertices(self):
"""Remove all vertices of the graph which are currently being filtered """Remove all vertices of the graph which are currently being filtered
out, and return it to the unfiltered state.""" out, and return it to the unfiltered state. This operation is not
self.__graph.PurgeVertices() reversible."""
old_indexes = self.vertex_index.copy("int32_t")
self.__graph.PurgeVertices(_prop("v", self, old_indexes))
self.set_vertex_filter(None) self.set_vertex_filter(None)
for pmap in self.__known_properties:
if pmap[0] == "v" and pmap[1]() != None and pmap[1]().is_writable():
self.__graph.ReIndexVertexProperty(pmap[1]().get_map(),
_prop("v", self, old_indexes))
def purge_edges(self): def purge_edges(self):
"""Remove all edges of the graph which are currently being filtered out, """Remove all edges of the graph which are currently being filtered out,
and return it to the unfiltered state.""" and return it to the unfiltered state. This operation is not reversible."""
self.__graph.PurgeEdges() self.__graph.PurgeEdges()
self.set_edge_filter(None) self.set_edge_filter(None)
......
Markdown is supported
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