From f561fa6e4c5572c60c8fcf40e617919e531e6ee3 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Thu, 18 Mar 2021 11:13:47 -0700 Subject: [PATCH] Change priority queue to use (priority, value) instead of (value, priority). --- src/Makefile.sources | 2 +- src/hb-priority-queue.hh | 24 ++++++++++++----------- src/hb-repacker.hh | 14 ++++++------- src/test-priority-queue.cc | 40 +++++++++++++++++++------------------- 4 files changed, 41 insertions(+), 39 deletions(-) diff --git a/src/Makefile.sources b/src/Makefile.sources index da97530fe..14c97996b 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -269,7 +269,7 @@ HB_SUBSET_sources = \ hb-subset-plan.hh \ hb-subset.cc \ hb-subset.hh \ - hb-repacker.hh \ + hb-repacker.hh \ $(NULL) HB_SUBSET_headers = \ diff --git a/src/hb-priority-queue.hh b/src/hb-priority-queue.hh index e47127edb..7d799ae90 100644 --- a/src/hb-priority-queue.hh +++ b/src/hb-priority-queue.hh @@ -43,7 +43,7 @@ struct hb_priority_queue_t ~hb_priority_queue_t () { fini (); } private: - typedef hb_pair_t item_t; + typedef hb_pair_t item_t; hb_vector_t heap; public: @@ -55,13 +55,13 @@ struct hb_priority_queue_t 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); } - item_t extract_minimum () + item_t pop_minimum () { item_t result = heap[0]; @@ -78,6 +78,8 @@ struct hb_priority_queue_t } 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. */ hb_priority_queue_t& operator << (item_t item) @@ -85,17 +87,17 @@ struct hb_priority_queue_t private: - unsigned parent (unsigned index) + static constexpr unsigned parent (unsigned index) { return (index - 1) / 2; } - unsigned left_child (unsigned index) + static constexpr unsigned left_child (unsigned index) { return 2 * index + 1; } - unsigned right_child (unsigned index) + static constexpr unsigned right_child (unsigned index) { return 2 * index + 2; } @@ -111,11 +113,11 @@ struct hb_priority_queue_t return; bool has_right = right < heap.length; - if (heap[index].second <= heap[left].second - && (!has_right || heap[index].second <= heap[right].second)) + if (heap[index].first <= heap[left].first + && (!has_right || heap[index].first <= heap[right].first)) return; - if (!has_right || heap[left].second < heap[right].second) + if (!has_right || heap[left].first < heap[right].first) { swap (index, left); bubble_down (left); @@ -131,7 +133,7 @@ struct hb_priority_queue_t if (index == 0) return; unsigned parent_index = parent (index); - if (heap[parent_index].second <= heap[index].second) + if (heap[parent_index].first <= heap[index].first) return; swap (index, parent_index); diff --git a/src/hb-repacker.hh b/src/hb-repacker.hh index 2b1e0fc56..cb0f8d613 100644 --- a/src/hb-repacker.hh +++ b/src/hb-repacker.hh @@ -288,12 +288,12 @@ struct graph_t check_success (removed_edges.resize (vertices_.length)); 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 (); unsigned order = 1; 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]; 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 // distance they'll be added to the topological order in the order that they are // referenced from the parent object. - queue.insert (link.objidx, - vertices_[link.objidx].modified_distance (order++)); + queue.insert (vertices_[link.objidx].modified_distance (order++), + link.objidx); } } @@ -509,13 +509,13 @@ struct graph_t } hb_priority_queue_t queue; - queue.insert (vertices_.length - 1, 0); + queue.insert (0, vertices_.length - 1); hb_set_t visited; 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; const auto& next = vertices_[next_idx]; int64_t next_distance = vertices_[next_idx].distance; @@ -533,7 +533,7 @@ struct graph_t if (child_distance < vertices_[link.objidx].distance) { vertices_[link.objidx].distance = child_distance; - queue.insert (link.objidx, child_distance); + queue.insert (child_distance, link.objidx); } } } diff --git a/src/test-priority-queue.cc b/src/test-priority-queue.cc index 65c2a320b..fab63acb6 100644 --- a/src/test-priority-queue.cc +++ b/src/test-priority-queue.cc @@ -33,21 +33,21 @@ test_insert () hb_priority_queue_t queue; assert (queue.is_empty ()); - queue.insert (0, 10); + queue.insert (10, 0); assert (!queue.is_empty ()); - assert (queue.minimum () == hb_pair (0, 10)); + assert (queue.minimum () == hb_pair (10, 0)); - queue.insert (1, 20); - assert (queue.minimum () == hb_pair (0, 10)); + queue.insert (20, 1); + assert (queue.minimum () == hb_pair (10, 0)); - queue.insert (2, 5); - assert (queue.minimum () == hb_pair (2, 5)); + queue.insert (5, 2); + assert (queue.minimum () == hb_pair (5, 2)); - queue.insert (3, 15); - assert (queue.minimum () == hb_pair (2, 5)); + queue.insert (15, 3); + assert (queue.minimum () == hb_pair (5, 2)); - queue.insert (4, 1); - assert (queue.minimum () == hb_pair (4, 1)); + queue.insert (1, 4); + assert (queue.minimum () == hb_pair (1, 4)); } static void @@ -55,19 +55,19 @@ test_extract () { hb_priority_queue_t queue; queue.insert (0, 0); - queue.insert (6, 60); - queue.insert (3, 30); - queue.insert (4, 40); - queue.insert (2, 20); - queue.insert (5, 50); - queue.insert (7, 70); - queue.insert (1, 10); + queue.insert (60, 6); + queue.insert (30, 3); + queue.insert (40 ,4); + queue.insert (20, 2); + queue.insert (50, 5); + queue.insert (70, 7); + queue.insert (10, 1); for (int i = 0; i < 8; i++) { assert (!queue.is_empty ()); - assert (queue.minimum () == hb_pair (i, i * 10)); - assert (queue.extract_minimum () == hb_pair (i, i * 10)); + assert (queue.minimum () == hb_pair (i * 10, i)); + assert (queue.pop_minimum () == hb_pair (i * 10, i)); } assert (queue.is_empty ()); @@ -77,7 +77,7 @@ static void test_extract_empty () { hb_priority_queue_t queue; - assert (queue.extract_minimum () == hb_pair (0, 0)); + assert (queue.pop_minimum () == hb_pair (0, 0)); } int