diff --git a/anki/decks.py b/anki/decks.py index f2c011656..c020379bf 100644 --- a/anki/decks.py +++ b/anki/decks.py @@ -164,6 +164,9 @@ class DeckManager(object): "A list of all decks." return self.decks.values() + def allIds(self): + return self.decks.keys() + def count(self): return len(self.decks) diff --git a/anki/sched.py b/anki/sched.py index 04d1fd002..089299327 100644 --- a/anki/sched.py +++ b/anki/sched.py @@ -26,6 +26,7 @@ class Scheduler(object): self.reportLimit = 1000 self.reps = 0 self._haveQueues = False + self._clearOverdue = True self._updateCutoff() def getCard(self): @@ -41,6 +42,8 @@ class Scheduler(object): def reset(self): deck = self.col.decks.current() self._updateCutoff() + if self._clearOverdue: + self.removeFailed(expiredOnly=True) self._resetLrn() self._resetRev() self._resetNew() @@ -532,11 +535,16 @@ limit %d""" % (self._deckLimit(), self.reportLimit), lim=self.dayCutoff) time.sleep(0.01) log() - def removeFailed(self, ids=None): + def removeFailed(self, ids=None, expiredOnly=False): "Remove failed cards from the learning queue." - extra = "" if ids: extra = " and id in "+ids2str(ids) + else: + # benchmarks indicate it's about 10x faster to search all decks + # with the index than scan the table + extra = " and did in "+ids2str(self.col.decks.allIds()) + if expiredOnly: + extra += " and odue <= %d" % self.today self.col.db.execute(""" update cards set due = odue, queue = 2, mod = %d, usn = %d diff --git a/tests/test_sched.py b/tests/test_sched.py index d0df38c22..465a8cb64 100644 --- a/tests/test_sched.py +++ b/tests/test_sched.py @@ -325,12 +325,22 @@ def test_overdue_lapse(): c.left = 2 c.ivl = 0 c.flush() + d.sched._clearOverdue = False + # checkpoint + d.save() d.sched.reset() assert d.sched.counts() == (0, 2, 0) c = d.sched.getCard() d.sched.answerCard(c, 3) # it should be due tomorrow assert c.due == d.sched.today + 1 + # revert to before + d.rollback() + d.sched._clearOverdue = True + # with the default settings, the overdue card should be removed from the + # learning queue + d.sched.reset() + assert d.sched.counts() == (0, 0, 1) def test_finished(): d = getEmptyDeck()