| // 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. |
| |
| #include "src/local_aggregation_1_1/backfill_manager.h" |
| |
| #include <algorithm> |
| #include <chrono> |
| |
| #include "src/lib/util/datetime_util.h" |
| #include "src/local_aggregation_1_1/local_aggregation.pb.h" |
| #include "src/public/lib/statusor/status_macros.h" |
| #include "src/public/lib/statusor/statusor.h" |
| #include "src/registry/metric_definition.pb.h" |
| |
| namespace cobalt::local_aggregation { |
| |
| using TimeInfo = util::TimeInfo; |
| using time_point = std::chrono::system_clock::time_point; |
| |
| BackfillManager::BackfillManager(uint32_t total_backfill_window) |
| : backstop_days_(total_backfill_window) {} |
| |
| lib::statusor::StatusOr<std::vector<TimeInfo>> BackfillManager::CalculateBackfill( |
| TimeInfo last_time_info, time_point end_time, |
| const util::CivilTimeConverterInterface& civil_time_converter, const MetricDefinition& metric, |
| bool is_daily) const { |
| // Calculate the end day index and hour ID with respect to the time zone specified in `metric`. |
| CB_ASSIGN_OR_RETURN(TimeInfo end_info, |
| TimeInfo::FromTimePoint(end_time, civil_time_converter, metric)); |
| |
| // Calculate the backstop day index with respect to the current UTC time. It is not useful to send |
| // observations for earlier day indices, since the shuffler's lookback period is calculated with |
| // respect to UTC. Observations with smaller day indices will be dropped. |
| uint32_t backstop_day_index = util::TimePointToDayIndexUtc(end_time) - backstop_days_; |
| |
| std::vector<TimeInfo> backfill; |
| // If calculating backfill for a daily report, select every day index since the last one (or the |
| // backstop day index, whichever is larger), up to the day index of `end_time` in `metric`'s time |
| // zone. |
| // |
| // If calculating for an hourly report, we need to be more careful, since not all hour IDs are |
| // valid for a given time zone. For each hour within the backfill period, we need to compute the |
| // hour ID with respect to `metric`'s time zone as of the beginning of that hour. This accounts |
| // for the possibility that the UTC offset or DST status may change within the backfill period. |
| if (is_daily) { |
| uint32_t start_day_index = std::max(last_time_info.day_index + 1, backstop_day_index); |
| for (uint32_t i = start_day_index; i < end_info.day_index; ++i) { |
| backfill.push_back(TimeInfo::FromDayIndex(i)); |
| } |
| } else { |
| time_point time = end_time - util::kOneHour; |
| while (time >= time_point::min()) { |
| CB_ASSIGN_OR_RETURN(TimeInfo time_info, |
| TimeInfo::FromTimePoint(time, civil_time_converter, metric)); |
| if (time_info.hour_id <= last_time_info.hour_id || time_info.day_index < backstop_day_index) { |
| break; |
| } |
| backfill.push_back(time_info); |
| time -= util::kOneHour; |
| } |
| std::reverse(backfill.begin(), backfill.end()); |
| } |
| |
| return backfill; |
| } |
| |
| } // namespace cobalt::local_aggregation |