Skip to content

Commit d5f1339

Browse files
Jimmy Clearymeta-codesync[bot]
authored andcommitted
Replace vector-keyed std::map with UnorderedMap in DexOutput
Summary: Four deduplication maps in DexOutput (annotation_byte_offsets, aset_offsets, xref_offsets, adir_offsets) use `std::map<std::vector<T>, uint32_t>`. Tree-based maps compare vectors element-by-element at O(n) per comparison, giving O(n log m) lookup. Replaced with `UnorderedMap` using a custom `VectorHash` functor for O(1) amortized lookup. Reviewed By: xuhdev Differential Revision: D95755756 fbshipit-source-id: dae777d948bedcf56ba7dd3e620e8a420ca503d4
1 parent 2496c13 commit d5f1339

File tree

1 file changed

+21
-4
lines changed

1 file changed

+21
-4
lines changed

libredex/DexOutput.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,19 @@
6666

6767
namespace {
6868

69+
// Hash functor for std::vector<T> to enable use as keys in UnorderedMap.
70+
// Uses FNV-1a-inspired hash combining over the raw element values.
71+
template <typename T>
72+
struct VectorHash {
73+
size_t operator()(const std::vector<T>& v) const {
74+
size_t seed = v.size();
75+
for (const auto& elem : v) {
76+
seed ^= std::hash<T>{}(elem) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
77+
}
78+
return seed;
79+
}
80+
};
81+
6982
template <class T, class U>
7083
class CustomSort {
7184
private:
@@ -1135,7 +1148,8 @@ void DexOutput::unique_annotations(annomap_t& annomap,
11351148
std::vector<DexAnnotation*>& annolist) {
11361149
int annocnt = 0;
11371150
uint32_t mentry_offset = m_offset;
1138-
std::map<std::vector<uint8_t>, uint32_t> annotation_byte_offsets;
1151+
UnorderedMap<std::vector<uint8_t>, uint32_t, VectorHash<uint8_t>>
1152+
annotation_byte_offsets;
11391153
for (auto* anno : annolist) {
11401154
if (annomap.count(anno) != 0u) {
11411155
continue;
@@ -1167,7 +1181,8 @@ void DexOutput::unique_asets(annomap_t& annomap,
11671181
std::vector<DexAnnotationSet*>& asetlist) {
11681182
int asetcnt = 0;
11691183
uint32_t mentry_offset = align(m_offset);
1170-
std::map<std::vector<uint32_t>, uint32_t> aset_offsets;
1184+
UnorderedMap<std::vector<uint32_t>, uint32_t, VectorHash<uint32_t>>
1185+
aset_offsets;
11711186
for (auto* aset : asetlist) {
11721187
if (asetmap.count(aset) != 0u) {
11731188
continue;
@@ -1199,7 +1214,8 @@ void DexOutput::unique_xrefs(asetmap_t& asetmap,
11991214
std::vector<ParamAnnotations*>& xreflist) {
12001215
int xrefcnt = 0;
12011216
uint32_t mentry_offset = align(m_offset);
1202-
std::map<std::vector<uint32_t>, uint32_t> xref_offsets;
1217+
UnorderedMap<std::vector<uint32_t>, uint32_t, VectorHash<uint32_t>>
1218+
xref_offsets;
12031219
for (auto* xref : xreflist) {
12041220
if (xrefmap.count(xref) != 0u) {
12051221
continue;
@@ -1238,7 +1254,8 @@ void DexOutput::unique_adirs(asetmap_t& asetmap,
12381254
std::vector<DexAnnotationDirectory*>& adirlist) {
12391255
int adircnt = 0;
12401256
uint32_t mentry_offset = align(m_offset);
1241-
std::map<std::vector<uint32_t>, uint32_t> adir_offsets;
1257+
UnorderedMap<std::vector<uint32_t>, uint32_t, VectorHash<uint32_t>>
1258+
adir_offsets;
12421259
for (auto* adir : adirlist) {
12431260
if (adirmap.count(adir) != 0u) {
12441261
continue;

0 commit comments

Comments
 (0)