max_vote_aggregator.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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. #ifndef COMPONENTS_PERFORMANCE_MANAGER_EXECUTION_CONTEXT_PRIORITY_MAX_VOTE_AGGREGATOR_H_
  5. #define COMPONENTS_PERFORMANCE_MANAGER_EXECUTION_CONTEXT_PRIORITY_MAX_VOTE_AGGREGATOR_H_
  6. #include <map>
  7. #include <utility>
  8. #include "base/containers/intrusive_heap.h"
  9. #include "components/performance_manager/public/execution_context_priority/execution_context_priority.h"
  10. namespace performance_manager {
  11. namespace execution_context_priority {
  12. // Aggregator that allows votes from an arbitrary number of voters, and forwards
  13. // the maximum vote for each frame. The upstream voting channel must be set
  14. // before any votes are submitted to this aggregator. New voting channels may
  15. // continue to be issued at any time during its lifetime, however.
  16. class MaxVoteAggregator : public VoteObserver {
  17. public:
  18. MaxVoteAggregator();
  19. MaxVoteAggregator(const MaxVoteAggregator&) = delete;
  20. MaxVoteAggregator& operator=(const MaxVoteAggregator&) = delete;
  21. ~MaxVoteAggregator() override;
  22. // Issues a voting channel (effectively registered a voter).
  23. VotingChannel GetVotingChannel();
  24. // Sets the upstream voting channel. Should only be called once.
  25. void SetUpstreamVotingChannel(VotingChannel channel);
  26. protected:
  27. // VoteObserver implementation:
  28. void OnVoteSubmitted(VoterId voter_id,
  29. const ExecutionContext* execution_context,
  30. const Vote& vote) override;
  31. void OnVoteChanged(VoterId voter_id,
  32. const ExecutionContext* execution_context,
  33. const Vote& new_vote) override;
  34. void OnVoteInvalidated(VoterId voter_id,
  35. const ExecutionContext* execution_context) override;
  36. private:
  37. friend class MaxVoteAggregatorTestAccess;
  38. // A StampedVote is a Vote with a serial number that can be used to order
  39. // votes by the order in which they were received. This ensures that votes
  40. // upstreamed by this aggregator remain as stable as possible.
  41. class StampedVote : public base::InternalHeapHandleStorage {
  42. public:
  43. StampedVote();
  44. StampedVote(const Vote& vote, uint32_t vote_id);
  45. StampedVote(StampedVote&&);
  46. StampedVote(const StampedVote&) = delete;
  47. ~StampedVote() override;
  48. StampedVote& operator=(StampedVote&&) = default;
  49. StampedVote& operator=(const StampedVote&) = delete;
  50. bool operator<(const StampedVote& rhs) const {
  51. if (vote_.value() != rhs.vote_.value())
  52. return vote_.value() < rhs.vote_.value();
  53. // Higher |vote_id| values are of lower priority.
  54. return vote_id_ > rhs.vote_id_;
  55. }
  56. const Vote& vote() const { return vote_; }
  57. uint32_t vote_id() const { return vote_id_; }
  58. void SetVote(const Vote& new_vote) { vote_ = new_vote; }
  59. private:
  60. Vote vote_;
  61. uint32_t vote_id_ = 0;
  62. };
  63. // The collection of votes for a single execution context. This is move-only
  64. // because all of its members are move-only. Internally it houses the
  65. // collection of all votes associated with an execution context as max-heap,
  66. // and a map of HeapHandles to access existing votes.
  67. class VoteData {
  68. public:
  69. VoteData();
  70. VoteData(const VoteData& rhs) = delete;
  71. VoteData(VoteData&& rhs);
  72. VoteData& operator=(const VoteData& rhs) = delete;
  73. VoteData& operator=(VoteData&& rhs);
  74. ~VoteData();
  75. // Adds a vote.
  76. void AddVote(VoterId voter_id, const Vote& vote, uint32_t vote_id);
  77. // Updates an existing vote casted by |voter_id|.
  78. void UpdateVote(VoterId voter_id, const Vote& new_vote);
  79. // Removes an existing vote casted by |voter_id|.
  80. void RemoveVote(VoterId voter_id);
  81. // Returns true if this VoteData is empty.
  82. bool IsEmpty() const { return votes_.empty(); }
  83. // Returns the top vote. Invalid to call if IsEmpty() returns true.
  84. const Vote& GetTopVote() const;
  85. private:
  86. base::IntrusiveHeap<StampedVote> votes_;
  87. // Maps each voting channel to the HeapHandle to their associated vote in
  88. // |votes_|.
  89. std::map<VoterId, base::HeapHandle*> heap_handles_;
  90. };
  91. using VoteDataMap = std::map<const ExecutionContext*, VoteData>;
  92. // Looks up the VoteData associated with the provided |execution_context|. The
  93. // data is expected to already exist (enforced by a DCHECK).
  94. VoteDataMap::iterator GetVoteData(const ExecutionContext* execution_context);
  95. // Our channel for upstreaming our votes.
  96. VotingChannel channel_;
  97. // Provides VotingChannels to our input voters.
  98. VotingChannelFactory voting_channel_factory_{this};
  99. // The next StampedVote ID to use.
  100. uint32_t next_vote_id_ = 0;
  101. // Received votes, plus all of the upstreamed votes.
  102. VoteDataMap vote_data_map_;
  103. };
  104. } // namespace execution_context_priority
  105. } // namespace performance_manager
  106. #endif // COMPONENTS_PERFORMANCE_MANAGER_EXECUTION_CONTEXT_PRIORITY_MAX_VOTE_AGGREGATOR_H_