diff --git a/test/source/scwx/provider/aws_level3_data_provider.test.cpp b/test/source/scwx/provider/aws_level3_data_provider.test.cpp index 4e88e4e6..b076d6bb 100644 --- a/test/source/scwx/provider/aws_level3_data_provider.test.cpp +++ b/test/source/scwx/provider/aws_level3_data_provider.test.cpp @@ -66,6 +66,26 @@ TEST(AwsLevel3DataProvider, GetAvailableProducts) EXPECT_GT(products.size(), 0); } +TEST(AwsLevel3DataProvider, GetTimePointsByDate) +{ + using namespace std::chrono; + using sys_days = time_point; + + const auto date = sys_days {2021y / May / 27d}; + const auto tomorrow = date + days {1}; + + AwsLevel3DataProvider provider("KLSX", "N0Q"); + + auto timePoints = provider.GetTimePointsByDate(date); + + EXPECT_GT(timePoints.size(), 0); + for (auto timePoint : timePoints) + { + EXPECT_GE(timePoint, date); + EXPECT_LT(timePoint, tomorrow); + } +} + TEST(AwsLevel3DataProvider, TimePointValid) { using namespace std::chrono; diff --git a/wxdata/include/scwx/provider/aws_nexrad_data_provider.hpp b/wxdata/include/scwx/provider/aws_nexrad_data_provider.hpp index 999a4952..b258e0d8 100644 --- a/wxdata/include/scwx/provider/aws_nexrad_data_provider.hpp +++ b/wxdata/include/scwx/provider/aws_nexrad_data_provider.hpp @@ -20,23 +20,26 @@ public: const std::string& region); virtual ~AwsNexradDataProvider(); - AwsNexradDataProvider(const AwsNexradDataProvider&) = delete; + AwsNexradDataProvider(const AwsNexradDataProvider&) = delete; AwsNexradDataProvider& operator=(const AwsNexradDataProvider&) = delete; AwsNexradDataProvider(AwsNexradDataProvider&&) noexcept; AwsNexradDataProvider& operator=(AwsNexradDataProvider&&) noexcept; - size_t cache_size() const; + size_t cache_size() const override; - std::chrono::system_clock::time_point last_modified() const; - std::chrono::seconds update_period() const; + std::chrono::system_clock::time_point last_modified() const override; + std::chrono::seconds update_period() const override; - std::string FindKey(std::chrono::system_clock::time_point time); - std::string FindLatestKey(); + std::string FindKey(std::chrono::system_clock::time_point time) override; + std::string FindLatestKey() override; + std::vector + GetTimePointsByDate(std::chrono::system_clock::time_point date) override; std::pair - ListObjects(std::chrono::system_clock::time_point date); - std::shared_ptr LoadObjectByKey(const std::string& key); - std::pair Refresh(); + ListObjects(std::chrono::system_clock::time_point date) override; + std::shared_ptr + LoadObjectByKey(const std::string& key) override; + std::pair Refresh() override; protected: std::shared_ptr client(); diff --git a/wxdata/include/scwx/provider/nexrad_data_provider.hpp b/wxdata/include/scwx/provider/nexrad_data_provider.hpp index 5041f9aa..2b1f683b 100644 --- a/wxdata/include/scwx/provider/nexrad_data_provider.hpp +++ b/wxdata/include/scwx/provider/nexrad_data_provider.hpp @@ -101,6 +101,17 @@ public: virtual std::chrono::system_clock::time_point GetTimePointByKey(const std::string& key) const = 0; + /** + * Gets NEXRAD data time points for the date supplied. Lists and adds them + * to the cache if required. + * + * @param date Date for which to get NEXRAD data time points + * + * @return NEXRAD data time points + */ + virtual std::vector + GetTimePointsByDate(std::chrono::system_clock::time_point date) = 0; + /** * Requests available NEXRAD products for the current radar site, and adds * the list to the cache. diff --git a/wxdata/source/scwx/provider/aws_nexrad_data_provider.cpp b/wxdata/source/scwx/provider/aws_nexrad_data_provider.cpp index 4d763135..e8f99b47 100644 --- a/wxdata/source/scwx/provider/aws_nexrad_data_provider.cpp +++ b/wxdata/source/scwx/provider/aws_nexrad_data_provider.cpp @@ -9,6 +9,7 @@ #include #include +#include namespace scwx { @@ -156,6 +157,45 @@ std::string AwsNexradDataProvider::FindLatestKey() return key; } +std::vector +AwsNexradDataProvider::GetTimePointsByDate( + std::chrono::system_clock::time_point date) +{ + const auto day = std::chrono::floor(date); + + std::vector timePoints {}; + + logger_->debug("GetTimePointsByDate: {}", day); + + std::shared_lock lock(p->objectsMutex_); + + // Is the date present in the date list? + if (std::find(p->objectDates_.cbegin(), p->objectDates_.cend(), day) == + p->objectDates_.cend()) + { + // Temporarily unlock mutex + lock.unlock(); + + // List objects, since the date is not present in the date list + ListObjects(date); + + // Re-lock mutex + lock.lock(); + } + + // Determine objects to retrieve + auto objectsBegin = p->objects_.lower_bound(day); + auto objectsEnd = p->objects_.lower_bound(day + std::chrono::days {1}); + + // Copy time points to destination vector + std::transform(objectsBegin, + objectsEnd, + std::back_inserter(timePoints), + [](const auto& object) { return object.first; }); + + return timePoints; +} + std::pair AwsNexradDataProvider::ListObjects(std::chrono::system_clock::time_point date) {