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.cc \
hb-subset.hh \
hb-repacker.hh \
hb-repacker.hh \
$(NULL)
HB_SUBSET_headers = \

View File

@ -43,7 +43,7 @@ struct hb_priority_queue_t
~hb_priority_queue_t () { fini (); }
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;
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);

View File

@ -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);
}
}
}

View File

@ -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