| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/observation_store/observation_store.h" |
| |
| #include <cmath> |
| #include <utility> |
| |
| #include "src/logging.h" |
| #include "src/pb/common.pb.h" |
| #include "src/public/lib/registry_identifiers.h" |
| |
| namespace cobalt::observation_store { |
| |
| namespace { |
| |
| constexpr float kAlmostFullThreshold = 0.6; |
| |
| std::optional<size_t> GetProfileIndex(const std::vector<std::string> &profiles, |
| const std::string_view profile) { |
| for (size_t i = 0; i < profiles.size(); ++i) { |
| if (profile == profiles[i]) { |
| return i; |
| } |
| } |
| |
| return std::nullopt; |
| } |
| |
| } // namespace |
| |
| // TODO(https://fxbug.dev/278930401): NOLINTNEXTLINE(bugprone-easily-swappable-parameters) |
| ObservationStore::ObservationStore(size_t max_bytes_per_observation, size_t max_bytes_per_envelope, |
| size_t max_bytes_total) |
| : max_bytes_per_observation_(max_bytes_per_observation), |
| max_bytes_per_envelope_(max_bytes_per_envelope), |
| max_bytes_total_(max_bytes_total), |
| almost_full_threshold_( |
| std::lround(kAlmostFullThreshold * static_cast<float>(max_bytes_total_))) { |
| CHECK_LE(max_bytes_per_observation_, max_bytes_per_envelope_); |
| CHECK_LE(max_bytes_per_envelope_, max_bytes_total_); |
| CHECK_LE(0, max_bytes_per_envelope_); |
| } |
| |
| bool ObservationStore::IsAlmostFull() const { return Size() > almost_full_threshold_; } |
| |
| uint64_t ObservationStore::num_observations_added() const { |
| uint64_t num_obs = 0; |
| for (const auto &count : num_obs_per_report_) { |
| num_obs += count.second; |
| } |
| return num_obs; |
| } |
| |
| std::vector<uint64_t> ObservationStore::num_observations_added_for_reports( |
| const std::vector<lib::ReportIdentifier> &report_specs) const { |
| std::vector<uint64_t> num_obs; |
| for (lib::ReportIdentifier report_spec : report_specs) { |
| const auto &count = num_obs_per_report_.find(report_spec); |
| if (count != num_obs_per_report_.end()) { |
| num_obs.push_back(count->second); |
| } else { |
| num_obs.push_back(0); |
| } |
| } |
| return num_obs; |
| } |
| |
| void ObservationStore::ResetObservationCounter() { num_obs_per_report_.clear(); } |
| |
| void ObservationStore::Disable(bool is_disabled) { |
| LOG(INFO) << "ObservationStore: " << (is_disabled ? "Disabling" : "Enabling") |
| << " observation storage."; |
| is_disabled_ = is_disabled; |
| } |
| |
| void ObservationStore::EnvelopeHolder::MoveSystemProfilesToEnvelope(Envelope &envelope) { |
| std::vector<std::string> serialized_profiles; |
| |
| for (ObservationBatch &batch : *envelope.mutable_batch()) { |
| const std::string serialized_profile = batch.meta_data().system_profile().SerializeAsString(); |
| std::optional<size_t> sp_index = GetProfileIndex(serialized_profiles, serialized_profile); |
| |
| if (sp_index == std::nullopt) { |
| // This is our first time encountering this system profile. Add it to the envelope. |
| *envelope.add_system_profiles() = batch.meta_data().system_profile(); |
| serialized_profiles.push_back(serialized_profile); |
| sp_index = serialized_profiles.size() - 1; |
| } |
| |
| batch.mutable_meta_data()->set_system_profile_index(*sp_index); |
| batch.mutable_meta_data()->clear_system_profile(); |
| } |
| } |
| |
| } // namespace cobalt::observation_store |