diff --git a/AsbCloudApp/AsbCloudApp.csproj b/AsbCloudApp/AsbCloudApp.csproj
index 7a10181c..8ca1bbfe 100644
--- a/AsbCloudApp/AsbCloudApp.csproj
+++ b/AsbCloudApp/AsbCloudApp.csproj
@@ -18,10 +18,6 @@
-
-
-
-
diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs
index a1881174..cee2cae8 100644
--- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs
+++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs
@@ -82,7 +82,7 @@ namespace AsbCloudInfrastructure.Services.SAUB
return 0;
}
}
-
+ ///
public virtual async Task> GetAsync(int idWell,
DateTime dateBegin = default, double intervalSec = 600d,
int approxPointsCount = 1024, CancellationToken token = default)
diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs
index b96622fe..1caa0102 100644
--- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs
+++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs
@@ -1,23 +1,114 @@
using AsbCloudDb.Model;
using System.Collections.Concurrent;
using System.Collections.Generic;
-using System.Collections;
using System;
-using AsbCloudApp.Services;
+using System.Linq;
+using Microsoft.EntityFrameworkCore;
+using Mapster;
#nullable enable
namespace AsbCloudInfrastructure.Services.SAUB
{
- public class TelemetryDataCache
+ public class TelemetryDataCache
+ where TDto : AsbCloudApp.Data.ITelemetryData
+ where TEntity : class, ITelemetryData
{
- private readonly ConcurrentDictionary> caches;
- private static TelemetryDataCache? instance;
+ private const int activeWellCapacity = 24 * 60 * 60;
+ private const int doneWellCapacity = 65 * 60;
+ private readonly ConcurrentDictionary> caches;
+
public TelemetryDataCache(IAsbCloudDbContext db)
{
caches = new ();
+ LoadCaches(db);
}
+ private void LoadCaches(IAsbCloudDbContext db)
+ {
+ Well[] wells = db.Set()
+ .Include(well => well.Telemetry)
+ .Where(well => well.IdTelemetry != null)
+ .ToArray();
+
+ foreach (Well well in wells)
+ {
+ var capacity = well.IdState == 1
+ ? activeWellCapacity
+ : doneWellCapacity;
+
+ var idTelemetry = well.IdTelemetry!.Value;
+ var hoursOffset = well.Timezone.Hours;
+
+ IEnumerable cacheItemData = GetCacheDataFromDb(db, idTelemetry, capacity, hoursOffset);
+ var cacheItem = new CyclycArray(capacity);
+ cacheItem.AddRange(cacheItemData);
+ caches.TryAdd(idTelemetry, cacheItem);
+ }
+ }
+
+ private static IEnumerable GetCacheDataFromDb(IAsbCloudDbContext db, int idTelemetry, int capacity, double hoursOffset)
+ {
+ var entities = db.Set()
+ .Where(i => i.IdTelemetry == idTelemetry)
+ .OrderByDescending(i => i.DateTime)
+ .Take(capacity)
+ .ToArray()
+ .OrderBy(i => i.DateTime);
+
+ var dtos = entities.Select(entity => {
+ var dto = entity.Adapt();
+ dto.DateTime = entity.DateTime.ToRemoteDateTime(hoursOffset);
+ return dto;
+ });
+
+ return dtos;
+ }
+
+ ///
+ /// Добавить элементы в кеш
+ ///
+ ///
+ ///
+ public void AddRange(int idTelemetry, IEnumerable range)
+ {
+ var cacheItem = caches.GetOrAdd(idTelemetry, _ => new CyclycArray(activeWellCapacity));
+ var newItems = range
+ .OrderBy(i => i.DateTime);
+ foreach (var item in newItems)
+ item.IdTelemetry = idTelemetry;
+ cacheItem.AddRange(newItems);
+ }
+
+ ///
+ /// Получить данные из кеша.
+ /// Если dateBegin меньше минимального элемента в кеше, то вернется null.
+ /// Даже если intervalSec частично перекрыт данными из кеша.
+ ///
+ ///
+ ///
+ ///
+ /// кол-во элементов до которых эти данные прореживаются
+ ///
+ public IEnumerable? GetOrDefault(int idTelemetry, DateTime dateBegin, double intervalSec = 600d, int approxPointsCount = 1024)
+ {
+ if(!caches.TryGetValue(idTelemetry, out CyclycArray? cacheItem))
+ return null;
+
+ if (cacheItem is null || cacheItem[0].DateTime > dateBegin)
+ return null;
+
+ var dateEnd = dateBegin.AddSeconds(intervalSec);
+ var items = cacheItem
+ .Where(i => i.DateTime >= dateBegin && i.DateTime <= dateEnd);
+
+ var ratio = items.Count() / approxPointsCount;
+ if (ratio > 1)
+ items = items
+ .Where((_, index) => index % ratio == 0);
+
+ return items;
+ }
}
}
#nullable disable
\ No newline at end of file