| // Copyright 2020 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. |
| |
| #ifndef COBALT_SRC_LOCAL_AGGREGATION_1_1_LOCAL_AGGREGATE_STORAGE_LOCAL_AGGREGATE_STORAGE_H_ |
| #define COBALT_SRC_LOCAL_AGGREGATION_1_1_LOCAL_AGGREGATE_STORAGE_LOCAL_AGGREGATE_STORAGE_H_ |
| |
| #include <mutex> |
| |
| #include "src/lib/statusor/statusor.h" |
| #include "src/lib/util/file_system.h" |
| #include "src/lib/util/status.h" |
| #include "src/local_aggregation_1_1/local_aggregation.pb.h" |
| #include "src/logger/logger_interface.h" |
| #include "src/logger/project_context_factory.h" |
| |
| namespace cobalt::local_aggregation { |
| |
| // LocalAggregateStorage is the generic interface for storing MetricAggregates. |
| // |
| // Different systems perform better with different implementations of this class, so it is up to the |
| // embedder to chose which StorageStrategy is best. |
| class LocalAggregateStorage { |
| public: |
| enum class StorageStrategy { |
| // Use the ImmediateLocalAggregateStorage implementation. This method writes to disk |
| // synchronously after each call to SaveMetricAggregate. |
| Immediate, |
| |
| // Use the DelayedLocalAggregateStorage implementation. This method is best used on embeddings |
| // where writes to disk are slow, or write amplification is an issue. |
| Delayed, |
| }; |
| |
| // MetricAggregateRef contains a pointer to the requested MetricAggregate, as well as unique_lock |
| // that holds the mutex for the LocalAggregateStorage it came from. |
| class MetricAggregateRef { |
| public: |
| MetricAggregateRef(uint32_t customer_id, uint32_t project_id, uint32_t metric_id, |
| MetricAggregate *aggregate, LocalAggregateStorage *self, std::mutex &mutex) |
| : customer_id_(customer_id), |
| project_id_(project_id), |
| metric_id_(metric_id), |
| aggregate_(aggregate), |
| self_(self), |
| lock_(mutex) {} |
| |
| MetricAggregateRef(uint32_t customer_id, uint32_t project_id, uint32_t metric_id, |
| MetricAggregate *aggregate, LocalAggregateStorage *self, |
| std::unique_lock<std::mutex> mutex_lock) |
| : customer_id_(customer_id), |
| project_id_(project_id), |
| metric_id_(metric_id), |
| aggregate_(aggregate), |
| self_(self), |
| lock_(std::move(mutex_lock)) {} |
| |
| // Returns the pointer to the contained MetricAggregate |
| MetricAggregate *aggregate() { return aggregate_; } |
| |
| // Triggers the source LocalAggregateStorage to save the given MetricAggregate. |
| util::Status Save() { |
| return self_->SaveMetricAggregate(customer_id_, project_id_, metric_id_); |
| } |
| |
| private: |
| uint32_t customer_id_; |
| uint32_t project_id_; |
| uint32_t metric_id_; |
| |
| MetricAggregate *aggregate_; |
| LocalAggregateStorage *self_; |
| std::unique_lock<std::mutex> lock_; |
| }; |
| |
| // New is the expected way to construct LocalAggregateStorage objects. Depending on which |
| // StorageStrategy is supplied, a different implementation of LocalAggregateStorage will be used. |
| static std::unique_ptr<LocalAggregateStorage> New( |
| StorageStrategy strategy, std::string base_directory, util::FileSystem *fs, |
| const logger::ProjectContextFactory *global_project_context_factory); |
| |
| // GetMetricAggregate returns a pointer to the live, mutable MetricAggregate that was requested. |
| // If no such aggregate exists, nullptr will be returned. |
| // |
| // Note: After modifying the MetricAggregate returned by this function, the user is expected to |
| // call 'SaveMetricAggregate' so that the modified values can be persisted to disk. |
| virtual lib::statusor::StatusOr<MetricAggregateRef> GetMetricAggregate(uint32_t customer_id, |
| uint32_t project_id, |
| uint32_t metric_id) = 0; |
| |
| // When DeleteData is called, all aggregated data should be deleted and written to disk |
| // immediately. |
| virtual void DeleteData() = 0; |
| |
| virtual void ResetInternalMetrics(logger::LoggerInterface *internal_logger) = 0; |
| |
| virtual ~LocalAggregateStorage() = default; |
| |
| protected: |
| // SaveMetricAggregate writes the current state of the MetricAggregate for the given |
| // (customer, project, metric) tuple to disk. |
| // |
| // Note: This should be called after modifying the MetricAggregate returned by GetMetricAggregate. |
| virtual util::Status SaveMetricAggregate(uint32_t customer_id, uint32_t project_id, |
| uint32_t metric_id) = 0; |
| }; |
| |
| } // namespace cobalt::local_aggregation |
| |
| #endif // COBALT_SRC_LOCAL_AGGREGATION_1_1_LOCAL_AGGREGATE_STORAGE_LOCAL_AGGREGATE_STORAGE_H_ |