private async Task FetchMeasurementsAsync(DateTime Hour) { // Discard all old data. hourData = new Dictionary <DateTime, List <Measurement> >(); // Determine where to stop. var endHour = Hour.AddHours(PrefetchSize); if (endHour > CacheEnd) { endHour = CacheEnd; } // Initialize the hour data cache. for (DateTime i = Hour; i < endHour; i = i.AddHours(1)) { hourData[i] = new List <Measurement>(); } // Fetch raw data. var measurements = await Database.GetRawMeasurementsAsync(SensorId, Hour, endHour); // Insert data into cache. foreach (var item in measurements) { var hour = MeasurementAggregation.Quantize(item.Time, TimeSpan.FromHours(1)); hourData[hour].Add(item); } }
/// <summary> /// Computes the given number of /// </summary> private void ComputeInCacheHourAverages( DateTime Start, int Offset, int Count, Measurement[] Target) { for (int i = 0; i < Count; i++) { var hour = Start.AddHours(i + Offset); Target[i + Offset] = MeasurementAggregation.Aggregate(hourData[hour], SensorId, hour); } }
/// <summary> /// Gets the hour average for the given hour. /// </summary> private async Task <Measurement> GetRealHourAverageAsync(DateTime Hour) { if (hourAverages == null) { await FetchHourAveragesAsync(); } Measurement result; if (hourAverages.TryGetValue(Hour, out result)) { return(result); } else { result = MeasurementAggregation.Aggregate( await GetMeasurementsAsync(Hour), SensorId, Hour); hourAverages[Hour] = result; return(result); } }
/// <summary> /// Gets the day average for the given day. /// </summary> private async Task <Measurement> GetRealDayAverageAsync(DateTime Day) { if (dayAverages == null) { await FetchDayAveragesAsync(); } Measurement result; if (dayAverages.TryGetValue(Day, out result)) { return(result); } else { result = MeasurementAggregation.Aggregate( await GetRealHourAveragesAsync(Day, 24), SensorId, Day, Enumerable.Average); dayAverages[Day] = result; return(result); } }
/// <summary> /// Gets the month-average for the given month. /// </summary> public async Task <Measurement> GetMonthAverageAsync(DateTime Month) { if (monthAverages == null) { await FetchMonthAveragesAsync(); } Measurement result; if (monthAverages.TryGetValue(Month, out result)) { return(result); } else { var timeSpan = Month.AddMonths(1) - Month; result = MeasurementAggregation.Aggregate( await GetRealDayAveragesAsync(Month, (int)timeSpan.TotalDays), SensorId, Month, Enumerable.Average); monthAverages[Month] = result; return(result); } }
private async Task <IEnumerable <Measurement> > GetMeasurementsAsync(FrozenPeriod Period) { const int MinutesPerHour = 60; switch (Period.Compaction) { case CompactionLevel.DayAverages: case CompactionLevel.HourAverages: case CompactionLevel.Measurements: // We'll re-create measurement data by replicating // hour-average data. var results = await GetHourAveragesAsync( MeasurementAggregation.Quantize(Period.StartTime, TimeSpan.FromHours(1)), (int)Math.Ceiling(Period.Duration.TotalHours)); return(ReplicateEach(results, Period.StartTime, Period.EndTime, TimeSpan.FromMinutes(1), MinutesPerHour).ToArray()); case CompactionLevel.None: default: // We can just fetch real measurements from the database. return(await Database.GetRawMeasurementsAsync(SensorId, Period.StartTime, Period.EndTime)); } }
private async Task <IEnumerable <Measurement> > GetHourAveragesAsync(FrozenPeriod Period) { const int HoursPerDay = 24; switch (Period.Compaction) { case CompactionLevel.DayAverages: case CompactionLevel.HourAverages: // We'll re-create hour-average data by replicating // day-average data. var results = await GetDayAveragesAsync( MeasurementAggregation.Quantize(Period.StartTime, TimeSpan.FromDays(1)), (int)Math.Ceiling(Period.Duration.TotalDays)); return(ReplicateEach(results, Period.StartTime, Period.EndTime, TimeSpan.FromHours(1), HoursPerDay).ToArray()); case CompactionLevel.Measurements: case CompactionLevel.None: default: // We can just fetch or create "real" hour-average data. return(await GetRealHourAveragesAsync(Period.StartTime, (int)Period.Duration.TotalHours)); } }
private async Task <IEnumerable <Measurement> > GetDayAveragesAsync(FrozenPeriod Period) { switch (Period.Compaction) { case CompactionLevel.DayAverages: // We'll re-create day-average data by replicating // month-average data. var results = new List <Measurement>(); for (var day = Period.StartTime; day < Period.EndTime; day = day.AddDays(1)) { var monthMeasurement = await GetMonthAverageAsync(MeasurementAggregation.QuantizeMonth(day)); results.Add(new Measurement(SensorId, day, monthMeasurement.MeasuredData, monthMeasurement.Notes)); } return(results); case CompactionLevel.HourAverages: case CompactionLevel.Measurements: case CompactionLevel.None: default: // We can just fetch or create "real" day-average data. return(await GetRealDayAveragesAsync(Period.StartTime, (int)Period.Duration.TotalDays)); } }