| // 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, CivilTimeManager* civil_time_mgr, const MetricDefinition& metric, |
| bool is_daily, bool is_expedited) 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, civil_time_mgr->GetTimeInfo(0, 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 = civil_time_mgr->GetInitialUtc().day_index - 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)); |
| } |
| if (is_expedited) { |
| backfill.push_back(end_info); |
| } |
| } else { |
| int past_hours = 1; |
| CB_ASSIGN_OR_RETURN(TimeInfo time_info, civil_time_mgr->GetTimeInfo(past_hours, metric)); |
| while (time_info.hour_id > last_time_info.hour_id && |
| time_info.day_index >= backstop_day_index) { |
| backfill.push_back(time_info); |
| past_hours++; |
| CB_ASSIGN_OR_RETURN(time_info, civil_time_mgr->GetTimeInfo(past_hours, metric)); |
| } |
| std::reverse(backfill.begin(), backfill.end()); |
| } |
| |
| return backfill; |
| } |
| |
| } // namespace cobalt::local_aggregation |