Commit 54606dc9 authored by Patrick Monette's avatar Patrick Monette Committed by Commit Bot

[PM] Migrate OverrideVoteAggregator to VoteObserver

Bug: 971272
Change-Id: I35e1dc341bbf62b1639e03620ed549f2effd4678
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2530239
Commit-Queue: Patrick Monette <pmonette@chromium.org>
Reviewed-by: default avatarChris Hamilton <chrisha@chromium.org>
Cr-Commit-Position: refs/heads/master@{#828051}
parent f0d69036
...@@ -7,15 +7,16 @@ ...@@ -7,15 +7,16 @@
namespace performance_manager { namespace performance_manager {
namespace execution_context_priority { namespace execution_context_priority {
OverrideVoteAggregator::OverrideVoteAggregator() : factory_(this) {} OverrideVoteAggregator::OverrideVoteAggregator()
: vote_consumer_default_impl_(this) {}
OverrideVoteAggregator::~OverrideVoteAggregator() = default; OverrideVoteAggregator::~OverrideVoteAggregator() = default;
VotingChannel OverrideVoteAggregator::GetOverrideVotingChannel() { VotingChannel OverrideVoteAggregator::GetOverrideVotingChannel() {
DCHECK(vote_data_map_.empty()); DCHECK(vote_data_map_.empty());
DCHECK_EQ(voting::kInvalidVoterId<Vote>, override_voter_id_); DCHECK_EQ(voting::kInvalidVoterId<Vote>, override_voter_id_);
DCHECK_GT(2u, factory_.voting_channels_issued()); DCHECK_GT(2u, vote_consumer_default_impl_.voting_channels_issued());
auto channel = factory_.BuildVotingChannel(); auto channel = vote_consumer_default_impl_.BuildVotingChannel();
override_voter_id_ = channel.voter_id(); override_voter_id_ = channel.voter_id();
return channel; return channel;
} }
...@@ -23,8 +24,8 @@ VotingChannel OverrideVoteAggregator::GetOverrideVotingChannel() { ...@@ -23,8 +24,8 @@ VotingChannel OverrideVoteAggregator::GetOverrideVotingChannel() {
VotingChannel OverrideVoteAggregator::GetDefaultVotingChannel() { VotingChannel OverrideVoteAggregator::GetDefaultVotingChannel() {
DCHECK(vote_data_map_.empty()); DCHECK(vote_data_map_.empty());
DCHECK_EQ(voting::kInvalidVoterId<Vote>, default_voter_id_); DCHECK_EQ(voting::kInvalidVoterId<Vote>, default_voter_id_);
DCHECK_GT(2u, factory_.voting_channels_issued()); DCHECK_GT(2u, vote_consumer_default_impl_.voting_channels_issued());
auto channel = factory_.BuildVotingChannel(); auto channel = vote_consumer_default_impl_.BuildVotingChannel();
default_voter_id_ = channel.voter_id(); default_voter_id_ = channel.voter_id();
return channel; return channel;
} }
...@@ -42,70 +43,73 @@ bool OverrideVoteAggregator::IsSetup() const { ...@@ -42,70 +43,73 @@ bool OverrideVoteAggregator::IsSetup() const {
channel_.IsValid(); channel_.IsValid();
} }
VoteReceipt OverrideVoteAggregator::SubmitVote( void OverrideVoteAggregator::OnVoteSubmitted(
util::PassKey<VotingChannel>, VoterId voter_id,
voting::VoterId<Vote> voter_id,
const ExecutionContext* execution_context, const ExecutionContext* execution_context,
const Vote& vote) { const Vote& vote) {
DCHECK(vote.IsValid());
DCHECK(IsSetup()); DCHECK(IsSetup());
VoteData& vote_data = vote_data_map_[execution_context]; VoteData& vote_data = vote_data_map_[execution_context];
if (voter_id == override_voter_id_) { if (voter_id == override_voter_id_) {
DCHECK(!vote_data.override_vote.IsValid()); DCHECK(!vote_data.override_vote.has_value());
vote_data.override_vote =
AcceptedVote(this, voter_id, execution_context, vote); vote_data.override_vote = vote;
UpstreamVote(execution_context, vote, &vote_data); UpstreamVote(execution_context, vote, &vote_data);
return vote_data.override_vote.IssueReceipt();
} else { } else {
DCHECK_EQ(default_voter_id_, voter_id); DCHECK_EQ(default_voter_id_, voter_id);
DCHECK(!vote_data.default_vote.IsValid()); DCHECK(!vote_data.default_vote.has_value());
vote_data.default_vote =
AcceptedVote(this, voter_id, execution_context, vote); vote_data.default_vote = vote;
if (!vote_data.override_vote.IsValid())
if (!vote_data.override_vote.has_value())
UpstreamVote(execution_context, vote, &vote_data); UpstreamVote(execution_context, vote, &vote_data);
return vote_data.default_vote.IssueReceipt();
} }
} }
void OverrideVoteAggregator::ChangeVote(util::PassKey<AcceptedVote>, void OverrideVoteAggregator::OnVoteChanged(
AcceptedVote* old_vote, VoterId voter_id,
const Vote& new_vote) { const ExecutionContext* execution_context,
DCHECK(old_vote->IsValid()); const Vote& new_vote) {
VoteData& vote_data = GetVoteData(old_vote)->second; VoteData& vote_data = GetVoteData(execution_context)->second;
if (voter_id == override_voter_id_) {
// Update the vote in place. DCHECK(vote_data.override_vote.has_value());
old_vote->UpdateVote(new_vote); vote_data.override_vote = new_vote;
// The vote being changed is the upstream vote if: UpstreamVote(execution_context, new_vote, &vote_data);
// (1) It is the override vote, or } else {
// (2) There is no override vote. DCHECK_EQ(default_voter_id_, voter_id);
if (old_vote == &vote_data.override_vote || DCHECK(vote_data.default_vote.has_value());
!vote_data.override_vote.IsValid()) { vote_data.default_vote = new_vote;
UpstreamVote(old_vote->context(), new_vote, &vote_data);
if (!vote_data.override_vote.has_value())
UpstreamVote(execution_context, new_vote, &vote_data);
} }
} }
void OverrideVoteAggregator::VoteInvalidated(util::PassKey<AcceptedVote>, void OverrideVoteAggregator::OnVoteInvalidated(
AcceptedVote* vote) { VoterId voter_id,
DCHECK(!vote->IsValid()); const ExecutionContext* execution_context) {
auto it = GetVoteData(vote); auto it = GetVoteData(execution_context);
VoteData& vote_data = it->second; VoteData& vote_data = it->second;
// Figure out which is the "other" vote in this case. // Figure out which is the "other" vote in this case.
bool is_override_vote = false; bool is_override_vote = voter_id == override_voter_id_;
AcceptedVote* other = nullptr; base::Optional<Vote>* other_vote = nullptr;
if (vote == &vote_data.override_vote) { if (is_override_vote) {
is_override_vote = true; DCHECK(vote_data.override_vote.has_value());
other = &vote_data.default_vote; vote_data.override_vote = base::nullopt;
other_vote = &vote_data.default_vote;
} else { } else {
DCHECK_EQ(&vote_data.default_vote, vote); DCHECK_EQ(default_voter_id_, voter_id);
other = &vote_data.override_vote; DCHECK(vote_data.default_vote.has_value());
vote_data.default_vote = base::nullopt;
other_vote = &vote_data.override_vote;
} }
// If the other vote is invalid the whole entry is being erased, which will // If there is no other vote, erase the whole entry. This will cancel the
// cancel the upstream vote as well. // upstream vote as well.
if (!other->IsValid()) { if (!other_vote->has_value()) {
vote_data_map_.erase(it); vote_data_map_.erase(it);
return; return;
} }
...@@ -116,7 +120,7 @@ void OverrideVoteAggregator::VoteInvalidated(util::PassKey<AcceptedVote>, ...@@ -116,7 +120,7 @@ void OverrideVoteAggregator::VoteInvalidated(util::PassKey<AcceptedVote>,
// being invalidated, and the default is valid. In this case we need to // being invalidated, and the default is valid. In this case we need to
// upstream a new vote. // upstream a new vote.
if (is_override_vote) if (is_override_vote)
UpstreamVote(other->context(), other->vote(), &vote_data); UpstreamVote(execution_context, other_vote->value(), &vote_data);
} }
OverrideVoteAggregator::VoteData::VoteData() = default; OverrideVoteAggregator::VoteData::VoteData() = default;
...@@ -124,16 +128,8 @@ OverrideVoteAggregator::VoteData::VoteData(VoteData&& rhs) = default; ...@@ -124,16 +128,8 @@ OverrideVoteAggregator::VoteData::VoteData(VoteData&& rhs) = default;
OverrideVoteAggregator::VoteData::~VoteData() = default; OverrideVoteAggregator::VoteData::~VoteData() = default;
OverrideVoteAggregator::VoteDataMap::iterator OverrideVoteAggregator::VoteDataMap::iterator
OverrideVoteAggregator::GetVoteData(AcceptedVote* vote) { OverrideVoteAggregator::GetVoteData(const ExecutionContext* execution_context) {
// The vote being retrieved should have us as its consumer, and have been auto it = vote_data_map_.find(execution_context);
// emitted by one of our known voters.
DCHECK(vote);
DCHECK_EQ(this, vote->consumer());
DCHECK(vote->voter_id() == override_voter_id_ ||
vote->voter_id() == default_voter_id_);
DCHECK(IsSetup());
auto it = vote_data_map_.find(vote->context());
DCHECK(it != vote_data_map_.end()); DCHECK(it != vote_data_map_.end());
return it; return it;
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <map> #include <map>
#include "base/optional.h"
#include "components/performance_manager/public/execution_context_priority/execution_context_priority.h" #include "components/performance_manager/public/execution_context_priority/execution_context_priority.h"
namespace performance_manager { namespace performance_manager {
...@@ -15,11 +16,14 @@ namespace execution_context_priority { ...@@ -15,11 +16,14 @@ namespace execution_context_priority {
// Aggregator that allows votes from 2 different Voters, where one of the voters // Aggregator that allows votes from 2 different Voters, where one of the voters
// is allowed to override the votes of another. This aggregator should be // is allowed to override the votes of another. This aggregator should be
// completely setup before any votes are submitted to it. // completely setup before any votes are submitted to it.
class OverrideVoteAggregator : public VoteConsumer { class OverrideVoteAggregator : public VoteObserver {
public: public:
OverrideVoteAggregator(); OverrideVoteAggregator();
~OverrideVoteAggregator() override; ~OverrideVoteAggregator() override;
OverrideVoteAggregator(const OverrideVoteAggregator&) = delete;
OverrideVoteAggregator& operator=(const OverrideVoteAggregator&) = delete;
// All 3 of these must have been called in order for the aggregator to be // All 3 of these must have been called in order for the aggregator to be
// fully setup. // fully setup.
VotingChannel GetOverrideVotingChannel(); VotingChannel GetOverrideVotingChannel();
...@@ -31,16 +35,15 @@ class OverrideVoteAggregator : public VoteConsumer { ...@@ -31,16 +35,15 @@ class OverrideVoteAggregator : public VoteConsumer {
size_t GetSizeForTesting() const { return vote_data_map_.size(); } size_t GetSizeForTesting() const { return vote_data_map_.size(); }
protected: protected:
// VoteConsumer implementation: // VoteObserver implementation:
VoteReceipt SubmitVote(util::PassKey<VotingChannel>, void OnVoteSubmitted(VoterId voter_id,
voting::VoterId<Vote> voter_id, const ExecutionContext* execution_context,
const ExecutionContext* execution_context, const Vote& vote) override;
const Vote& vote) override; void OnVoteChanged(VoterId voter_id,
void ChangeVote(util::PassKey<AcceptedVote>, const ExecutionContext* execution_context,
AcceptedVote* old_vote, const Vote& new_vote) override;
const Vote& new_vote) override; void OnVoteInvalidated(VoterId voter_id,
void VoteInvalidated(util::PassKey<AcceptedVote>, const ExecutionContext* execution_context) override;
AcceptedVote* vote) override;
private: private:
// This is move-only because all of its members are move-only. // This is move-only because all of its members are move-only.
...@@ -52,11 +55,11 @@ class OverrideVoteAggregator : public VoteConsumer { ...@@ -52,11 +55,11 @@ class OverrideVoteAggregator : public VoteConsumer {
VoteData& operator=(VoteData&& rhs) = default; VoteData& operator=(VoteData&& rhs) = default;
~VoteData(); ~VoteData();
// Each of these IsValid if a vote has been emitted for this execution // Each of these is not null if a vote has been emitted for this execution
// context, otherwise !IsValid. At least one of the votes must be valid, // context. At least one of the votes must exist, otherwise the entire map
// otherwise the entire map entry will be destroyed. // entry will be destroyed.
AcceptedVote override_vote; base::Optional<Vote> override_vote;
AcceptedVote default_vote; base::Optional<Vote> default_vote;
// The receipt for the vote we've upstreamed. // The receipt for the vote we've upstreamed.
VoteReceipt receipt; VoteReceipt receipt;
...@@ -66,7 +69,7 @@ class OverrideVoteAggregator : public VoteConsumer { ...@@ -66,7 +69,7 @@ class OverrideVoteAggregator : public VoteConsumer {
// Looks up the VoteData associated with the provided |vote|. The data is // Looks up the VoteData associated with the provided |vote|. The data is
// expected to already exist (enforced by a DCHECK). // expected to already exist (enforced by a DCHECK).
VoteDataMap::iterator GetVoteData(AcceptedVote* vote); VoteDataMap::iterator GetVoteData(const ExecutionContext* execution_context);
// Rebrands |vote| as belonging to this voter, and then sends it along to our // Rebrands |vote| as belonging to this voter, and then sends it along to our
// |consumer_|. Stores the resulting receipt in |vote_data|. // |consumer_|. Stores the resulting receipt in |vote_data|.
...@@ -76,19 +79,17 @@ class OverrideVoteAggregator : public VoteConsumer { ...@@ -76,19 +79,17 @@ class OverrideVoteAggregator : public VoteConsumer {
// Our two input voters. We'll only accept votes from these voters otherwise // Our two input voters. We'll only accept votes from these voters otherwise
// we'll DCHECK. // we'll DCHECK.
voting::VoterId<Vote> override_voter_id_ = voting::kInvalidVoterId<Vote>; VoterId override_voter_id_ = voting::kInvalidVoterId<Vote>;
voting::VoterId<Vote> default_voter_id_ = voting::kInvalidVoterId<Vote>; VoterId default_voter_id_ = voting::kInvalidVoterId<Vote>;
// Our channel for upstreaming our votes. // Our channel for upstreaming our votes.
VotingChannel channel_; VotingChannel channel_;
// Our VotingChannelFactory for providing VotingChannels to our input voters. // Provides VotingChannels to our input voters.
VotingChannelFactory factory_; VoteConsumerDefaultImpl vote_consumer_default_impl_;
// The votes we've upstreamed to our consumer. // The votes we've upstreamed to our consumer.
VoteDataMap vote_data_map_; VoteDataMap vote_data_map_;
DISALLOW_COPY_AND_ASSIGN(OverrideVoteAggregator);
}; };
} // namespace execution_context_priority } // namespace execution_context_priority
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment