diff --git a/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp b/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp index a6ce5221..7f227817 100644 --- a/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/radar_product_manager.cpp @@ -40,7 +40,11 @@ static constexpr uint32_t NUM_COORIDNATES_1_DEGREE = static std::unordered_map> instanceMap_; +std::unordered_map> + fileIndex_; + static std::shared_mutex fileLoadMutex_; +static std::shared_mutex fileIndexMutex_; class RadarProductManagerImpl { @@ -59,7 +63,7 @@ public: } ~RadarProductManagerImpl() = default; - void + std::shared_ptr StoreRadarProductRecord(std::shared_ptr record); static void @@ -74,6 +78,14 @@ public: std::vector coordinates0_5Degree_; std::vector coordinates1Degree_; + std::map> + level2ProductRecords_; + std::unordered_map>> + level3ProductRecords_; + std::map> level2VolumeScans_; @@ -213,6 +225,8 @@ void RadarProductManager::Initialize() void RadarProductManager::LoadData( std::istream& is, std::shared_ptr request) { + BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "LoadData()"; + RadarProductManagerImpl::LoadNexradFile( [=, &is]() -> std::shared_ptr { return wsr88d::NexradFileFactory::Create(is); }, @@ -223,10 +237,47 @@ void RadarProductManager::LoadFile( const std::string& filename, std::shared_ptr request) { - RadarProductManagerImpl::LoadNexradFile( - [=]() -> std::shared_ptr - { return wsr88d::NexradFileFactory::Create(filename); }, - request); + BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "LoadFile(" << filename << ")"; + + std::shared_ptr existingRecord = nullptr; + + { + std::shared_lock lock {fileIndexMutex_}; + auto it = fileIndex_.find(filename); + if (it != fileIndex_.cend()) + { + BOOST_LOG_TRIVIAL(debug) + << logPrefix_ << "File previously loaded, loading from file cache"; + + existingRecord = it->second; + } + } + + if (existingRecord == nullptr) + { + QObject::connect(request.get(), + &request::NexradFileRequest::RequestComplete, + [=](std::shared_ptr request) + { + auto record = request->radar_product_record(); + + if (record != nullptr) + { + std::unique_lock lock {fileIndexMutex_}; + fileIndex_[filename] = record; + } + }); + + RadarProductManagerImpl::LoadNexradFile( + [=]() -> std::shared_ptr + { return wsr88d::NexradFileFactory::Create(filename); }, + request); + } + else if (request != nullptr) + { + request->set_radar_product_record(existingRecord); + emit request->RequestComplete(request); + } } void RadarProductManagerImpl::LoadNexradFile( @@ -250,9 +301,8 @@ void RadarProductManagerImpl::LoadNexradFile( std::shared_ptr manager = RadarProductManager::Instance(record->radar_id()); - manager->p->StoreRadarProductRecord(record); - - // TODO: When to initialize? + manager->Initialize(); + record = manager->p->StoreRadarProductRecord(record); } lock.unlock(); @@ -286,10 +336,50 @@ void RadarProductManager::LoadLevel2Data(const std::string& filename) emit Level2DataLoaded(); } -void RadarProductManagerImpl::StoreRadarProductRecord( +std::shared_ptr +RadarProductManagerImpl::StoreRadarProductRecord( std::shared_ptr record) { - // TODO + BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "StoreRadarProductRecord()"; + + std::shared_ptr storedRecord = record; + + if (record->radar_product_group() == common::RadarProductGroup::Level2) + { + auto it = level2ProductRecords_.find(record->time()); + if (it != level2ProductRecords_.cend()) + { + BOOST_LOG_TRIVIAL(debug) + << logPrefix_ + << "Level 2 product previously loaded, loading from cache"; + + storedRecord = it->second; + } + else + { + level2ProductRecords_[record->time()] = record; + } + } + else if (record->radar_product_group() == common::RadarProductGroup::Level3) + { + auto productMap = level3ProductRecords_[record->radar_product()]; + + auto it = productMap.find(record->time()); + if (it != productMap.cend()) + { + BOOST_LOG_TRIVIAL(debug) + << logPrefix_ + << "Level 3 product previously loaded, loading from cache"; + + storedRecord = it->second; + } + else + { + productMap[record->time()] = record; + } + } + + return storedRecord; } std::tuple, diff --git a/scwx-qt/source/scwx/qt/types/radar_product_record.cpp b/scwx-qt/source/scwx/qt/types/radar_product_record.cpp index aa690fe7..0262a452 100644 --- a/scwx-qt/source/scwx/qt/types/radar_product_record.cpp +++ b/scwx-qt/source/scwx/qt/types/radar_product_record.cpp @@ -49,8 +49,6 @@ RadarProductRecord::RadarProductRecord( uint16_t julianDate = 0; uint32_t milliseconds = 0; - std::chrono::system_clock::time_point time; - if (level2File != nullptr) { p->radarProductGroup_ = common::RadarProductGroup::Level2; @@ -81,7 +79,7 @@ RadarProductRecord::RadarProductRecord( } } - time = util::TimePoint(julianDate, milliseconds); + p->time_ = util::TimePoint(julianDate, milliseconds); } RadarProductRecord::~RadarProductRecord() = default;