mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-29 09:22:18 -07:00
[CardDB] Cache CardDatabaseQuerier count maps
This commit is contained in:
parent
2086deff5c
commit
f439f605fd
2 changed files with 50 additions and 30 deletions
|
|
@ -12,6 +12,17 @@ CardDatabaseQuerier::CardDatabaseQuerier(QObject *_parent,
|
||||||
const ICardPreferenceProvider *prefs)
|
const ICardPreferenceProvider *prefs)
|
||||||
: QObject(_parent), db(_db), prefs(prefs)
|
: QObject(_parent), db(_db), prefs(prefs)
|
||||||
{
|
{
|
||||||
|
// Invalidate the cached count maps whenever the database contents change.
|
||||||
|
connect(db, &CardDatabase::cardAdded, this, &CardDatabaseQuerier::invalidateCaches);
|
||||||
|
connect(db, &CardDatabase::cardRemoved, this, &CardDatabaseQuerier::invalidateCaches);
|
||||||
|
connect(db, &CardDatabase::cardDatabaseReset, this, &CardDatabaseQuerier::invalidateCaches);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardDatabaseQuerier::invalidateCaches()
|
||||||
|
{
|
||||||
|
mainCardTypeCountsCache.clear();
|
||||||
|
subCardTypeCountsCache.clear();
|
||||||
|
formatsCountCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -304,44 +315,43 @@ QString CardDatabaseQuerier::getPreferredPrintingProviderId(const QString &cardN
|
||||||
|
|
||||||
QStringList CardDatabaseQuerier::getAllMainCardTypes() const
|
QStringList CardDatabaseQuerier::getAllMainCardTypes() const
|
||||||
{
|
{
|
||||||
QSet<QString> types;
|
return getAllMainCardTypesWithCount().keys();
|
||||||
for (const auto &card : db->cards.values()) {
|
|
||||||
types.insert(card->getMainCardType());
|
|
||||||
}
|
|
||||||
return types.values();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QString, int> CardDatabaseQuerier::getAllMainCardTypesWithCount() const
|
QMap<QString, int> CardDatabaseQuerier::getAllMainCardTypesWithCount() const
|
||||||
{
|
{
|
||||||
QMap<QString, int> typeCounts;
|
// An empty cache is always recomputed correctly: a database with no cards
|
||||||
|
// produces an empty map, so the cache is only ever empty when it needs a
|
||||||
for (const auto &card : db->cards.values()) {
|
// (trivially cheap) rebuild.
|
||||||
QString type = card->getMainCardType();
|
if (mainCardTypeCountsCache.isEmpty()) {
|
||||||
typeCounts[type]++;
|
for (const auto &card : db->cards.values()) {
|
||||||
|
QString type = card->getMainCardType();
|
||||||
|
mainCardTypeCountsCache[type]++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return typeCounts;
|
return mainCardTypeCountsCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QString, int> CardDatabaseQuerier::getAllSubCardTypesWithCount() const
|
QMap<QString, int> CardDatabaseQuerier::getAllSubCardTypesWithCount() const
|
||||||
{
|
{
|
||||||
QMap<QString, int> typeCounts;
|
if (subCardTypeCountsCache.isEmpty()) {
|
||||||
|
for (const auto &card : db->cards.values()) {
|
||||||
|
QString type = card->getCardType();
|
||||||
|
|
||||||
for (const auto &card : db->cards.values()) {
|
QStringList parts = type.split(" — ");
|
||||||
QString type = card->getCardType();
|
|
||||||
|
|
||||||
QStringList parts = type.split(" — ");
|
if (parts.size() > 1) { // Ensure there are subtypes
|
||||||
|
QStringList subtypes = parts[1].split(" ", Qt::SkipEmptyParts);
|
||||||
|
|
||||||
if (parts.size() > 1) { // Ensure there are subtypes
|
for (const QString &subtype : subtypes) {
|
||||||
QStringList subtypes = parts[1].split(" ", Qt::SkipEmptyParts);
|
subCardTypeCountsCache[subtype]++;
|
||||||
|
}
|
||||||
for (const QString &subtype : subtypes) {
|
|
||||||
typeCounts[subtype]++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return typeCounts;
|
return subCardTypeCountsCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
FormatRulesPtr CardDatabaseQuerier::getFormat(const QString &formatName) const
|
FormatRulesPtr CardDatabaseQuerier::getFormat(const QString &formatName) const
|
||||||
|
|
@ -351,18 +361,18 @@ FormatRulesPtr CardDatabaseQuerier::getFormat(const QString &formatName) const
|
||||||
|
|
||||||
QMap<QString, int> CardDatabaseQuerier::getAllFormatsWithCount() const
|
QMap<QString, int> CardDatabaseQuerier::getAllFormatsWithCount() const
|
||||||
{
|
{
|
||||||
QMap<QString, int> formatCounts;
|
if (formatsCountCache.isEmpty()) {
|
||||||
|
for (const auto &card : db->cards.values()) {
|
||||||
|
QStringList allProps = card->getProperties();
|
||||||
|
|
||||||
for (const auto &card : db->cards.values()) {
|
for (const QString &prop : allProps) {
|
||||||
QStringList allProps = card->getProperties();
|
if (prop.startsWith("format-")) {
|
||||||
|
QString formatName = prop.mid(QStringLiteral("format-").size());
|
||||||
for (const QString &prop : allProps) {
|
formatsCountCache[formatName]++;
|
||||||
if (prop.startsWith("format-")) {
|
}
|
||||||
QString formatName = prop.mid(QStringLiteral("format-").size());
|
|
||||||
formatCounts[formatName]++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return formatCounts;
|
return formatsCountCache;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,16 @@ public:
|
||||||
private:
|
private:
|
||||||
const CardDatabase *db; //!< Card database used for all lookups.
|
const CardDatabase *db; //!< Card database used for all lookups.
|
||||||
const ICardPreferenceProvider *prefs; //!< Preference provider for preferred printings.
|
const ICardPreferenceProvider *prefs; //!< Preference provider for preferred printings.
|
||||||
|
|
||||||
|
// Count maps are expensive to compute (they iterate the whole database) and are
|
||||||
|
// queried every time a filter widget is built, so cache them and invalidate on
|
||||||
|
// any database mutation. Only the main thread reads or writes these.
|
||||||
|
mutable QMap<QString, int> mainCardTypeCountsCache;
|
||||||
|
mutable QMap<QString, int> subCardTypeCountsCache;
|
||||||
|
mutable QMap<QString, int> formatsCountCache;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void invalidateCaches();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // COCKATRICE_CARD_DATABASE_QUERIER_H
|
#endif // COCKATRICE_CARD_DATABASE_QUERIER_H
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue