Reputation: 9798
I have created a labeled graph:
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
Item, Link > UnGraph;
My labels are uint64_t, I want to have my own ids on the graph.
If I add a node, everything is fine, I only have the nodes with my labels.
m_g.add_vertex(nodeId, Item(nodeId));
I want to check if a label is in my graph:
auto BUnGraph::exists( nid source ) const -> bool
{
if( m_g.vertex(source) == BUnGraph::null_vertex() )
return false;
else
return true;
}
But the method:
vertex(source)
gives me false results, and returns me a default constructed vertex_descriptor when a node is not in the graph instead of a null_vertex() depending on the label ...
I have isolated the method in boost:
labeled_graph.hpp
/** @name Find Labeled Vertex */
//@{
// Tag dispatch for sequential maps (i.e., vectors).
template <typename Container, typename Graph, typename Label>
typename graph_traits<Graph>::vertex_descriptor
find_labeled_vertex(Container const& c, Graph const&, Label const& l,
random_access_container_tag)
{ return l < c.size() ? c[l] : graph_traits<Graph>::null_vertex(); }
and checked the internal map. If I add a single node in the graph, map.size() == 42. Instead of 1 ! If I add 5 nodes size() == 248.
Depending on the id, the map size is equal to: max label value * 2 + 2 So any label number inferior to map.size() will give false results.
What's going on ?
EDIT: I put a label like 60000000, in my graph, only one node. My computer ran out of memory ...
Upvotes: 2
Views: 539
Reputation: 9798
I found the line responsible for this:
/**
* Choose the default map instance. If Label is an unsigned integral type
* the we can use a vector to store the information.
*/
template <typename Label, typename Vertex>
struct choose_default_map {
typedef typename mpl::if_<
is_unsigned<Label>,
std::vector<Vertex>,
std::map<Label, Vertex> // TODO: Should use unordered_map?
>::type type;
};
If the type is unsigned, so uint8_t, 16, 32, 64 it will use a vector. I cannot find a good use case for this behavior. It is very dangerous.
So, the only solution I found is to use from now on int64_t instead of uint64_t.
Upvotes: 3