Skip to content

Commit edea8b6

Browse files
committed
Deduplicate identical AndroidBuild members in AndroidBuilds
This reduces re-calculating the same partition information for multiple builds. Bug: b/473893997
1 parent 3abdca5 commit edea8b6

File tree

6 files changed

+116
-30
lines changed

6 files changed

+116
-30
lines changed

base/cvd/cuttlefish/host/commands/assemble_cvd/android_build/BUILD.bazel

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ cf_cc_library(
2222
hdrs = ["android_builds.h"],
2323
deps = [
2424
"//cuttlefish/host/commands/assemble_cvd/android_build",
25+
"//cuttlefish/host/commands/assemble_cvd/android_build:identify_build",
2526
"//cuttlefish/result",
27+
"@abseil-cpp//absl/log:check",
2628
"@fmt",
2729
],
2830
)
@@ -124,6 +126,7 @@ cf_cc_library(
124126
"//cuttlefish/result",
125127
"//libbase",
126128
"@abseil-cpp//absl/strings",
129+
"@fmt",
127130
],
128131
)
129132

base/cvd/cuttlefish/host/commands/assemble_cvd/android_build/android_builds.cc

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,45 +22,66 @@
2222
#include <utility>
2323
#include <vector>
2424

25+
#include "absl/log/check.h"
26+
#include "fmt/ostream.h"
27+
#include "fmt/ranges.h"
28+
2529
#include "cuttlefish/host/commands/assemble_cvd/android_build/android_build.h"
30+
#include "cuttlefish/host/commands/assemble_cvd/android_build/identify_build.h"
2631
#include "cuttlefish/result/result.h"
2732

2833
namespace cuttlefish {
2934

30-
Result<AndroidBuilds> AndroidBuilds::Create(
31-
std::vector<std::unique_ptr<AndroidBuild>> providers) {
32-
CF_EXPECT(!providers.empty());
33-
for (const auto& provider : providers) {
34-
CF_EXPECT(provider.get());
35+
Result<AndroidBuilds> AndroidBuilds::Identify(
36+
std::vector<AndroidBuildKey> keys) {
37+
CF_EXPECT(!keys.empty());
38+
39+
std::map<AndroidBuildKey, std::unique_ptr<AndroidBuild>> builds_map;
40+
for (const AndroidBuildKey& key : keys) {
41+
if (builds_map.count(key) > 0) {
42+
continue;
43+
}
44+
std::unique_ptr<AndroidBuild> build = CF_EXPECT(IdentifyAndroidBuild(key));
45+
CF_EXPECT(build.get());
46+
builds_map[key] = std::move(build);
3547
}
36-
return AndroidBuilds(std::move(providers));
37-
}
3848

39-
AndroidBuilds::AndroidBuilds(
40-
std::vector<std::unique_ptr<AndroidBuild>> providers)
41-
: providers_(std::move(providers)) {}
49+
CF_EXPECT(!builds_map.empty());
50+
51+
AndroidBuilds builds;
52+
builds.keys_ = std::move(keys);
53+
builds.builds_ = std::move(builds_map);
54+
55+
return builds;
56+
}
4257

43-
AndroidBuild& AndroidBuilds::ForIndex(size_t index) {
58+
AndroidBuild& AndroidBuilds::ForIndex(const size_t index) {
4459
const AndroidBuilds& const_this = *this;
4560
return const_cast<AndroidBuild&>(const_this.ForIndex(index));
4661
}
4762

4863
const AndroidBuild& AndroidBuilds::ForIndex(size_t index) const {
49-
if (index < providers_.size()) {
50-
return *providers_[index];
51-
} else {
52-
return *providers_[0];
64+
if (index >= keys_.size()) {
65+
CHECK(!keys_.empty());
66+
index = 0;
5367
}
68+
const AndroidBuildKey& key = keys_[index];
69+
auto it = builds_.find(key);
70+
CHECK(it != builds_.end());
71+
CHECK(it->second.get() != nullptr);
72+
return *it->second;
5473
}
5574

56-
size_t AndroidBuilds::Size() const { return providers_.size(); }
75+
size_t AndroidBuilds::Size() const { return keys_.size(); }
5776

58-
std::ostream& operator<<(std::ostream& out, const AndroidBuilds& providers) {
59-
out << "AndroidBuilds {";
60-
for (const auto& provider : providers.providers_) {
61-
out << *provider << ", ";
77+
std::ostream& operator<<(std::ostream& out, const AndroidBuilds& builds) {
78+
fmt::print(out, "AndroidBuilds {{ .keys_ = [{}], .builds_= {{",
79+
fmt::join(builds.keys_, ", "));
80+
for (const auto& [key, value] : builds.builds_) {
81+
CHECK(value.get() != nullptr);
82+
fmt::print(out, "{} -> {}, ", key, *value);
6283
}
63-
return out << "}";
84+
return out << "}}";
6485
};
6586

6687
} // namespace cuttlefish

base/cvd/cuttlefish/host/commands/assemble_cvd/android_build/android_builds.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,19 @@
1515

1616
#pragma once
1717

18+
#include <map>
1819
#include <memory>
1920
#include <vector>
2021

2122
#include "cuttlefish/host/commands/assemble_cvd/android_build/android_build.h"
23+
#include "cuttlefish/host/commands/assemble_cvd/android_build/identify_build.h"
2224
#include "cuttlefish/result/result.h"
2325

2426
namespace cuttlefish {
2527

2628
class AndroidBuilds {
2729
public:
28-
static Result<AndroidBuilds> Create(
29-
std::vector<std::unique_ptr<AndroidBuild>>);
30+
static Result<AndroidBuilds> Identify(std::vector<AndroidBuildKey>);
3031

3132
AndroidBuild& ForIndex(size_t index);
3233
const AndroidBuild& ForIndex(size_t index) const;
@@ -36,9 +37,10 @@ class AndroidBuilds {
3637
friend std::ostream& operator<<(std::ostream&, const AndroidBuilds&);
3738

3839
private:
39-
AndroidBuilds(std::vector<std::unique_ptr<AndroidBuild>>);
40+
AndroidBuilds() = default;
4041

41-
std::vector<std::unique_ptr<AndroidBuild>> providers_;
42+
std::vector<AndroidBuildKey> keys_;
43+
std::map<AndroidBuildKey, std::unique_ptr<AndroidBuild>> builds_;
4244
};
4345

4446
} // namespace cuttlefish

base/cvd/cuttlefish/host/commands/assemble_cvd/android_build/identify_build.cc

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@
1717

1818
#include <memory>
1919
#include <string>
20-
#include <string_view>
2120
#include <utility>
2221
#include <vector>
2322

23+
#include "fmt/ostream.h"
24+
2425
#include "cuttlefish/host/commands/assemble_cvd/android_build/android_build.h"
2526
#include "cuttlefish/host/commands/assemble_cvd/android_build/android_dist_build.h"
2627
#include "cuttlefish/host/commands/assemble_cvd/android_build/android_product_dir.h"
@@ -34,6 +35,32 @@
3435

3536
namespace cuttlefish {
3637

38+
AndroidBuildKey::AndroidBuildKey(std::string system_image_dir,
39+
const FetcherConfig& fetcher_config,
40+
FileSource source)
41+
: system_image_dir(std::move(system_image_dir)),
42+
fetcher_config(&fetcher_config),
43+
source(source) {}
44+
45+
bool operator<(const AndroidBuildKey& left, const AndroidBuildKey& right) {
46+
if (left.system_image_dir != right.system_image_dir) {
47+
return left.system_image_dir < right.system_image_dir;
48+
}
49+
if (left.fetcher_config != right.fetcher_config) {
50+
return left.fetcher_config < right.fetcher_config;
51+
}
52+
return left.source < right.source;
53+
}
54+
55+
std::ostream& operator<<(std::ostream& out, const AndroidBuildKey& key) {
56+
fmt::print(out,
57+
"AndroidBuildKey {{ .system_image_dir = {}, .fetcher_config = {}, "
58+
".source = {} }}",
59+
key.system_image_dir, key.fetcher_config ? "(present)" : "(null)",
60+
key.source);
61+
return out;
62+
}
63+
3764
Result<std::unique_ptr<AndroidBuild>> IdentifyAndroidBuild(
3865
const std::string& system_image_dir, const FetcherConfig& config,
3966
FileSource source) {
@@ -67,4 +94,12 @@ Result<std::unique_ptr<AndroidBuild>> IdentifyAndroidBuild(
6794
return build;
6895
}
6996

97+
Result<std::unique_ptr<AndroidBuild>> IdentifyAndroidBuild(
98+
const AndroidBuildKey& android_build_key) {
99+
CF_EXPECT_NE(android_build_key.fetcher_config, nullptr);
100+
return CF_EXPECT(IdentifyAndroidBuild(android_build_key.system_image_dir,
101+
*android_build_key.fetcher_config,
102+
android_build_key.source));
103+
}
104+
70105
} // namespace cuttlefish

base/cvd/cuttlefish/host/commands/assemble_cvd/android_build/identify_build.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,39 @@
1818
#include <memory>
1919
#include <string>
2020

21+
#include "fmt/ostream.h"
22+
2123
#include "cuttlefish/host/commands/assemble_cvd/android_build/android_build.h"
2224
#include "cuttlefish/host/libs/config/fetcher_config.h"
2325
#include "cuttlefish/host/libs/config/file_source.h"
2426
#include "cuttlefish/result/result.h"
2527

2628
namespace cuttlefish {
2729

30+
struct AndroidBuildKey {
31+
explicit AndroidBuildKey(std::string, const FetcherConfig&, FileSource);
32+
33+
std::string system_image_dir;
34+
const FetcherConfig* fetcher_config;
35+
FileSource source;
36+
};
37+
38+
bool operator<(const AndroidBuildKey&, const AndroidBuildKey&);
39+
40+
std::ostream& operator<<(std::ostream&, const AndroidBuildKey&);
41+
2842
Result<std::unique_ptr<AndroidBuild>> IdentifyAndroidBuild(
2943
const std::string& system_image_dir, const FetcherConfig& config,
3044
FileSource source);
3145

46+
Result<std::unique_ptr<AndroidBuild>> IdentifyAndroidBuild(
47+
const AndroidBuildKey&);
48+
3249
} // namespace cuttlefish
50+
51+
namespace fmt {
52+
53+
template <>
54+
struct formatter<::cuttlefish::AndroidBuildKey> : ostream_formatter {};
55+
56+
} // namespace fmt

base/cvd/cuttlefish/host/commands/assemble_cvd/assemble_cvd.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -538,13 +538,14 @@ Result<AndroidBuilds> FindAndroidBuilds(
538538
CF_EXPECT_EQ(system_image_dir.Size(), fetcher_configs.Size());
539539
std::vector<std::unique_ptr<AndroidBuild>> android_builds;
540540

541+
std::vector<AndroidBuildKey> keys;
541542
for (size_t i = 0; i < system_image_dir.Size(); i++) {
542-
android_builds.emplace_back(CF_EXPECT(IdentifyAndroidBuild(
543-
system_image_dir.ForIndex(i), fetcher_configs.ForInstance(i),
544-
FileSource::DEFAULT_BUILD)));
543+
keys.emplace_back(system_image_dir.ForIndex(i),
544+
fetcher_configs.ForInstance(i),
545+
FileSource::DEFAULT_BUILD);
545546
}
546547

547-
return CF_EXPECT(AndroidBuilds::Create(std::move(android_builds)));
548+
return CF_EXPECT(AndroidBuilds::Identify(std::move(keys)));
548549
}
549550

550551
} // namespace

0 commit comments

Comments
 (0)