[graph] Speed-up vertices having only one parent

pull/4343/head
Behdad Esfahbod 1 year ago
parent f3d0b11d57
commit 1b5abb1781
  1. 55
      src/graph/graph.hh

@ -49,12 +49,16 @@ struct graph_t
unsigned priority = 0;
private:
unsigned incoming_edges_ = 0;
unsigned single_parent = (unsigned) -1;
hb_hashmap_t<unsigned, unsigned> parents;
public:
auto parents_iter () const HB_AUTO_RETURN
const auto parents_iter () const HB_AUTO_RETURN
(
parents.keys ()
hb_concat (
hb_iter (&single_parent, single_parent != (unsigned) -1),
parents.keys_ref ()
)
)
bool parents_in_error () const
@ -155,6 +159,7 @@ struct graph_t
hb_swap (a.obj, b.obj);
hb_swap (a.distance, b.distance);
hb_swap (a.space, b.space);
hb_swap (a.single_parent, b.single_parent);
hb_swap (a.parents, b.parents);
hb_swap (a.incoming_edges_, b.incoming_edges_);
hb_swap (a.start, b.start);
@ -188,17 +193,37 @@ struct graph_t
void reset_parents ()
{
incoming_edges_ = 0;
single_parent = (unsigned) -1;
parents.reset ();
}
void add_parent (unsigned parent_index)
{
if (incoming_edges_ == 0)
{
single_parent = parent_index;
incoming_edges_ = 1;
return;
}
else if (single_parent != (unsigned) -1)
{
parents.set (single_parent, 1);
single_parent = (unsigned) -1;
}
incoming_edges_++;
parents.set (parent_index, parents[parent_index] + 1);
}
void remove_parent (unsigned parent_index)
{
if (parent_index == single_parent)
{
single_parent = (unsigned) -1;
incoming_edges_--;
return;
}
unsigned *v;
if (parents.has (parent_index, &v))
{
@ -207,6 +232,12 @@ struct graph_t
*v -= 1;
else
parents.del (parent_index);
if (incoming_edges_ == 1)
{
single_parent = *parents.keys ();
parents.reset ();
}
}
}
@ -229,18 +260,9 @@ struct graph_t
void remap_parents (const hb_vector_t<unsigned>& id_map)
{
if (parents.get_population () == 1)
if (single_parent != (unsigned) -1)
{
// Fast path for the common case.
const auto &_ = *parents.iter_ref ();
unsigned old_index = _.first;
unsigned new_index = id_map[old_index];
if (old_index != new_index)
{
unsigned v = _.second;
parents.del (old_index);
parents.set (new_index, v);
}
single_parent = id_map[single_parent];
return;
}
@ -254,6 +276,13 @@ struct graph_t
void remap_parent (unsigned old_index, unsigned new_index)
{
if (single_parent != (unsigned) -1)
{
if (single_parent == old_index)
single_parent = new_index;
return;
}
if (parents.has (old_index))
{
remove_parent (old_index);

Loading…
Cancel
Save