Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question loading gets faster #570

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 9 additions & 17 deletions pylib/anki/sched.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ def __init__( # pylint: disable=super-init-not-called
self.today: Optional[int] = None
self._haveQueues = False
self._updateCutoff()
self._next_card = None
self._current_card = None

def answerCard(self, card: Card, ease: int) -> None:
self.col.log()
Expand Down Expand Up @@ -280,10 +282,11 @@ def _fillLrn(self) -> Union[bool, List[Any]]:
self._lrnQueue = self.col.db.all(
f"""
select due, id from cards where
did in %s and queue = {QUEUE_TYPE_LRN} and due < ?
did in %s and queue = {QUEUE_TYPE_LRN} and due < ? and nid != ?
limit %d"""
% (self._deckLimit(), self.reportLimit),
self.dayCutoff,
self._current_card_nid(),
)
for i in range(len(self._lrnQueue)):
self._lrnQueue[i] = (self._lrnQueue[i][0], self._lrnQueue[i][1])
Expand Down Expand Up @@ -566,9 +569,10 @@ def _fillRev(self) -> Optional[bool]:
self._revQueue = self.col.db.list(
f"""
select id from cards where
did = ? and queue = {QUEUE_TYPE_REV} and due <= ? limit ?""",
did = ? and queue = {QUEUE_TYPE_REV} and due <= ? and nid != ? limit ?""",
did,
self.today,
self._current_card_nid(),
lim,
)
if self._revQueue:
Expand Down Expand Up @@ -974,7 +978,7 @@ def buryCards(self, cids: List[int]) -> None: # type: ignore[override]
##########################################################################

def _burySiblings(self, card: Card) -> None:
toBury = []
toBury: List[int] = []
nconf = self._newConf(card)
buryNew = nconf.get("bury", True)
rconf = self._revConf(card)
Expand All @@ -989,21 +993,9 @@ def _burySiblings(self, card: Card) -> None:
self.today,
):
if queue == QUEUE_TYPE_REV:
if buryRev:
toBury.append(cid)
# if bury disabled, we still discard to give same-day spacing
try:
self._revQueue.remove(cid)
except ValueError:
pass
self._actual_bury_siblings(buryRev, toBury, cid, self._revQueue)
else:
# if bury disabled, we still discard to give same-day spacing
if buryNew:
toBury.append(cid)
try:
self._newQueue.remove(cid)
except ValueError:
pass
self._actual_bury_siblings(buryNew, toBury, cid, self._newQueue)
# then bury
if toBury:
self.col.db.execute(
Expand Down
82 changes: 59 additions & 23 deletions pylib/anki/schedv2.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class Scheduler:
haveCustomStudy = True
_burySiblingsOnAnswer = True
revCount: int
_next_card: Optional[Card]
_current_card: Optional[Card]

def __init__(self, col: anki.storage._Collection) -> None:
self.col = col.weakref()
Expand All @@ -46,13 +48,13 @@ def __init__(self, col: anki.storage._Collection) -> None:
self._haveQueues = False
self._lrnCutoff = 0
self._updateCutoff()
self._next_card = None
self._current_card = None

def getCard(self) -> Optional[Card]:
"""Pop the next card from the queue. None if finished."""
self._checkDay()
if not self._haveQueues:
self.reset()
card = self._getCard()
card = self.load_next_card(False)
self._next_card = None
if card:
self.col.log(card)
if not self._burySiblingsOnAnswer:
Expand All @@ -62,13 +64,45 @@ def getCard(self) -> Optional[Card]:
return card
return None

def load_next_card(self, qa):
""" set _next_card to next card and returns it.

qa -- whether to precompute question and answer. Useful to win time while the user review"""
self._checkDay()
if not self._haveQueues:
self.reset()
if self._next_card is None:
self._next_card = self._getCard()
while (
self._next_card is not None
and self._next_card.nid == self._current_card_nid()
):
self._next_card = self._getCard()
if self._next_card and qa:
self._next_card.answer()
return self._next_card

def reset(self) -> None:
self._next_card = None
self._updateCutoff()
self._resetLrn()
self._resetRev()
self._resetNew()
self._haveQueues = True

def set_current_card(self, card: Card):
"""card -- it and its sibling won't be put in queue nor scheduled as next card"""
self._current_card = card
if card is None:
return
self._burySiblings(card)

def _current_card_nid(self):
if self._current_card is None:
return 0
else:
return self._current_card.nid

def answerCard(self, card: Card, ease: int) -> None:
self.col.log()
assert 1 <= ease <= 4
Expand Down Expand Up @@ -389,8 +423,9 @@ def _fillNew(self) -> Optional[bool]:
# fill the queue with the current did
self._newQueue = self.col.db.list(
f"""
select id from cards where did = ? and queue = {QUEUE_TYPE_NEW} order by due,ord limit ?""",
select id from cards where did = ? and queue = {QUEUE_TYPE_NEW} and nid != ? order by due,ord limit ?""",
did,
self._current_card_nid(),
lim,
)
if self._newQueue:
Expand Down Expand Up @@ -542,10 +577,11 @@ def _fillLrn(self) -> Union[bool, List[Any]]:
self._lrnQueue = self.col.db.all( # type: ignore
f"""
select due, id from cards where
did in %s and queue in ({QUEUE_TYPE_LRN},{QUEUE_TYPE_PREVIEW}) and due < ?
did in %s and queue in ({QUEUE_TYPE_LRN},{QUEUE_TYPE_PREVIEW}) and due < ? and nid != ?
limit %d"""
% (self._deckLimit(), self.reportLimit),
cutoff,
self._current_card_nid(),
)
for i in range(len(self._lrnQueue)):
self._lrnQueue[i] = (self._lrnQueue[i][0], self._lrnQueue[i][1])
Expand Down Expand Up @@ -578,9 +614,10 @@ def _fillLrnDay(self) -> Optional[bool]:
self._lrnDayQueue = self.col.db.list(
f"""
select id from cards where
did = ? and queue = {QUEUE_TYPE_DAY_LEARN_RELEARN} and due <= ? limit ?""",
did = ? and queue = {QUEUE_TYPE_DAY_LEARN_RELEARN} and due <= ? and nid != ? limit ?""",
did,
self.today,
self._current_card_nid(),
self.queueLimit,
)
if self._lrnDayQueue:
Expand Down Expand Up @@ -912,11 +949,12 @@ def _fillRev(self) -> Any:
self._revQueue = self.col.db.list(
f"""
select id from cards where
did in %s and queue = {QUEUE_TYPE_REV} and due <= ?
did in %s and queue = {QUEUE_TYPE_REV} and due <= ? and nid != ?
order by due, random()
limit ?"""
% self._deckLimit(),
self.today,
self._current_card_nid(),
lim,
)

Expand Down Expand Up @@ -1695,8 +1733,18 @@ def unburyCardsForDeck(self, type: str = "all") -> None:
# Sibling spacing
##########################################################################

def _actual_bury_siblings(self, bury: bool, toBury: List[int], cid: int, queue: List[int]):
if bury:
toBury.append(cid)
try:
queue.remove(cid)
except ValueError:
pass
if self._next_card and self._next_card.id == cid:
self._next_card = None

def _burySiblings(self, card: Card) -> None:
toBury = []
toBury : List[int] = []
nconf = self._newConf(card)
buryNew = nconf.get("bury", True)
rconf = self._revConf(card)
Expand All @@ -1711,21 +1759,9 @@ def _burySiblings(self, card: Card) -> None:
self.today,
):
if queue == QUEUE_TYPE_REV:
if buryRev:
toBury.append(cid)
# if bury disabled, we still discard to give same-day spacing
try:
self._revQueue.remove(cid)
except ValueError:
pass
self._actual_bury_siblings(buryRev, toBury, cid, self._revQueue)
else:
# if bury disabled, we still discard to give same-day spacing
if buryNew:
toBury.append(cid)
try:
self._newQueue.remove(cid)
except ValueError:
pass
self._actual_bury_siblings(buryNew, toBury, cid, self._newQueue)
# then bury
if toBury:
self.buryCards(toBury, manual=False)
Expand Down
3 changes: 3 additions & 0 deletions qt/aqt/reviewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,15 @@ def nextCard(self) -> None:
c = self.mw.col.sched.getCard()
self.card = c
if not c:
self.mw.col.sched.set_current_card(None)
self.mw.moveToState("overview")
return
if self._reps is None or self._reps % 100 == 0:
# we recycle the webview periodically so webkit can free memory
self._initWeb()
self._showQuestion()
self.mw.col.sched.set_current_card(self.card)
self.mw.col.sched.load_next_card(True)

# Audio
##########################################################################
Expand Down