[instancer] templatize the priority queue, use custom type for varstore

when instantiating varstore, we need to pop a tuple like
(combined_gain, i, j), if combined gain is the same then we compare the
value of i, and then j. So we'd like to use custom type as the key when
popping from the queue. This would match fonttool's algorithm cause it
uses heappop().
pull/4440/head
Qunxin Liu 1 year ago committed by Garret Rieger
parent bbd53fcfa4
commit 1f395cbaf9
  1. 4
      src/graph/graph.hh
  2. 47
      src/hb-ot-var-common.hh
  3. 5
      src/hb-priority-queue.hh
  4. 4
      src/test-priority-queue.cc

@ -566,7 +566,7 @@ struct graph_t
update_distances ();
hb_priority_queue_t queue;
hb_priority_queue_t<int64_t> queue;
hb_vector_t<vertex_t> &sorted_graph = vertices_scratch_;
if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return;
hb_vector_t<unsigned> id_map;
@ -1369,7 +1369,7 @@ struct graph_t
vertices_.arrayZ[i].distance = hb_int_max (int64_t);
vertices_.tail ().distance = 0;
hb_priority_queue_t queue;
hb_priority_queue_t<int64_t> queue;
queue.insert (0, vertices_.length - 1);
hb_vector_t<bool> visited;

@ -1938,6 +1938,35 @@ struct item_variations_t
/* main algorithm ported from fonttools VarStore_optimize() method, optimize
* varstore by default */
struct combined_gain_idx_tuple_t
{
int gain;
unsigned idx_1;
unsigned idx_2;
combined_gain_idx_tuple_t () = default;
combined_gain_idx_tuple_t (int gain_, unsigned i, unsigned j)
:gain (gain_), idx_1 (i), idx_2 (j) {}
bool operator < (const combined_gain_idx_tuple_t& o)
{
if (gain != o.gain)
return gain < o.gain;
if (idx_1 != o.idx_1)
return idx_1 < o.idx_1;
return idx_2 < o.idx_2;
}
bool operator <= (const combined_gain_idx_tuple_t& o)
{
if (*this < o) return true;
return gain == o.gain && idx_1 == o.idx_1 && idx_2 == o.idx_2;
}
};
bool as_item_varstore (bool optimize=true, bool use_no_variation_idx=true)
{
if (!region_list) return false;
@ -2058,7 +2087,7 @@ struct item_variations_t
/* main algorithm: repeatedly pick 2 best encodings to combine, and combine
* them */
hb_priority_queue_t queue;
hb_priority_queue_t<combined_gain_idx_tuple_t> queue;
unsigned num_todos = encoding_objs.length;
for (unsigned i = 0; i < num_todos; i++)
{
@ -2066,19 +2095,16 @@ struct item_variations_t
{
int combining_gain = encoding_objs.arrayZ[i].gain_from_merging (encoding_objs.arrayZ[j]);
if (combining_gain > 0)
{
unsigned val = (i << 16) + j;
queue.insert (-combining_gain, val);
}
queue.insert (combined_gain_idx_tuple_t (-combining_gain, i, j), 0);
}
}
hb_set_t removed_todo_idxes;
while (queue)
{
unsigned val = queue.pop_minimum ().second;
unsigned j = val & 0xFFFF;
unsigned i = (val >> 16) & 0xFFFF;
auto t = queue.pop_minimum ().first;
unsigned i = t.idx_1;
unsigned j = t.idx_2;
if (removed_todo_idxes.has (i) || removed_todo_idxes.has (j))
continue;
@ -2119,10 +2145,7 @@ struct item_variations_t
int combined_gain = combined_encoding_obj.gain_from_merging (obj);
if (combined_gain > 0)
{
unsigned val = (idx << 16) + encoding_objs.length;
queue.insert (-combined_gain, val);
}
queue.insert (combined_gain_idx_tuple_t (-combined_gain, idx, encoding_objs.length), 0);
}
encoding_objs.push (std::move (combined_encoding_obj));

@ -42,10 +42,11 @@
* priority of its children. The heap is stored in an array, with the
* children of node i stored at indices 2i + 1 and 2i + 2.
*/
template <typename K>
struct hb_priority_queue_t
{
private:
typedef hb_pair_t<int64_t, unsigned> item_t;
typedef hb_pair_t<K, unsigned> item_t;
hb_vector_t<item_t> heap;
public:
@ -57,7 +58,7 @@ struct hb_priority_queue_t
#ifndef HB_OPTIMIZE_SIZE
HB_ALWAYS_INLINE
#endif
void insert (int64_t priority, unsigned value)
void insert (K priority, unsigned value)
{
heap.push (item_t (priority, value));
if (unlikely (heap.in_error ())) return;

@ -30,7 +30,7 @@
static void
test_insert ()
{
hb_priority_queue_t queue;
hb_priority_queue_t<int64_t> queue;
assert (queue.is_empty ());
queue.insert (10, 0);
@ -53,7 +53,7 @@ test_insert ()
static void
test_extract ()
{
hb_priority_queue_t queue;
hb_priority_queue_t<int32_t> queue;
queue.insert (0, 0);
queue.insert (60, 6);
queue.insert (30, 3);

Loading…
Cancel
Save