[subset] use vectors instead of hashmaps throughout the repacker since all keys will be mapped for these use cases.

This commit is contained in:
Garret Rieger 2020-11-05 14:23:29 -08:00
parent 519ae96617
commit 8286bd8094
1 changed files with 31 additions and 34 deletions

View File

@ -110,8 +110,9 @@ struct graph_t
hb_vector_t<unsigned> queue; hb_vector_t<unsigned> queue;
hb_vector_t<hb_serialize_context_t::object_t> sorted_graph; hb_vector_t<hb_serialize_context_t::object_t> sorted_graph;
hb_map_t id_map; hb_vector_t<unsigned> id_map;
hb_map_t edge_count; id_map.resize (objects_.length);
hb_vector_t<unsigned> edge_count;
incoming_edge_count (&edge_count); incoming_edge_count (&edge_count);
// Object graphs are in reverse order, the first object is at the end // Object graphs are in reverse order, the first object is at the end
@ -127,12 +128,12 @@ struct graph_t
hb_serialize_context_t::object_t& next = objects_[next_id]; hb_serialize_context_t::object_t& next = objects_[next_id];
sorted_graph.push (next); sorted_graph.push (next);
id_map.set (next_id, new_id--); id_map[next_id] = new_id--;
for (const auto& link : next.links) { for (const auto& link : next.links) {
// TODO(garretrieger): sort children from smallest to largest // TODO(garretrieger): sort children from smallest to largest
edge_count.set (link.objidx, edge_count.get (link.objidx) - 1); edge_count[link.objidx] -= 1;
if (!edge_count.get (link.objidx)) if (!edge_count[link.objidx])
queue.push (link.objidx); queue.push (link.objidx);
} }
} }
@ -167,8 +168,9 @@ struct graph_t
hb_priority_queue_t queue; hb_priority_queue_t queue;
hb_vector_t<hb_serialize_context_t::object_t> sorted_graph; hb_vector_t<hb_serialize_context_t::object_t> sorted_graph;
hb_map_t id_map; hb_vector_t<unsigned> id_map;
hb_map_t edge_count; id_map.resize (objects_.length);
hb_vector_t<unsigned> edge_count;
incoming_edge_count (&edge_count); incoming_edge_count (&edge_count);
// Object graphs are in reverse order, the first object is at the end // Object graphs are in reverse order, the first object is at the end
@ -183,11 +185,11 @@ struct graph_t
hb_serialize_context_t::object_t& next = objects_[next_id]; hb_serialize_context_t::object_t& next = objects_[next_id];
sorted_graph.push (next); sorted_graph.push (next);
id_map.set (next_id, new_id--); id_map[next_id] = new_id--;
for (const auto& link : next.links) { for (const auto& link : next.links) {
edge_count.set (link.objidx, edge_count.get (link.objidx) - 1); edge_count[link.objidx] -= 1;
if (!edge_count.get (link.objidx)) if (!edge_count[link.objidx])
// Add the order that the links were encountered to the priority. // Add the order that the links were encountered to the priority.
// This ensures that ties between priorities objects are broken in a consistent // This ensures that ties between priorities objects are broken in a consistent
// 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
@ -216,15 +218,17 @@ struct graph_t
*/ */
bool will_overflow () bool will_overflow ()
{ {
hb_map_t start_positions; hb_vector_t<unsigned> start_positions;
hb_map_t end_positions; start_positions.resize (objects_.length);
hb_vector_t<unsigned> end_positions;
end_positions.resize (objects_.length);
unsigned current_pos = 0; unsigned current_pos = 0;
for (int i = objects_.length - 1; i >= 0; i--) for (int i = objects_.length - 1; i >= 0; i--)
{ {
start_positions.set (i, current_pos); start_positions[i] = current_pos;
current_pos += objects_[i].tail - objects_[i].head; current_pos += objects_[i].tail - objects_[i].head;
end_positions.set (i, current_pos); end_positions[i] = current_pos;
} }
@ -267,7 +271,6 @@ struct graph_t
// According to https://www3.cs.stonybrook.edu/~rezaul/papers/TR-07-54.pdf // According to https://www3.cs.stonybrook.edu/~rezaul/papers/TR-07-54.pdf
// for practical performance this is faster then using a more advanced queue // for practical performance this is faster then using a more advanced queue
// (such as a fibonaacci queue) with a fast decrease priority. // (such as a fibonaacci queue) with a fast decrease priority.
hb_priority_queue_t queue;
distance_to->resize (0); distance_to->resize (0);
distance_to->resize (objects_.length); distance_to->resize (objects_.length);
for (unsigned i = 0; i < objects_.length; i++) for (unsigned i = 0; i < objects_.length; i++)
@ -276,9 +279,11 @@ struct graph_t
(*distance_to)[i] = 0; (*distance_to)[i] = 0;
else else
(*distance_to)[i] = hb_int_max (int64_t); (*distance_to)[i] = hb_int_max (int64_t);
queue.insert (i, (*distance_to)[i]);
} }
hb_priority_queue_t queue;
queue.insert (objects_.length - 1, 0);
hb_set_t visited; hb_set_t visited;
while (!queue.is_empty ()) while (!queue.is_empty ())
@ -312,8 +317,8 @@ struct graph_t
int64_t compute_offset ( int64_t compute_offset (
unsigned parent_idx, unsigned parent_idx,
const hb_serialize_context_t::object_t::link_t& link, const hb_serialize_context_t::object_t::link_t& link,
const hb_map_t& start_positions, const hb_vector_t<unsigned>& start_positions,
const hb_map_t& end_positions) const hb_vector_t<unsigned>& end_positions)
{ {
unsigned child_idx = link.objidx; unsigned child_idx = link.objidx;
int64_t offset = 0; int64_t offset = 0;
@ -353,7 +358,7 @@ struct graph_t
/* /*
* Updates all objidx's in all links using the provided mapping. * Updates all objidx's in all links using the provided mapping.
*/ */
void remap_obj_indices (const hb_map_t& id_map, void remap_obj_indices (const hb_vector_t<unsigned>& id_map,
hb_vector_t<hb_serialize_context_t::object_t>* sorted_graph) hb_vector_t<hb_serialize_context_t::object_t>* sorted_graph)
{ {
for (unsigned i = 0; i < sorted_graph->length; i++) for (unsigned i = 0; i < sorted_graph->length; i++)
@ -361,10 +366,7 @@ struct graph_t
for (unsigned j = 0; j < (*sorted_graph)[i].links.length; j++) for (unsigned j = 0; j < (*sorted_graph)[i].links.length; j++)
{ {
auto& link = (*sorted_graph)[i].links[j]; auto& link = (*sorted_graph)[i].links[j];
if (!id_map.has (link.objidx)) link.objidx = id_map[link.objidx];
// TODO(garretrieger): handle this.
assert (false);
link.objidx = id_map.get (link.objidx);
} }
} }
} }
@ -372,20 +374,15 @@ struct graph_t
/* /*
* Creates a map from objid to # of incoming edges. * Creates a map from objid to # of incoming edges.
*/ */
void incoming_edge_count (hb_map_t* out) void incoming_edge_count (hb_vector_t<unsigned>* out)
{ {
for (unsigned i = 0; i < objects_.length; i++) out->resize (0);
out->resize (objects_.length);
for (const auto& o : objects_)
{ {
if (!out->has (i)) for (const auto& l : o.links)
out->set (i, 0);
for (const auto& l : objects_[i].links)
{ {
unsigned id = l.objidx; (*out)[l.objidx] += 1;
if (out->has (id))
out->set (id, out->get (id) + 1);
else
out->set (id, 1);
} }
} }
} }