speed up v2 deckDueList() in many decks case

This commit is contained in:
Damien Elmes 2018-05-31 16:21:33 +10:00
parent ec090e02eb
commit c207c9bc8c
2 changed files with 33 additions and 4 deletions

View file

@ -2,7 +2,7 @@
# Copyright: Damien Elmes <anki@ichi2.net>
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import copy
import copy, operator
from anki.utils import intTime, ids2str, json
from anki.hooks import runHook
from anki.consts import *
@ -473,6 +473,34 @@ class DeckManager:
actv.append((g['name'], g['id']))
return actv
def childDids(self, did, childMap):
def gather(node, arr):
for did, child in node.items():
arr.append(did)
gather(child, arr)
arr = []
gather(childMap[did], arr)
return arr
def childMap(self):
nameMap = self.nameMap()
childMap = {}
# go through all decks, sorted by name
for deck in sorted(self.all(), key=operator.itemgetter("name")):
node = {}
childMap[deck['id']] = node
# add note to immediate parent
parts = deck['name'].split("::")
if len(parts) > 1:
immediateParent = "::".join(parts[:-1])
pid = nameMap[immediateParent]['id']
childMap[pid][deck['id']] = node
return childMap
def parents(self, did, nameMap=None):
"All parents of did."
# get parent and grandparent names

View file

@ -215,6 +215,7 @@ order by due""" % self._deckLimit(),
return None
parts = parts[:-1]
return "::".join(parts)
childMap = self.col.decks.childMap()
for deck in decks:
# if we've already seen the exact same deck name, remove the
# invalid duplicate and reload
@ -240,7 +241,7 @@ order by due""" % self._deckLimit(),
else:
plim = None
rlim = self._deckRevLimitSingle(deck, parentLimit=plim)
rev = self._revForDeck(deck['id'], rlim)
rev = self._revForDeck(deck['id'], rlim, childMap)
# save to list
data.append([deck['name'], deck['id'], rev, lrn, new])
# add deck as a parent
@ -749,8 +750,8 @@ and due <= ? limit ?)""",
lim = min(lim, self._deckRevLimitSingle(parent, parentLimit=lim))
return lim
def _revForDeck(self, did, lim):
dids = [did] + [x[1] for x in self.col.decks.children(did)]
def _revForDeck(self, did, lim, childMap):
dids = [did] + self.col.decks.childDids(did, childMap)
lim = min(lim, self.reportLimit)
return self.col.db.scalar(
"""