refs #649, added caches to model data reader

* trait
* const fix distributor list
This commit is contained in:
Klaus Basan
2016-06-06 02:36:49 +02:00
parent c39882e5db
commit 332d8e5fc8
8 changed files with 169 additions and 84 deletions

View File

@@ -49,11 +49,22 @@ namespace BlackCore
return ll;
}
const CDistributorList &DbDistributorCache::defaultValue()
{
static const CDistributorList dl;
return dl;
}
const BlackMisc::Network::CUrl &DbIcaoReaderBaseUrl::defaultValue()
{
static const CUrl url;
return url;
}
const CUrl &DbModelReaderBaseUrl::defaultValue()
{
static const CUrl url;
return url;
}
} // ns
} // ns

View File

@@ -14,6 +14,7 @@
#include "blackmisc/datacache.h"
#include "blackmisc/simulation/aircraftmodellist.h"
#include "blackmisc/simulation/distributorlist.h"
#include "blackmisc/aviation/airlineicaocodelist.h"
#include "blackmisc/aviation/aircrafticaocodelist.h"
#include "blackmisc/aviation/liverylist.h"
@@ -40,6 +41,32 @@ namespace BlackCore
static const char *key() { return "dbmodelcache"; }
};
//! Trait for DB distributor cache
struct DbDistributorCache : public BlackMisc::CDataTrait<BlackMisc::Simulation::CDistributorList>
{
//! Default value
static const BlackMisc::Simulation::CDistributorList &defaultValue();
//! Defer loading (no currently small)
static constexpr bool isDeferred() { return false; }
//! Key in data cache
static const char *key() { return "dbdistributorcache"; }
};
//! Trait for DB liveries
struct DbLiveryCache : public BlackMisc::CDataTrait<BlackMisc::Aviation::CLiveryList>
{
//! Default value
static const BlackMisc::Aviation::CLiveryList &defaultValue();
//! Defer loading
static constexpr bool isDeferred() { return true; }
//! Key in data cache
static const char *key() { return "dbliverycache"; }
};
//! Trait for DB airline ICAO codes
struct DbAirlineIcaoCache : public BlackMisc::CDataTrait<BlackMisc::Aviation::CAirlineIcaoCodeList>
{
@@ -80,19 +107,6 @@ namespace BlackCore
static const char *key() { return "dbcountrycache"; }
};
//! Trait for DB liveries
struct DbLiveryCache : public BlackMisc::CDataTrait<BlackMisc::Aviation::CLiveryList>
{
//! Default value
static const BlackMisc::Aviation::CLiveryList &defaultValue();
//! Defer loading
static constexpr bool isDeferred() { return true; }
//! Key in data cache
static const char *key() { return "dbliverycache"; }
};
//! Trait for ICAO reader base URL
struct DbIcaoReaderBaseUrl : public BlackMisc::CDataTrait<BlackMisc::Network::CUrl>
{
@@ -105,6 +119,19 @@ namespace BlackCore
//! Key in data cache
static const char *key() { return "dbicaoreaderurl"; }
};
//! Trait for ICAO reader base URL
struct DbModelReaderBaseUrl : public BlackMisc::CDataTrait<BlackMisc::Network::CUrl>
{
//! Default value
static const BlackMisc::Network::CUrl &defaultValue();
//! First load is synchronous
static constexpr bool isPinned() { return true; }
//! Key in data cache
static const char *key() { return "dbmodelreaderurl"; }
};
} // ns
} // ns

View File

@@ -152,6 +152,8 @@ namespace BlackCore
//! Split into single entity and send dataRead signal
void emitReadSignalPerSingleCachedEntity(BlackMisc::Network::CEntityFlags::Entity cachedEntities);
// ---------------- cache access ------------------
//! Syncronize caches for given entities
virtual void syncronizeCaches(BlackMisc::Network::CEntityFlags::Entity entities) = 0;

View File

@@ -146,7 +146,9 @@ namespace BlackCore
BlackMisc::CData<BlackCore::Data::DbAircraftIcaoCache> m_aircraftIcaoCache {this, &CIcaoDataReader::ps_aircraftIcaoCacheChanged };
BlackMisc::CData<BlackCore::Data::DbAirlineIcaoCache> m_airlineIcaoCache {this, &CIcaoDataReader::ps_airlineIcaoCacheChanged };
BlackMisc::CData<BlackCore::Data::DbCountryCache> m_countryCache {this, &CIcaoDataReader::ps_countryCacheChanged };
BlackMisc::CData<BlackCore::Data::DbIcaoReaderBaseUrl> m_readerUrlCache {this, &CIcaoDataReader::ps_baseUrlCacheChanged };
//! Reader URL (we read from where?) used to detect changes of location
BlackMisc::CData<BlackCore::Data::DbIcaoReaderBaseUrl> m_readerUrlCache {this, &CIcaoDataReader::ps_baseUrlCacheChanged };
//! Update reader URL
void updateReaderUrl(const BlackMisc::Network::CUrl &url);

View File

@@ -47,97 +47,89 @@ namespace BlackCore
CLiveryList CModelDataReader::getLiveries() const
{
QReadLocker l(&m_lockLivery);
return m_liveries;
return this->m_liveryCache.getCopy();
}
CLivery CModelDataReader::getLiveryForCombinedCode(const QString &combinedCode) const
{
if (!CLivery::isValidCombinedCode(combinedCode)) { return CLivery(); }
CLiveryList liveries(getLiveries());
const CLiveryList liveries(getLiveries());
return liveries.findByCombinedCode(combinedCode);
}
CLivery CModelDataReader::getStdLiveryForAirlineCode(const CAirlineIcaoCode &icao) const
{
if (!icao.hasValidDesignator()) { return CLivery(); }
CLiveryList liveries(getLiveries());
const CLiveryList liveries(getLiveries());
return liveries.findStdLiveryByAirlineIcaoDesignator(icao);
}
CLivery CModelDataReader::getLiveryForDbKey(int id) const
{
if (id < 0) { return CLivery(); }
CLiveryList liveries(getLiveries());
const CLiveryList liveries(getLiveries());
return liveries.findByKey(id);
}
CLivery CModelDataReader::smartLiverySelector(const CLivery &liveryPattern) const
{
CLiveryList liveries(getLiveries()); // thread safe copy
const CLiveryList liveries(getLiveries()); // thread safe copy
return liveries.smartLiverySelector(liveryPattern);
}
CDistributorList CModelDataReader::getDistributors() const
{
QReadLocker l(&m_lockDistributor);
return m_distributors;
return m_distributorCache.getCopy();
}
CAircraftModelList CModelDataReader::getModels() const
{
QReadLocker l(&m_lockModels);
return m_models;
return m_modelCache.getCopy();
}
CAircraftModel CModelDataReader::getModelForModelString(const QString &modelString) const
{
if (modelString.isEmpty()) { return CAircraftModel(); }
CAircraftModelList models(getModels());
const CAircraftModelList models(getModels());
return models.findFirstByModelStringOrDefault(modelString);
}
CAircraftModelList CModelDataReader::getModelsForAircraftDesignatorAndLiveryCombinedCode(const QString &aircraftDesignator, const QString &combinedCode)
{
if (aircraftDesignator.isEmpty()) { return CAircraftModelList(); }
CAircraftModelList models(getModels());
const CAircraftModelList models(getModels());
return models.findByAircraftDesignatorAndLiveryCombinedCode(aircraftDesignator, combinedCode);
}
int CModelDataReader::getLiveriesCount() const
{
QReadLocker l(&m_lockLivery);
return m_liveries.size();
return this->getLiveries().size();
}
int CModelDataReader::getDistributorsCount() const
{
QReadLocker l(&m_lockDistributor);
return m_distributors.size();
return this->getDistributors().size();
}
CDistributor CModelDataReader::smartDistributorSelector(const CDistributor &distributorPattern) const
{
CDistributorList distributors(getDistributors()); // thread safe copy
const CDistributorList distributors(getDistributors()); // thread safe copy
return distributors.smartDistributorSelector(distributorPattern);
}
int CModelDataReader::getModelsCount() const
{
QReadLocker l(&m_lockModels);
return m_models.size();
return this->getModels().size();
}
QList<int> CModelDataReader::getModelDbKeys() const
{
QReadLocker l(&m_lockModels);
return m_models.toDbKeyList();
return this->getModels().toDbKeyList();
}
QStringList CModelDataReader::getModelStrings() const
{
QReadLocker l(&m_lockModels);
return m_models.getModelStrings(false);
return this->getModels().getModelStrings(false);
}
bool CModelDataReader::areAllDataRead() const
@@ -217,6 +209,37 @@ namespace BlackCore
}
}
void CModelDataReader::ps_liveryCacheChanged()
{
// void
}
void CModelDataReader::ps_modelCacheChanged()
{
// void
}
void CModelDataReader::ps_distributorCacheChanged()
{
// void
}
void CModelDataReader::ps_baseUrlCacheChanged()
{
// void
}
void CModelDataReader::updateReaderUrl(const CUrl &url)
{
const CUrl current = this->m_readerUrlCache.getCopy();
if (current == url) { return; }
const CStatusMessage m = this->m_readerUrlCache.set(url);
if (m.isFailure())
{
CLogMessage::preformatted(m);
}
}
void CModelDataReader::ps_parseLiveryData(QNetworkReply *nwReplyPtr)
{
// wrap pointer, make sure any exit cleans up reply
@@ -245,16 +268,18 @@ namespace BlackCore
liveries = CLiveryList::fromDatabaseJson(res);
}
// this part needs to be synchronized
int n = liveries.size();
qint64 latestTimestamp = liveries.latestTimestampMsecsSinceEpoch();
if (n > 0 && latestTimestamp < 0)
{
QWriteLocker wl(&this->m_lockLivery);
this->m_liveries = liveries;
CLogMessage(this).error("No timestamp in livery list, setting to last modified value");
latestTimestamp = lastModifiedMsSinceEpoch(nwReply.data());
}
this->m_liveryCache.set(liveries, latestTimestamp);
this->updateReaderUrl(this->getBaseUrl());
// never emit when lock is held -> deadlock
emit dataRead(CEntityFlags::LiveryEntity,
res.isRestricted() ? CEntityFlags::ReadFinishedRestricted : CEntityFlags::ReadFinished, n);
emit dataRead(CEntityFlags::LiveryEntity, res.isRestricted() ? CEntityFlags::ReadFinishedRestricted : CEntityFlags::ReadFinished, n);
CLogMessage(this).info("Read %1 %2 from %3") << n << CEntityFlags::flagToString(CEntityFlags::LiveryEntity) << urlString;
}
@@ -286,14 +311,17 @@ namespace BlackCore
distributors = CDistributorList::fromDatabaseJson(res);
}
// this part needs to be synchronized
int n = distributors.size();
qint64 latestTimestamp = distributors.latestTimestampMsecsSinceEpoch();
if (n > 0 && latestTimestamp < 0)
{
QWriteLocker wl(&this->m_lockDistributor);
this->m_distributors = distributors;
CLogMessage(this).error("No timestamp in distributor list, setting to last modified value");
latestTimestamp = lastModifiedMsSinceEpoch(nwReply.data());
}
emit dataRead(CEntityFlags::DistributorEntity,
res.isRestricted() ? CEntityFlags::ReadFinishedRestricted : CEntityFlags::ReadFinished, n);
this->m_distributorCache.set(distributors, latestTimestamp);
this->updateReaderUrl(this->getBaseUrl());
emit dataRead(CEntityFlags::DistributorEntity, res.isRestricted() ? CEntityFlags::ReadFinishedRestricted : CEntityFlags::ReadFinished, n);
CLogMessage(this).info("Read %1 %2 from %3") << n << CEntityFlags::flagToString(CEntityFlags::DistributorEntity) << urlString;
}
@@ -327,13 +355,16 @@ namespace BlackCore
// syncronized update
int n = models.size();
qint64 latestTimestamp = models.latestTimestampMsecsSinceEpoch();
if (n > 0 && latestTimestamp < 0)
{
QWriteLocker wl(&this->m_lockModels);
this->m_models = models;
CLogMessage(this).error("No timestamp in model list, setting to last modified value");
latestTimestamp = lastModifiedMsSinceEpoch(nwReply.data());
}
this->m_modelCache.set(models, latestTimestamp);
this->updateReaderUrl(this->getBaseUrl());
emit dataRead(CEntityFlags::ModelEntity,
res.isRestricted() ? CEntityFlags::ReadFinishedRestricted : CEntityFlags::ReadFinished, n);
emit dataRead(CEntityFlags::ModelEntity, res.isRestricted() ? CEntityFlags::ReadFinishedRestricted : CEntityFlags::ReadFinished, n);
CLogMessage(this).info("Read %1 %2 from %3") << n << CEntityFlags::flagToString(CEntityFlags::ModelEntity) << urlString;
}
@@ -351,11 +382,8 @@ namespace BlackCore
CLiveryList liveries;
liveries.convertFromJson(liveriesJson);
int c = liveries.size();
{
QWriteLocker l(&m_lockLivery);
m_liveries = liveries;
}
// never emit when lcok is held -> deadlock
this->m_liveryCache.set(liveries);
emit dataRead(CEntityFlags::LiveryEntity, CEntityFlags::ReadFinished, c);
reallyRead |= CEntityFlags::LiveryEntity;
}
@@ -369,10 +397,8 @@ namespace BlackCore
CAircraftModelList models;
models.convertFromJson(Json::jsonObjectFromString(modelsJson));
int c = models.size();
{
QWriteLocker l(&m_lockModels);
m_models = models;
}
this->m_modelCache.set(models);
emit dataRead(CEntityFlags::ModelEntity, CEntityFlags::ReadFinished, c);
reallyRead |= CEntityFlags::ModelEntity;
}
@@ -386,12 +412,10 @@ namespace BlackCore
CDistributorList distributors;
distributors.convertFromJson(Json::jsonObjectFromString(distributorsJson));
int c = distributors.size();
{
QWriteLocker l(&m_lockDistributor);
m_distributors = distributors;
}
reallyRead |= CEntityFlags::DistributorEntity;
this->m_distributorCache.set(distributors);
emit dataRead(CEntityFlags::DistributorEntity, CEntityFlags::ReadFinished, c);
reallyRead |= CEntityFlags::DistributorEntity;
}
}
@@ -438,30 +462,44 @@ namespace BlackCore
void CModelDataReader::syncronizeCaches(CEntityFlags::Entity entities)
{
Q_UNUSED(entities);
if (entities.testFlag(CEntityFlags::LiveryEntity)) { this->m_liveryCache.synchronize(); }
if (entities.testFlag(CEntityFlags::ModelEntity)) { this->m_modelCache.synchronize(); }
if (entities.testFlag(CEntityFlags::DistributorEntity)) { this->m_distributorCache.synchronize(); }
}
void CModelDataReader::invalidateCaches(CEntityFlags::Entity entities)
{
Q_UNUSED(entities);
if (entities.testFlag(CEntityFlags::LiveryEntity)) { CDataCache::instance()->clearAllValues(this->m_liveryCache.getKey()); }
if (entities.testFlag(CEntityFlags::ModelEntity)) { CDataCache::instance()->clearAllValues(this->m_modelCache.getKey()); }
if (entities.testFlag(CEntityFlags::DistributorEntity)) { CDataCache::instance()->clearAllValues(this->m_distributorCache.getKey()); }
}
QDateTime CModelDataReader::getCacheTimestamp(CEntityFlags::Entity entity) const
{
Q_UNUSED(entity);
return QDateTime();
switch (entity)
{
case CEntityFlags::LiveryEntity: return this->m_liveryCache.getAvailableTimestamp();
case CEntityFlags::ModelEntity: return this->m_modelCache.getAvailableTimestamp();
case CEntityFlags::DistributorEntity: return this->m_distributorCache.getAvailableTimestamp();
default: return QDateTime();
}
}
int CModelDataReader::getCacheCount(CEntityFlags::Entity entity) const
{
Q_UNUSED(entity);
return 0;
switch (entity)
{
case CEntityFlags::LiveryEntity: return this->m_liveryCache.getCopy().size();
case CEntityFlags::ModelEntity: return this->m_modelCache.getCopy().size();
case CEntityFlags::DistributorEntity: return this->m_distributorCache.getCopy().size();
default: return 0;
}
}
bool CModelDataReader::hasChangedUrl(CEntityFlags::Entity entity) const
{
Q_UNUSED(entity);
return CDatabaseReader::isChangedUrl(CUrl(), this->getBaseUrl());
return CDatabaseReader::isChangedUrl(this->m_readerUrlCache.getCopy(), this->getBaseUrl());
}
const CUrl &CModelDataReader::getBaseUrl()

View File

@@ -13,6 +13,7 @@
#define BLACKCORE_MODELDATAREADER_H
#include "blackcore/blackcoreexport.h"
#include "blackcore/data/dbcaches.h"
#include "blackcore/db/databasereader.h"
#include "blackmisc/aviation/airlineicaocode.h"
#include "blackmisc/aviation/livery.h"
@@ -142,17 +143,21 @@ namespace BlackCore
//! Read / re-read data file
void ps_read(BlackMisc::Network::CEntityFlags::Entity entity = BlackMisc::Network::CEntityFlags::DistributorLiveryModel, const QDateTime &newerThan = QDateTime());
private:
BlackMisc::Aviation::CLiveryList m_liveries;
BlackMisc::Simulation::CDistributorList m_distributors;
BlackMisc::Simulation::CAircraftModelList m_models;
BlackMisc::Network::CUrl m_urlLiveries;
BlackMisc::Network::CUrl m_urlDistributors;
BlackMisc::Network::CUrl m_urlModels;
void ps_liveryCacheChanged();
void ps_modelCacheChanged();
void ps_distributorCacheChanged();
void ps_baseUrlCacheChanged();
mutable QReadWriteLock m_lockDistributor;
mutable QReadWriteLock m_lockLivery;
mutable QReadWriteLock m_lockModels;
private:
BlackMisc::CData<BlackCore::Data::DbLiveryCache> m_liveryCache {this, &CModelDataReader::ps_liveryCacheChanged };
BlackMisc::CData<BlackCore::Data::DbModelCache> m_modelCache {this, &CModelDataReader::ps_modelCacheChanged };
BlackMisc::CData<BlackCore::Data::DbDistributorCache> m_distributorCache {this, &CModelDataReader::ps_distributorCacheChanged };
//! Reader URL (we read from where?) used to detect changes of location
BlackMisc::CData<BlackCore::Data::DbModelReaderBaseUrl> m_readerUrlCache {this, &CModelDataReader::ps_baseUrlCacheChanged };
//! Update reader URL
void updateReaderUrl(const BlackMisc::Network::CUrl &url);
//! Base URL
//! \threadsafe

View File

@@ -32,7 +32,7 @@ namespace BlackMisc
return CDistributor();
}
CDistributor CDistributorList::smartDistributorSelector(const CDistributor &distributorPattern)
CDistributor CDistributorList::smartDistributorSelector(const CDistributor &distributorPattern) const
{
if (distributorPattern.hasValidDbKey())
{

View File

@@ -49,7 +49,7 @@ namespace BlackMisc
CDistributor findByKeyOrAlias(const QString &keyOrAlias) const;
//! Best match by given pattern
CDistributor smartDistributorSelector(const CDistributor &distributorPattern);
CDistributor smartDistributorSelector(const CDistributor &distributorPattern) const;
//! At least is matching key or alias
bool matchesAnyKeyOrAlias(const QString &keyOrAlias) const;