override_vote_aggregator.cc 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/performance_manager/execution_context_priority/override_vote_aggregator.h"
  5. namespace performance_manager {
  6. namespace execution_context_priority {
  7. OverrideVoteAggregator::OverrideVoteAggregator() = default;
  8. OverrideVoteAggregator::~OverrideVoteAggregator() = default;
  9. VotingChannel OverrideVoteAggregator::GetOverrideVotingChannel() {
  10. DCHECK(vote_data_map_.empty());
  11. DCHECK(!override_voter_id_);
  12. DCHECK_GT(2u, voting_channel_factory_.voting_channels_issued());
  13. auto channel = voting_channel_factory_.BuildVotingChannel();
  14. override_voter_id_ = channel.voter_id();
  15. return channel;
  16. }
  17. VotingChannel OverrideVoteAggregator::GetDefaultVotingChannel() {
  18. DCHECK(vote_data_map_.empty());
  19. DCHECK(!default_voter_id_);
  20. DCHECK_GT(2u, voting_channel_factory_.voting_channels_issued());
  21. auto channel = voting_channel_factory_.BuildVotingChannel();
  22. default_voter_id_ = channel.voter_id();
  23. return channel;
  24. }
  25. void OverrideVoteAggregator::SetUpstreamVotingChannel(VotingChannel channel) {
  26. channel_ = std::move(channel);
  27. }
  28. bool OverrideVoteAggregator::IsSetup() const {
  29. return override_voter_id_ && default_voter_id_ && channel_.IsValid();
  30. }
  31. void OverrideVoteAggregator::OnVoteSubmitted(
  32. VoterId voter_id,
  33. const ExecutionContext* execution_context,
  34. const Vote& vote) {
  35. DCHECK(IsSetup());
  36. // Create the VoteData for this execution context, if necessary.
  37. VoteData& vote_data = vote_data_map_[execution_context];
  38. // Remember the previous chosen vote before adding the new vote. There could
  39. // be none if the this the first vote submitted for |execution_context|.
  40. absl::optional<Vote> old_chosen_vote;
  41. if (vote_data.HasChosenVote())
  42. old_chosen_vote = vote_data.GetChosenVote();
  43. vote_data.AddVote(GetVoterType(voter_id), vote);
  44. // If there was no previous chosen vote, the vote must be submitted.
  45. if (!old_chosen_vote) {
  46. channel_.SubmitVote(execution_context, vote);
  47. return;
  48. }
  49. // Since there is a previous chosen vote, it must be modified if the chosen
  50. // vote changed.
  51. const Vote new_chosen_vote = vote_data.GetChosenVote();
  52. if (old_chosen_vote.value() != new_chosen_vote)
  53. channel_.ChangeVote(execution_context, new_chosen_vote);
  54. }
  55. void OverrideVoteAggregator::OnVoteChanged(
  56. VoterId voter_id,
  57. const ExecutionContext* execution_context,
  58. const Vote& new_vote) {
  59. // The VoteData for this execution context is guaranteed to exist.
  60. VoteData& vote_data = GetVoteData(execution_context)->second;
  61. // Remember the previous chosen vote before updating the vote for this
  62. // |voter_id|.
  63. const Vote old_chosen_vote = vote_data.GetChosenVote();
  64. vote_data.ChangeVote(GetVoterType(voter_id), new_vote);
  65. // If the chosen vote changed, the upstream vote must also be changed.
  66. const Vote new_chosen_vote = vote_data.GetChosenVote();
  67. if (old_chosen_vote != new_chosen_vote)
  68. channel_.ChangeVote(execution_context, new_chosen_vote);
  69. }
  70. void OverrideVoteAggregator::OnVoteInvalidated(
  71. VoterId voter_id,
  72. const ExecutionContext* execution_context) {
  73. // The VoteData for this execution context is guaranteed to exist.
  74. auto it = GetVoteData(execution_context);
  75. VoteData& vote_data = it->second;
  76. // Remember the previous chosen vote before removing the vote for this
  77. // |voter_id|.
  78. const Vote old_chosen_vote = vote_data.GetChosenVote();
  79. vote_data.RemoveVote(GetVoterType(voter_id));
  80. // In case the last vote for |execution_context| was invalidated, the upstream
  81. // vote must also be invalidated.
  82. if (!vote_data.HasChosenVote()) {
  83. channel_.InvalidateVote(execution_context);
  84. // Clean up the VoteData for |execution_context| since it is empty.
  85. vote_data_map_.erase(it);
  86. return;
  87. }
  88. // If the top vote changed, the upstream vote must also be changed.
  89. const Vote new_chosen_vote = vote_data.GetChosenVote();
  90. if (old_chosen_vote != new_chosen_vote)
  91. channel_.ChangeVote(execution_context, new_chosen_vote);
  92. }
  93. OverrideVoteAggregator::VoteData::VoteData() = default;
  94. OverrideVoteAggregator::VoteData::VoteData(VoteData&& rhs) = default;
  95. OverrideVoteAggregator::VoteData::~VoteData() = default;
  96. void OverrideVoteAggregator::VoteData::AddVote(VoterType voter_type,
  97. const Vote& vote) {
  98. switch (voter_type) {
  99. case VoterType::kDefault:
  100. DCHECK(!default_vote_.has_value());
  101. default_vote_ = vote;
  102. break;
  103. case VoterType::kOverride:
  104. DCHECK(!override_vote_.has_value());
  105. override_vote_ = vote;
  106. break;
  107. }
  108. }
  109. void OverrideVoteAggregator::VoteData::ChangeVote(VoterType voter_type,
  110. const Vote& new_vote) {
  111. switch (voter_type) {
  112. case VoterType::kDefault:
  113. DCHECK(default_vote_.has_value());
  114. default_vote_ = new_vote;
  115. break;
  116. case VoterType::kOverride:
  117. DCHECK(override_vote_.has_value());
  118. override_vote_ = new_vote;
  119. break;
  120. }
  121. }
  122. void OverrideVoteAggregator::VoteData::RemoveVote(VoterType voter_type) {
  123. switch (voter_type) {
  124. case VoterType::kDefault:
  125. DCHECK(default_vote_.has_value());
  126. default_vote_ = absl::nullopt;
  127. break;
  128. case VoterType::kOverride:
  129. DCHECK(override_vote_.has_value());
  130. override_vote_ = absl::nullopt;
  131. break;
  132. }
  133. }
  134. bool OverrideVoteAggregator::VoteData::HasChosenVote() const {
  135. return default_vote_.has_value() || override_vote_.has_value();
  136. }
  137. const Vote& OverrideVoteAggregator::VoteData::GetChosenVote() const {
  138. // The |override_vote| is always chosen first.
  139. if (override_vote_.has_value())
  140. return override_vote_.value();
  141. return default_vote_.value();
  142. }
  143. OverrideVoteAggregator::VoteDataMap::iterator
  144. OverrideVoteAggregator::GetVoteData(const ExecutionContext* execution_context) {
  145. auto it = vote_data_map_.find(execution_context);
  146. DCHECK(it != vote_data_map_.end());
  147. return it;
  148. }
  149. OverrideVoteAggregator::VoteData::VoterType
  150. OverrideVoteAggregator::GetVoterType(VoterId voter_id) const {
  151. DCHECK(voter_id == default_voter_id_ || voter_id == override_voter_id_);
  152. return voter_id == default_voter_id_ ? VoteData::VoterType::kDefault
  153. : VoteData::VoterType::kOverride;
  154. }
  155. } // namespace execution_context_priority
  156. } // namespace performance_manager