Compute deck hashes lazily (#5707)

* Calculate deck hashes lazily

* rename
This commit is contained in:
RickyRister
2025-03-11 18:43:21 -07:00
committed by GitHub
parent 9b00bdcaea
commit ec536126b9
3 changed files with 43 additions and 21 deletions

View File

@@ -262,7 +262,7 @@ bool DeckListModel::setData(const QModelIndex &index, const QVariant &value, con
}
emitRecursiveUpdates(index);
deckList->updateDeckHash();
deckList->refreshDeckHash();
return true;
}
@@ -398,7 +398,7 @@ QModelIndex DeckListModel::addCard(const QString &cardName,
cardNode->setCardSetShortName(cardSetName);
cardNode->setCardCollectorNumber(cardInfoSet.getProperty("num"));
cardNode->setCardProviderId(cardInfoSet.getProperty("uuid"));
deckList->updateDeckHash();
deckList->refreshDeckHash();
}
sort(lastKnownColumn, lastKnownOrder);
emitRecursiveUpdates(parentIndex);

View File

@@ -368,8 +368,8 @@ DeckList::DeckList()
// TODO: https://qt-project.org/doc/qt-4.8/qobject.html#no-copy-constructor-or-assignment-operator
DeckList::DeckList(const DeckList &other)
: QObject(), name(other.name), comments(other.comments), bannerCard(other.bannerCard), deckHash(other.deckHash),
lastLoadedTimestamp(other.lastLoadedTimestamp), tags(other.tags)
: QObject(), name(other.name), comments(other.comments), bannerCard(other.bannerCard),
lastLoadedTimestamp(other.lastLoadedTimestamp), tags(other.tags), cachedDeckHash(other.cachedDeckHash)
{
root = new InnerDecklistNode(other.getRoot());
@@ -378,7 +378,6 @@ DeckList::DeckList(const DeckList &other)
spIterator.next();
sideboardPlans.insert(spIterator.key(), new SideboardPlan(spIterator.key(), spIterator.value()->getMoveList()));
}
updateDeckHash();
}
DeckList::DeckList(const QString &nativeString)
@@ -507,7 +506,7 @@ bool DeckList::loadFromXml(QXmlStreamReader *xml)
}
}
}
updateDeckHash();
refreshDeckHash();
if (xml->error()) {
qDebug() << "Error loading deck from xml: " << xml->errorString();
return false;
@@ -734,7 +733,7 @@ bool DeckList::loadFromStream_Plain(QTextStream &in)
new DecklistCardNode(cardName, amount, getZoneObjFromName(zoneName), setCode, collectorNumber);
}
updateDeckHash();
refreshDeckHash();
return true;
}
@@ -808,8 +807,7 @@ void DeckList::cleanList()
setName();
setComments();
setTags();
deckHash = QString();
emit deckHashChanged();
refreshDeckHash();
}
void DeckList::getCardListHelper(InnerDecklistNode *item, QSet<QString> &result) const
@@ -881,7 +879,7 @@ DecklistCardNode *DeckList::addCard(const QString &cardName,
}
auto *node = new DecklistCardNode(cardName, 1, zoneNode, cardSetName, cardSetCollectorNumber, cardProviderId);
updateDeckHash();
refreshDeckHash();
return node;
}
@@ -907,7 +905,7 @@ bool DeckList::deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNod
}
if (updateHash) {
updateDeckHash();
refreshDeckHash();
}
return true;
@@ -918,7 +916,7 @@ bool DeckList::deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNod
if (inner) {
if (deleteNode(node, inner)) {
if (updateHash) {
updateDeckHash();
refreshDeckHash();
}
return true;
@@ -929,7 +927,7 @@ bool DeckList::deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNod
return false;
}
void DeckList::updateDeckHash()
static QString computeDeckHash(const InnerDecklistNode *root)
{
QStringList cardList;
QSet<QString> hashZones, optionalZones;
@@ -955,7 +953,30 @@ void DeckList::updateDeckHash()
(((quint64)(unsigned char)deckHashArray[1]) << 24) +
(((quint64)(unsigned char)deckHashArray[2] << 16)) +
(((quint64)(unsigned char)deckHashArray[3]) << 8) + (quint64)(unsigned char)deckHashArray[4];
deckHash = QString::number(number, 32).rightJustified(8, '0');
return QString::number(number, 32).rightJustified(8, '0');
}
/**
* Gets the deck hash.
* The hash is computed on the first call to this method, and is cached until the decklist is modified.
*
* @return The deck hash
*/
QString DeckList::getDeckHash() const
{
if (!cachedDeckHash.isEmpty()) {
return cachedDeckHash;
}
cachedDeckHash = computeDeckHash(root);
return cachedDeckHash;
}
/**
* Invalidates the cached deckHash and emits the deckHashChanged signal.
*/
void DeckList::refreshDeckHash()
{
cachedDeckHash = QString();
emit deckHashChanged();
}

View File

@@ -252,7 +252,6 @@ class DeckList : public QObject
private:
QString name, comments;
QPair<QString, QString> bannerCard;
QString deckHash;
QString lastLoadedTimestamp;
QStringList tags;
QMap<QString, SideboardPlan *> sideboardPlans;
@@ -261,6 +260,11 @@ private:
void getCardListWithProviderIdHelper(InnerDecklistNode *item, QMap<QString, QString> &result) const;
InnerDecklistNode *getZoneObjFromName(const QString &zoneName);
/**
* Empty string indicates invalidated cache.
*/
mutable QString cachedDeckHash;
protected:
virtual QString getCardZoneFromName(const QString /*cardName*/, QString currentZoneName)
{
@@ -363,12 +367,6 @@ public:
int getSideboardSize() const;
QString getDeckHash() const
{
return deckHash;
}
void updateDeckHash();
InnerDecklistNode *getRoot() const
{
return root;
@@ -380,6 +378,9 @@ public:
const QString &cardProviderId = QString());
bool deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode = nullptr);
QString getDeckHash() const;
void refreshDeckHash();
/**
* Calls a given function object for each card in the deck. It must
* take a InnerDecklistNode* as its first argument and a