Skip to content

Commit

Permalink
Make dependency map available via public getter
Browse files Browse the repository at this point in the history
Dependency map can be used for visualizing the graph

Test: th
Bug: 289236484
Change-Id: Ifa23187f96c3f228f7009f6ccd9b0253d9f8f5f4
  • Loading branch information
zhangxp1998 committed Jun 29, 2023
1 parent 709123b commit 6c89c66
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 21 deletions.
26 changes: 10 additions & 16 deletions payload_generator/merge_sequence_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -196,20 +196,20 @@ std::unique_ptr<MergeSequenceGenerator> MergeSequenceGenerator::Create(
new MergeSequenceGenerator(sequence, partition_name));
}

bool MergeSequenceGenerator::FindDependency(
std::map<CowMergeOperation, std::set<CowMergeOperation>>* result) const {
CHECK(result);
std::map<CowMergeOperation, std::set<CowMergeOperation>>
MergeSequenceGenerator::FindDependency(
const std::vector<CowMergeOperation>& operations) {
LOG(INFO) << "Finding dependencies";

// Since the OTA operation may reuse some source blocks, use the binary
// search on sorted dst extents to find overlaps.
std::map<CowMergeOperation, std::set<CowMergeOperation>> merge_after;
for (const auto& op : operations_) {
for (const auto& op : operations) {
// lower bound (inclusive): dst extent's end block >= src extent's start
// block.
const auto lower_it = std::lower_bound(
operations_.begin(),
operations_.end(),
operations.begin(),
operations.end(),
op,
[](const CowMergeOperation& it, const CowMergeOperation& op) {
auto dst_end_block =
Expand All @@ -219,7 +219,7 @@ bool MergeSequenceGenerator::FindDependency(
// upper bound: dst extent's start block > src extent's end block
const auto upper_it = std::upper_bound(
lower_it,
operations_.end(),
operations.end(),
op,
[](const CowMergeOperation& op, const CowMergeOperation& it) {
auto src_end_block =
Expand All @@ -243,26 +243,20 @@ bool MergeSequenceGenerator::FindDependency(
}
}

*result = std::move(merge_after);
return true;
return merge_after;
}

bool MergeSequenceGenerator::Generate(
std::vector<CowMergeOperation>* sequence) const {
sequence->clear();
std::map<CowMergeOperation, std::set<CowMergeOperation>> merge_after;
if (!FindDependency(&merge_after)) {
LOG(ERROR) << "Failed to find dependencies";
return false;
}

LOG(INFO) << "Generating sequence";

// Use the non-DFS version of the topology sort. So we can control the
// operations to discard to break cycles; thus yielding a deterministic
// sequence.
std::map<CowMergeOperation, int> incoming_edges;
for (const auto& it : merge_after) {
for (const auto& it : merge_after_) {
for (const auto& blocked : it.second) {
// Value is default initialized to 0.
incoming_edges[blocked] += 1;
Expand Down Expand Up @@ -301,7 +295,7 @@ bool MergeSequenceGenerator::Generate(
// Now that this particular operation is merged, other operations
// blocked by this one may be free. Decrement the count of blocking
// operations, and set up the free operations for the next iteration.
for (const auto& blocked : merge_after[op]) {
for (const auto& blocked : merge_after_.at(op)) {
auto it = incoming_edges.find(blocked);
if (it == incoming_edges.end()) {
continue;
Expand Down
16 changes: 13 additions & 3 deletions payload_generator/merge_sequence_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class MergeSequenceGenerator {
explicit MergeSequenceGenerator(std::vector<CowMergeOperation> transfers,
std::string_view partition_name)
: operations_(std::move(Sort(transfers))),
merge_after_(FindDependency(operations_)),
partition_name_(partition_name) {}
// Checks that no read after write happens in the given sequence.
static bool ValidateSequence(const std::vector<CowMergeOperation>& sequence);
Expand All @@ -69,15 +70,24 @@ class MergeSequenceGenerator {
// |sequence|. Returns false on failure.
bool Generate(std::vector<CowMergeOperation>* sequence) const;

const std::vector<CowMergeOperation>& GetOperations() const {
return operations_;
}
const std::map<CowMergeOperation, std::set<CowMergeOperation>>&
GetDependencyMap() const {
return merge_after_;
}

private:
friend class MergeSequenceGeneratorTest;

// For a given merge operation, finds all the operations that should merge
// after myself. Put the result in |merge_after|.
bool FindDependency(std::map<CowMergeOperation, std::set<CowMergeOperation>>*
merge_after) const;
// after myself. Put the result in |merge_after|. |operations| must be sorted
static std::map<CowMergeOperation, std::set<CowMergeOperation>>
FindDependency(const std::vector<CowMergeOperation>& operations);
// The list of CowMergeOperations to sort.
const std::vector<CowMergeOperation> operations_;
const std::map<CowMergeOperation, std::set<CowMergeOperation>> merge_after_;
const std::string_view partition_name_;
};

Expand Down
3 changes: 1 addition & 2 deletions payload_generator/merge_sequence_generator_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ class MergeSequenceGeneratorTest : public ::testing::Test {
std::vector<CowMergeOperation> transfers,
std::map<CowMergeOperation, std::set<CowMergeOperation>>* result) {
std::sort(transfers.begin(), transfers.end());
MergeSequenceGenerator generator(std::move(transfers), "");
ASSERT_TRUE(generator.FindDependency(result));
*result = MergeSequenceGenerator::FindDependency(transfers);
}

void GenerateSequence(std::vector<CowMergeOperation> transfers) {
Expand Down

0 comments on commit 6c89c66

Please sign in to comment.