blob: 9b961634e735679a8c82d8a1ee62d9566b899613 [file] [log] [blame]
// 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_