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:
// graph modification
void InsertPropertyMap(string name, boost::any map);
void ReIndexEdges();
void PurgeVertices(); // removes filtered vertices
void PurgeVertices(boost::any old_index); // removes filtered vertices
void PurgeEdges(); // removes filtered edges
void Clear();
void ClearEdges();
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,
boost::any prop_tgt);
void CopyEdgeProperty(const GraphInterface& src, boost::any prop_src,
......
......@@ -362,6 +362,7 @@ BOOST_PYTHON_MODULE(libgraph_tool_core)
.def("PurgeVertices", &GraphInterface::PurgeVertices)
.def("PurgeEdges", &GraphInterface::PurgeEdges)
.def("ShiftVertexProperty", &GraphInterface::ShiftVertexProperty)
.def("ReIndexVertexProperty", &GraphInterface::ReIndexVertexProperty)
.def("WriteToFile", &GraphInterface::WriteToFile)
.def("ReadFromFile",&GraphInterface::ReadFromFile)
.def("DegreeMap", &GraphInterface::DegreeMap)
......
......@@ -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
void GraphInterface::PurgeVertices()
void GraphInterface::PurgeVertices(boost::any aold_index)
{
if (!IsVertexFilterActive())
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,
_vertex_filter_invert);
size_t N = num_vertices(_state->_mg);
vector<bool> deleted(N, false);
for (size_t i = 0; i < N; ++i)
deleted[i] = !filter(vertex(i, _state->_mg));
vector<int> old_indexes;
vector<graph_traits<multigraph_t>::edge_descriptor> edges;
......@@ -278,6 +284,16 @@ void GraphInterface::PurgeVertices()
remove_vertex(v, _state->_mg);
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
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
......
......@@ -1463,13 +1463,19 @@ class Graph(object):
def purge_vertices(self):
"""Remove all vertices of the graph which are currently being filtered
out, and return it to the unfiltered state."""
self.__graph.PurgeVertices()
out, and return it to the unfiltered state. This operation is not
reversible."""
old_indexes = self.vertex_index.copy("int32_t")
self.__graph.PurgeVertices(_prop("v", self, old_indexes))
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):
"""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.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