1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/reporting/health/health_module_delegate_impl.h"
#include <utility>
#include "base/logging.h"
#include "components/reporting/util/file.h"
#include "components/reporting/util/status.h"
namespace reporting {
namespace {
const size_t kRepeatedPtrFieldOverhead = 2;
} // namespace
HealthModuleDelegateImpl::HealthModuleDelegateImpl(
const base::FilePath& directory,
size_t max_history_storage,
std::string_view file_base_name)
: directory_(directory),
file_base_name_(file_base_name),
max_history_storage_(max_history_storage) {}
HealthModuleDelegateImpl::~HealthModuleDelegateImpl() {
// Because of weak ptr factory, must be on the same sequence.
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
Status HealthModuleDelegateImpl::DoInit() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
files_ = HealthModuleFiles::Create(directory_, file_base_name_,
max_history_storage_);
if (!files_) {
return Status(error::FAILED_PRECONDITION, "Could not create history files");
}
files_->PopulateHistory(&data_in_memory_);
return Status::StatusOK();
}
void HealthModuleDelegateImpl::DoGetERPHealthData(HealthCallback cb) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
std::move(cb).Run(data_in_memory_);
}
void HealthModuleDelegateImpl::DoPostHealthRecord(HealthDataHistory record) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (static_cast<size_t>(record.ByteSizeLong()) > max_history_storage_) {
DVLOG(1) << "Health record exceeded max storage";
return;
}
if (!IsInitialized()) {
return;
}
auto* const history = data_in_memory_.mutable_history();
size_t history_space = data_in_memory_.ByteSizeLong();
const size_t record_space = record.ByteSizeLong();
if (history_space + record_space > max_history_storage_) {
size_t removable_space = 0;
int index_removed = 0;
// Find out how many elements must be deleted to make room.
while (index_removed < history->size()) {
removable_space +=
data_in_memory_.history().Get(index_removed).ByteSizeLong() +
kRepeatedPtrFieldOverhead;
if (history_space + record_space - removable_space <=
max_history_storage_) {
break;
}
index_removed++;
}
history->DeleteSubrange(0, index_removed + 1);
}
storage_used_ += record.ByteSizeLong();
*data_in_memory_.add_history() = record;
}
} // namespace reporting
|