mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 22:10:05 +00:00
Additional level 2 data provider functionality for display of latest data
This commit is contained in:
parent
57e5badd70
commit
4b9d12a7ef
3 changed files with 147 additions and 24 deletions
|
|
@ -29,12 +29,19 @@ public:
|
||||||
|
|
||||||
size_t cache_size() const;
|
size_t cache_size() const;
|
||||||
|
|
||||||
|
std::chrono::system_clock::time_point last_modified() const;
|
||||||
|
std::chrono::seconds update_period() const;
|
||||||
|
|
||||||
std::string FindKey(std::chrono::system_clock::time_point time);
|
std::string FindKey(std::chrono::system_clock::time_point time);
|
||||||
|
std::string FindLatestKey();
|
||||||
std::pair<size_t, size_t>
|
std::pair<size_t, size_t>
|
||||||
ListObjects(std::chrono::system_clock::time_point date);
|
ListObjects(std::chrono::system_clock::time_point date);
|
||||||
std::shared_ptr<wsr88d::Ar2vFile> LoadObjectByKey(const std::string& key);
|
std::shared_ptr<wsr88d::Ar2vFile> LoadObjectByKey(const std::string& key);
|
||||||
size_t Refresh();
|
size_t Refresh();
|
||||||
|
|
||||||
|
std::chrono::system_clock::time_point
|
||||||
|
GetTimePointByKey(const std::string& key) const;
|
||||||
|
|
||||||
static std::chrono::system_clock::time_point
|
static std::chrono::system_clock::time_point
|
||||||
GetTimePointFromKey(const std::string& key);
|
GetTimePointFromKey(const std::string& key);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,23 @@ public:
|
||||||
|
|
||||||
virtual size_t cache_size() const = 0;
|
virtual size_t cache_size() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the last modified time. This is equal to the most recent object's
|
||||||
|
* modification time. If there are no objects, the epoch is returned.
|
||||||
|
*
|
||||||
|
* @return Last modified time
|
||||||
|
*/
|
||||||
|
virtual std::chrono::system_clock::time_point last_modified() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current update period. This is equal to the difference between
|
||||||
|
* the last two objects' modification times. If there are less than two
|
||||||
|
* objects, an update period of 0 is returned.
|
||||||
|
*
|
||||||
|
* @return Update period
|
||||||
|
*/
|
||||||
|
virtual std::chrono::seconds update_period() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the most recent key in the cache, no later than the time provided.
|
* Finds the most recent key in the cache, no later than the time provided.
|
||||||
*
|
*
|
||||||
|
|
@ -36,6 +53,13 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual std::string FindKey(std::chrono::system_clock::time_point time) = 0;
|
virtual std::string FindKey(std::chrono::system_clock::time_point time) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the most recent key in the cache.
|
||||||
|
*
|
||||||
|
* @return Level 2 data key
|
||||||
|
*/
|
||||||
|
virtual std::string FindLatestKey() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists level 2 objects for the date supplied, and adds them to the cache.
|
* Lists level 2 objects for the date supplied, and adds them to the cache.
|
||||||
*
|
*
|
||||||
|
|
@ -66,6 +90,16 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual size_t Refresh() = 0;
|
virtual size_t Refresh() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the object key to a time point.
|
||||||
|
*
|
||||||
|
* @key Level 2 data key
|
||||||
|
*
|
||||||
|
* @return Level 2 data time point
|
||||||
|
*/
|
||||||
|
virtual std::chrono::system_clock::time_point
|
||||||
|
GetTimePointByKey(const std::string& key) const = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Level2DataProviderImpl> p;
|
std::unique_ptr<Level2DataProviderImpl> p;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,20 @@ static const std::string kDefaultRegion_ = "us-east-1";
|
||||||
class AwsLevel2DataProviderImpl
|
class AwsLevel2DataProviderImpl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
struct ObjectRecord
|
||||||
|
{
|
||||||
|
explicit ObjectRecord(
|
||||||
|
const std::string& key,
|
||||||
|
std::chrono::system_clock::time_point lastModified) :
|
||||||
|
key_ {key}, lastModified_ {lastModified}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
~ObjectRecord() = default;
|
||||||
|
|
||||||
|
std::string key_;
|
||||||
|
std::chrono::system_clock::time_point lastModified_;
|
||||||
|
};
|
||||||
|
|
||||||
explicit AwsLevel2DataProviderImpl(const std::string& radarSite,
|
explicit AwsLevel2DataProviderImpl(const std::string& radarSite,
|
||||||
const std::string& bucketName,
|
const std::string& bucketName,
|
||||||
const std::string& region) :
|
const std::string& region) :
|
||||||
|
|
@ -35,7 +49,9 @@ public:
|
||||||
region_ {region},
|
region_ {region},
|
||||||
client_ {nullptr},
|
client_ {nullptr},
|
||||||
objects_ {},
|
objects_ {},
|
||||||
objectsMutex_ {}
|
objectsMutex_ {},
|
||||||
|
lastModified_ {},
|
||||||
|
updatePeriod_ {}
|
||||||
{
|
{
|
||||||
Aws::Client::ClientConfiguration config;
|
Aws::Client::ClientConfiguration config;
|
||||||
config.region = region_;
|
config.region = region_;
|
||||||
|
|
@ -45,14 +61,19 @@ public:
|
||||||
|
|
||||||
~AwsLevel2DataProviderImpl() {}
|
~AwsLevel2DataProviderImpl() {}
|
||||||
|
|
||||||
|
void UpdateMetadata();
|
||||||
|
|
||||||
std::string radarSite_;
|
std::string radarSite_;
|
||||||
std::string bucketName_;
|
std::string bucketName_;
|
||||||
std::string region_;
|
std::string region_;
|
||||||
|
|
||||||
std::unique_ptr<Aws::S3::S3Client> client_;
|
std::unique_ptr<Aws::S3::S3Client> client_;
|
||||||
|
|
||||||
std::map<std::chrono::system_clock::time_point, std::string> objects_;
|
std::map<std::chrono::system_clock::time_point, ObjectRecord> objects_;
|
||||||
std::shared_mutex objectsMutex_;
|
std::shared_mutex objectsMutex_;
|
||||||
|
|
||||||
|
std::chrono::system_clock::time_point lastModified_;
|
||||||
|
std::chrono::seconds updatePeriod_;
|
||||||
};
|
};
|
||||||
|
|
||||||
AwsLevel2DataProvider::AwsLevel2DataProvider(const std::string& radarSite) :
|
AwsLevel2DataProvider::AwsLevel2DataProvider(const std::string& radarSite) :
|
||||||
|
|
@ -78,6 +99,17 @@ size_t AwsLevel2DataProvider::cache_size() const
|
||||||
return p->objects_.size();
|
return p->objects_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::chrono::seconds AwsLevel2DataProvider::update_period() const
|
||||||
|
{
|
||||||
|
return p->updatePeriod_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::chrono::system_clock::time_point
|
||||||
|
AwsLevel2DataProvider::last_modified() const
|
||||||
|
{
|
||||||
|
return p->lastModified_;
|
||||||
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
AwsLevel2DataProvider::FindKey(std::chrono::system_clock::time_point time)
|
AwsLevel2DataProvider::FindKey(std::chrono::system_clock::time_point time)
|
||||||
{
|
{
|
||||||
|
|
@ -87,12 +119,27 @@ AwsLevel2DataProvider::FindKey(std::chrono::system_clock::time_point time)
|
||||||
|
|
||||||
std::shared_lock lock(p->objectsMutex_);
|
std::shared_lock lock(p->objectsMutex_);
|
||||||
|
|
||||||
std::optional<std::string> element =
|
auto element = util::GetBoundedElement(p->objects_, time);
|
||||||
util::GetBoundedElement(p->objects_, time);
|
|
||||||
|
|
||||||
if (element.has_value())
|
if (element.has_value())
|
||||||
{
|
{
|
||||||
key = *element;
|
key = element->key_;
|
||||||
|
}
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AwsLevel2DataProvider::FindLatestKey()
|
||||||
|
{
|
||||||
|
logger_->debug("FindLatestKey()");
|
||||||
|
|
||||||
|
std::string key {};
|
||||||
|
|
||||||
|
std::shared_lock lock(p->objectsMutex_);
|
||||||
|
|
||||||
|
if (!p->objects_.empty())
|
||||||
|
{
|
||||||
|
key = p->objects_.crbegin()->second.key_;
|
||||||
}
|
}
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
|
|
@ -122,7 +169,8 @@ AwsLevel2DataProvider::ListObjects(std::chrono::system_clock::time_point date)
|
||||||
logger_->debug("Found {} objects", objects.size());
|
logger_->debug("Found {} objects", objects.size());
|
||||||
|
|
||||||
// Store objects
|
// Store objects
|
||||||
std::for_each(objects.cbegin(),
|
std::for_each( //
|
||||||
|
objects.cbegin(),
|
||||||
objects.cend(),
|
objects.cend(),
|
||||||
[&](const Aws::S3::Model::Object& object)
|
[&](const Aws::S3::Model::Object& object)
|
||||||
{
|
{
|
||||||
|
|
@ -132,10 +180,16 @@ AwsLevel2DataProvider::ListObjects(std::chrono::system_clock::time_point date)
|
||||||
{
|
{
|
||||||
auto time = GetTimePointFromKey(key);
|
auto time = GetTimePointFromKey(key);
|
||||||
|
|
||||||
|
std::chrono::seconds lastModifiedSeconds {
|
||||||
|
object.GetLastModified().Seconds()};
|
||||||
|
std::chrono::system_clock::time_point lastModified {
|
||||||
|
lastModifiedSeconds};
|
||||||
|
|
||||||
std::unique_lock lock(p->objectsMutex_);
|
std::unique_lock lock(p->objectsMutex_);
|
||||||
|
|
||||||
auto [it, inserted] =
|
auto [it, inserted] = p->objects_.insert_or_assign(
|
||||||
p->objects_.insert_or_assign(time, key);
|
time,
|
||||||
|
AwsLevel2DataProviderImpl::ObjectRecord {key, lastModified});
|
||||||
|
|
||||||
if (inserted)
|
if (inserted)
|
||||||
{
|
{
|
||||||
|
|
@ -152,6 +206,8 @@ AwsLevel2DataProvider::ListObjects(std::chrono::system_clock::time_point date)
|
||||||
outcome.GetError().GetMessage());
|
outcome.GetError().GetMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p->UpdateMetadata();
|
||||||
|
|
||||||
return std::make_pair(newObjects, totalObjects);
|
return std::make_pair(newObjects, totalObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -222,6 +278,32 @@ size_t AwsLevel2DataProvider::Refresh()
|
||||||
return totalNewObjects;
|
return totalNewObjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AwsLevel2DataProviderImpl::UpdateMetadata()
|
||||||
|
{
|
||||||
|
std::shared_lock lock(objectsMutex_);
|
||||||
|
|
||||||
|
if (!objects_.empty())
|
||||||
|
{
|
||||||
|
lastModified_ = objects_.crbegin()->second.lastModified_;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (objects_.size() >= 2)
|
||||||
|
{
|
||||||
|
auto it = objects_.crbegin();
|
||||||
|
auto lastModified = it->second.lastModified_;
|
||||||
|
auto prevModified = (++it)->second.lastModified_;
|
||||||
|
auto delta = lastModified - prevModified;
|
||||||
|
|
||||||
|
updatePeriod_ = std::chrono::duration_cast<std::chrono::seconds>(delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::chrono::system_clock::time_point
|
||||||
|
AwsLevel2DataProvider::GetTimePointByKey(const std::string& key) const
|
||||||
|
{
|
||||||
|
return GetTimePointFromKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
std::chrono::system_clock::time_point
|
std::chrono::system_clock::time_point
|
||||||
AwsLevel2DataProvider::GetTimePointFromKey(const std::string& key)
|
AwsLevel2DataProvider::GetTimePointFromKey(const std::string& key)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue