Merge "[adb] use zip iteration with functor" am: 26a8ed983c
Change-Id: I90aa462916891634b5406f0408aff02b0a3e97a5
diff --git a/adb/client/incremental_utils.cpp b/adb/client/incremental_utils.cpp
index caadb26..fa501e4 100644
--- a/adb/client/incremental_utils.cpp
+++ b/adb/client/incremental_utils.cpp
@@ -23,6 +23,7 @@
#include <ziparchive/zip_archive.h>
#include <ziparchive/zip_writer.h>
+#include <array>
#include <cinttypes>
#include <numeric>
#include <unordered_set>
@@ -30,6 +31,8 @@
#include "adb_trace.h"
#include "sysdeps.h"
+using namespace std::literals;
+
static constexpr int kBlockSize = 4096;
static constexpr inline int32_t offsetToBlockIndex(int64_t offset) {
@@ -217,16 +220,24 @@
return {zip, std::move(mapping)};
}
-// TODO(b/151676293): avoid using libziparchive as it reads local file headers
-// which causes additional performance cost. Instead, only read from central directory.
static std::vector<int32_t> InstallationPriorityBlocks(int fd, int64_t fileSize) {
+ static constexpr std::array<std::string_view, 3> additional_matches = {
+ "resources.arsc"sv, "AndroidManifest.xml"sv, "classes.dex"sv};
auto [zip, _] = openZipArchive(fd, fileSize);
if (!zip) {
return {};
}
+ auto matcher = [](std::string_view entry_name) {
+ if (entry_name.starts_with("lib/"sv) && entry_name.ends_with(".so"sv)) {
+ return true;
+ }
+ return std::any_of(additional_matches.begin(), additional_matches.end(),
+ [entry_name](std::string_view i) { return i == entry_name; });
+ };
+
void* cookie = nullptr;
- if (StartIteration(zip, &cookie) != 0) {
+ if (StartIteration(zip, &cookie, std::move(matcher)) != 0) {
D("%s failed at StartIteration: %d", __func__, errno);
return {};
}
@@ -235,8 +246,12 @@
ZipEntry entry;
std::string_view entryName;
while (Next(cookie, &entry, &entryName) == 0) {
- if (entryName == "resources.arsc" || entryName == "AndroidManifest.xml" ||
- entryName.starts_with("lib/")) {
+ if (entryName == "classes.dex"sv) {
+ // Only the head is needed for installation
+ int32_t startBlockIndex = offsetToBlockIndex(entry.offset);
+ appendBlocks(startBlockIndex, 1, &installationPriorityBlocks);
+ D("\tadding to priority blocks: '%.*s' 1", (int)entryName.size(), entryName.data());
+ } else {
// Full entries are needed for installation
off64_t entryStartOffset = entry.offset;
off64_t entryEndOffset =
@@ -248,11 +263,8 @@
int32_t endBlockIndex = offsetToBlockIndex(entryEndOffset);
int32_t numNewBlocks = endBlockIndex - startBlockIndex + 1;
appendBlocks(startBlockIndex, numNewBlocks, &installationPriorityBlocks);
- D("\tadding to priority blocks: '%.*s'", (int)entryName.size(), entryName.data());
- } else if (entryName == "classes.dex") {
- // Only the head is needed for installation
- int32_t startBlockIndex = offsetToBlockIndex(entry.offset);
- appendBlocks(startBlockIndex, 1, &installationPriorityBlocks);
+ D("\tadding to priority blocks: '%.*s' (%d)", (int)entryName.size(), entryName.data(),
+ numNewBlocks);
}
}