Change priority queue to use (priority, value) instead of (value, priority).

This commit is contained in:
Garret Rieger 2021-03-18 11:13:47 -07:00
parent b14475d2ae
commit f561fa6e4c
4 changed files with 41 additions and 39 deletions

View File

@ -269,7 +269,7 @@ HB_SUBSET_sources = \
hb-subset-plan.hh \ hb-subset-plan.hh \
hb-subset.cc \ hb-subset.cc \
hb-subset.hh \ hb-subset.hh \
hb-repacker.hh \ hb-repacker.hh \
$(NULL) $(NULL)
HB_SUBSET_headers = \ HB_SUBSET_headers = \

View File

@ -43,7 +43,7 @@ struct hb_priority_queue_t
~hb_priority_queue_t () { fini (); } ~hb_priority_queue_t () { fini (); }
private: private:
typedef hb_pair_t<unsigned, int64_t> item_t; typedef hb_pair_t<int64_t, unsigned> item_t;
hb_vector_t<item_t> heap; hb_vector_t<item_t> heap;
public: public:
@ -55,13 +55,13 @@ struct hb_priority_queue_t
bool in_error () const { return heap.in_error (); } bool in_error () const { return heap.in_error (); }
void insert (unsigned value, int64_t priority) void insert (int64_t priority, unsigned value)
{ {
heap.push (item_t (value, priority)); heap.push (item_t (priority, value));
bubble_up (heap.length - 1); bubble_up (heap.length - 1);
} }
item_t extract_minimum () item_t pop_minimum ()
{ {
item_t result = heap[0]; item_t result = heap[0];
@ -78,6 +78,8 @@ struct hb_priority_queue_t
} }
bool is_empty () const { return heap.length == 0; } bool is_empty () const { return heap.length == 0; }
explicit operator bool () const { return !is_empty (); }
unsigned int get_population () const { return heap.length; }
/* Sink interface. */ /* Sink interface. */
hb_priority_queue_t& operator << (item_t item) hb_priority_queue_t& operator << (item_t item)
@ -85,17 +87,17 @@ struct hb_priority_queue_t
private: private:
unsigned parent (unsigned index) static constexpr unsigned parent (unsigned index)
{ {
return (index - 1) / 2; return (index - 1) / 2;
} }
unsigned left_child (unsigned index) static constexpr unsigned left_child (unsigned index)
{ {
return 2 * index + 1; return 2 * index + 1;
} }
unsigned right_child (unsigned index) static constexpr unsigned right_child (unsigned index)
{ {
return 2 * index + 2; return 2 * index + 2;
} }
@ -111,11 +113,11 @@ struct hb_priority_queue_t
return; return;
bool has_right = right < heap.length; bool has_right = right < heap.length;
if (heap[index].second <= heap[left].second if (heap[index].first <= heap[left].first
&& (!has_right || heap[index].second <= heap[right].second)) && (!has_right || heap[index].first <= heap[right].first))
return; return;
if (!has_right || heap[left].second < heap[right].second) if (!has_right || heap[left].first < heap[right].first)
{ {
swap (index, left); swap (index, left);
bubble_down (left); bubble_down (left);
@ -131,7 +133,7 @@ struct hb_priority_queue_t
if (index == 0) return; if (index == 0) return;
unsigned parent_index = parent (index); unsigned parent_index = parent (index);
if (heap[parent_index].second <= heap[index].second) if (heap[parent_index].first <= heap[index].first)
return; return;
swap (index, parent_index); swap (index, parent_index);

View File

@ -288,12 +288,12 @@ struct graph_t
check_success (removed_edges.resize (vertices_.length)); check_success (removed_edges.resize (vertices_.length));
update_incoming_edge_count (); update_incoming_edge_count ();
queue.insert (root_idx (), root ().modified_distance (0)); queue.insert (root ().modified_distance (0), root_idx ());
int new_id = root_idx (); int new_id = root_idx ();
unsigned order = 1; unsigned order = 1;
while (!queue.in_error () && !queue.is_empty ()) while (!queue.in_error () && !queue.is_empty ())
{ {
unsigned next_id = queue.extract_minimum().first; unsigned next_id = queue.pop_minimum().second;
vertex_t& next = vertices_[next_id]; vertex_t& next = vertices_[next_id];
sorted_graph.push (next); sorted_graph.push (next);
@ -307,8 +307,8 @@ struct graph_t
// way. More specifically this is set up so that if a set of objects have the same // way. More specifically this is set up so that if a set of objects have the same
// distance they'll be added to the topological order in the order that they are // distance they'll be added to the topological order in the order that they are
// referenced from the parent object. // referenced from the parent object.
queue.insert (link.objidx, queue.insert (vertices_[link.objidx].modified_distance (order++),
vertices_[link.objidx].modified_distance (order++)); link.objidx);
} }
} }
@ -509,13 +509,13 @@ struct graph_t
} }
hb_priority_queue_t queue; hb_priority_queue_t queue;
queue.insert (vertices_.length - 1, 0); queue.insert (0, vertices_.length - 1);
hb_set_t visited; hb_set_t visited;
while (!queue.in_error () && !queue.is_empty ()) while (!queue.in_error () && !queue.is_empty ())
{ {
unsigned next_idx = queue.extract_minimum ().first; unsigned next_idx = queue.pop_minimum ().second;
if (visited.has (next_idx)) continue; if (visited.has (next_idx)) continue;
const auto& next = vertices_[next_idx]; const auto& next = vertices_[next_idx];
int64_t next_distance = vertices_[next_idx].distance; int64_t next_distance = vertices_[next_idx].distance;
@ -533,7 +533,7 @@ struct graph_t
if (child_distance < vertices_[link.objidx].distance) if (child_distance < vertices_[link.objidx].distance)
{ {
vertices_[link.objidx].distance = child_distance; vertices_[link.objidx].distance = child_distance;
queue.insert (link.objidx, child_distance); queue.insert (child_distance, link.objidx);
} }
} }
} }

View File

@ -33,21 +33,21 @@ test_insert ()
hb_priority_queue_t queue; hb_priority_queue_t queue;
assert (queue.is_empty ()); assert (queue.is_empty ());
queue.insert (0, 10); queue.insert (10, 0);
assert (!queue.is_empty ()); assert (!queue.is_empty ());
assert (queue.minimum () == hb_pair (0, 10)); assert (queue.minimum () == hb_pair (10, 0));
queue.insert (1, 20); queue.insert (20, 1);
assert (queue.minimum () == hb_pair (0, 10)); assert (queue.minimum () == hb_pair (10, 0));
queue.insert (2, 5); queue.insert (5, 2);
assert (queue.minimum () == hb_pair (2, 5)); assert (queue.minimum () == hb_pair (5, 2));
queue.insert (3, 15); queue.insert (15, 3);
assert (queue.minimum () == hb_pair (2, 5)); assert (queue.minimum () == hb_pair (5, 2));
queue.insert (4, 1); queue.insert (1, 4);
assert (queue.minimum () == hb_pair (4, 1)); assert (queue.minimum () == hb_pair (1, 4));
} }
static void static void
@ -55,19 +55,19 @@ test_extract ()
{ {
hb_priority_queue_t queue; hb_priority_queue_t queue;
queue.insert (0, 0); queue.insert (0, 0);
queue.insert (6, 60); queue.insert (60, 6);
queue.insert (3, 30); queue.insert (30, 3);
queue.insert (4, 40); queue.insert (40 ,4);
queue.insert (2, 20); queue.insert (20, 2);
queue.insert (5, 50); queue.insert (50, 5);
queue.insert (7, 70); queue.insert (70, 7);
queue.insert (1, 10); queue.insert (10, 1);
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
assert (!queue.is_empty ()); assert (!queue.is_empty ());
assert (queue.minimum () == hb_pair (i, i * 10)); assert (queue.minimum () == hb_pair (i * 10, i));
assert (queue.extract_minimum () == hb_pair (i, i * 10)); assert (queue.pop_minimum () == hb_pair (i * 10, i));
} }
assert (queue.is_empty ()); assert (queue.is_empty ());
@ -77,7 +77,7 @@ static void
test_extract_empty () test_extract_empty ()
{ {
hb_priority_queue_t queue; hb_priority_queue_t queue;
assert (queue.extract_minimum () == hb_pair (0, 0)); assert (queue.pop_minimum () == hb_pair (0, 0));
} }
int int