move other queue variables into qconf; discard old selective study

This commit is contained in:
Damien Elmes 2011-03-03 02:15:19 +09:00
parent b3ee91a9d5
commit 4c931e0ff4
3 changed files with 31 additions and 38 deletions

View file

@ -29,26 +29,23 @@ import anki.latex # sets up hook
# ensure all the DB metadata in other files is loaded before proceeding # ensure all the DB metadata in other files is loaded before proceeding
import anki.models, anki.facts, anki.cards, anki.media, anki.groups, anki.graves import anki.models, anki.facts, anki.cards, anki.media, anki.groups, anki.graves
# Selective study and new card limits. These vars are necessary to determine # Settings related to queue building. These may be loaded without the rest of
# counts even on a minimum deck load, and thus are separate from the rest of # the config to check due counts faster on mobile clients.
# the config. defaultQconf = {
defaultLim = {
'newActive': u"", 'newActive': u"",
'newInactive': u"", 'newInactive': u"",
'revActive': u"", 'revActive': u"",
'revInactive': u"", 'revInactive': u"",
'newPerDay': 20, 'newPerDay': 20,
# currentDay, count 'newToday': [0, 0], # currentDay, count
'newToday': [0, 0],
'newTodayOrder': NEW_TODAY_ORDINAL, 'newTodayOrder': NEW_TODAY_ORDINAL,
'newCardOrder': 1,
'newCardSpacing': NEW_CARDS_DISTRIBUTE,
'revCardOrder': REV_CARDS_OLD_FIRST,
} }
# scheduling and other options # scheduling and other options
defaultConf = { defaultConf = {
'utcOffset': -2,
'newCardOrder': 1,
'newCardSpacing': NEW_CARDS_DISTRIBUTE,
'revCardOrder': REV_CARDS_OLD_FIRST,
'collapseTime': 600, 'collapseTime': 600,
'sessionRepLimit': 0, 'sessionRepLimit': 0,
'sessionTimeLimit': 600, 'sessionTimeLimit': 600,
@ -78,8 +75,8 @@ deckTable = Table(
Column('syncName', UnicodeText, nullable=False, default=u""), Column('syncName', UnicodeText, nullable=False, default=u""),
Column('lastSync', Integer, nullable=False, default=0), Column('lastSync', Integer, nullable=False, default=0),
Column('utcOffset', Integer, nullable=False, default=-2), Column('utcOffset', Integer, nullable=False, default=-2),
Column('limits', UnicodeText, nullable=False, default=unicode( Column('qconf', UnicodeText, nullable=False, default=unicode(
simplejson.dumps(defaultLim))), simplejson.dumps(defaultQconf))),
Column('config', UnicodeText, nullable=False, default=unicode( Column('config', UnicodeText, nullable=False, default=unicode(
simplejson.dumps(defaultConf))), simplejson.dumps(defaultConf))),
Column('data', UnicodeText, nullable=False, default=u"{}") Column('data', UnicodeText, nullable=False, default=u"{}")
@ -144,7 +141,7 @@ interval=0, due=created, factor=2.5, reps=0, successive=0, lapses=0, flags=0"""
sql2 += " where cardId in "+sids sql2 += " where cardId in "+sids
self.db.statement(sql, now=time.time()) self.db.statement(sql, now=time.time())
self.db.statement(sql2) self.db.statement(sql2)
if self.config['newCardOrder'] == NEW_CARDS_RANDOM: if self.qconf['newCardOrder'] == NEW_CARDS_RANDOM:
# we need to re-randomize now # we need to re-randomize now
self.randomizeNewCards(ids) self.randomizeNewCards(ids)
self.flushMod() self.flushMod()
@ -435,7 +432,7 @@ due > :now and due < :now""", now=time.time())
self.db.save(fact) self.db.save(fact)
# update field cache # update field cache
self.flushMod() self.flushMod()
isRandom = self.config['newCardOrder'] == NEW_CARDS_RANDOM isRandom = self.qconf['newCardOrder'] == NEW_CARDS_RANDOM
if isRandom: if isRandom:
due = random.uniform(0, time.time()) due = random.uniform(0, time.time())
t = time.time() t = time.time()
@ -2148,7 +2145,7 @@ Return new path, relative to media dir."""
def flushConfig(self): def flushConfig(self):
print "make flushConfig() more intelligent" print "make flushConfig() more intelligent"
self._config = unicode(simplejson.dumps(self.config)) self._config = unicode(simplejson.dumps(self.config))
self._limits = unicode(simplejson.dumps(self.limits)) self._qconf = unicode(simplejson.dumps(self.qconf))
self._data = unicode(simplejson.dumps(self.data)) self._data = unicode(simplejson.dumps(self.data))
def close(self): def close(self):
@ -2634,9 +2631,9 @@ seq > :s and seq <= :e order by seq desc""", s=start, e=end)
def updateDynamicIndices(self): def updateDynamicIndices(self):
# determine required columns # determine required columns
required = [] required = []
if self.limits['newTodayOrder'] == NEW_TODAY_ORDINAL: if self.qconf['newTodayOrder'] == NEW_TODAY_ORDINAL:
required.append("ordinal") required.append("ordinal")
if self.config['revCardOrder'] in (REV_CARDS_OLD_FIRST, REV_CARDS_NEW_FIRST): if self.qconf['revCardOrder'] in (REV_CARDS_OLD_FIRST, REV_CARDS_NEW_FIRST):
required.append("interval") required.append("interval")
cols = ["queue", "due", "groupId"] + required cols = ["queue", "due", "groupId"] + required
# update if changed # update if changed
@ -2652,7 +2649,7 @@ seq > :s and seq <= :e order by seq desc""", s=start, e=end)
self.db.statement("analyze") self.db.statement("analyze")
mapper(Deck, deckTable, properties={ mapper(Deck, deckTable, properties={
'_limits': deckTable.c.limits, '_qconf': deckTable.c.qconf,
'_config': deckTable.c.config, '_config': deckTable.c.config,
'_data': deckTable.c.data, '_data': deckTable.c.data,
}) })
@ -2831,7 +2828,7 @@ confId integer not null)"""
create = not os.path.exists(path) create = not os.path.exists(path)
deck = DeckStorage._getDeck(path, create, pool) deck = DeckStorage._getDeck(path, create, pool)
oldMod = deck.modified oldMod = deck.modified
deck.limits = simplejson.loads(deck._limits) deck.qconf = simplejson.loads(deck._qconf)
deck.config = simplejson.loads(deck._config) deck.config = simplejson.loads(deck._config)
deck.data = simplejson.loads(deck._data) deck.data = simplejson.loads(deck._data)
if minimal: if minimal:

View file

@ -92,7 +92,7 @@ class Scheduler(object):
# need to keep track of reps for timebox and new card introduction # need to keep track of reps for timebox and new card introduction
def resetNew(self): def resetNew(self):
l = self.deck.limits l = self.deck.qconf
if l['newToday'][0] != self.today: if l['newToday'][0] != self.today:
# it's a new day; reset counts # it's a new day; reset counts
l['newToday'] = [self.today, 0] l['newToday'] = [self.today, 0]
@ -114,10 +114,10 @@ queue = 2 %s order by due limit %d""" % (self.newOrder(), self.groupLimit('new')
return self.newQueue.pop()[0] return self.newQueue.pop()[0]
def newOrder(self): def newOrder(self):
return (",ordinal", "")[self.deck.limits['newTodayOrder']] return (",ordinal", "")[self.deck.qconf['newTodayOrder']]
def updateNewCardRatio(self): def updateNewCardRatio(self):
if self.deck.config['newCardSpacing'] == NEW_CARDS_DISTRIBUTE: if self.deck.qconf['newCardSpacing'] == NEW_CARDS_DISTRIBUTE:
if self.newCount: if self.newCount:
self.newCardModulus = ( self.newCardModulus = (
(self.newCount + self.revCount) / self.newCount) (self.newCount + self.revCount) / self.newCount)
@ -131,9 +131,9 @@ queue = 2 %s order by due limit %d""" % (self.newOrder(), self.groupLimit('new')
"True if it's time to display a new card when distributing." "True if it's time to display a new card when distributing."
if not self.newCount: if not self.newCount:
return False return False
if self.deck.config['newCardSpacing'] == NEW_CARDS_LAST: if self.deck.qconf['newCardSpacing'] == NEW_CARDS_LAST:
return False return False
elif self.deck.config['newCardSpacing'] == NEW_CARDS_FIRST: elif self.deck.qconf['newCardSpacing'] == NEW_CARDS_FIRST:
return True return True
elif self.newCardModulus: elif self.newCardModulus:
return self.deck.reps and self.deck.reps % self.newCardModulus == 0 return self.deck.reps and self.deck.reps % self.newCardModulus == 0
@ -227,13 +227,10 @@ queue = 1 %s and due < :lim order by %s limit %d""" % (
self.fillRevQueue() self.fillRevQueue()
return self.revQueue return self.revQueue
# FIXME: current random order won't work with new spacing
# FIXME: limits for new, config for rev is strange atm
def revOrder(self): def revOrder(self):
return ("interval desc", return ("interval desc",
"interval", "interval",
"due", "due")[self.deck.qconf['revCardOrder']]
"factId, ordinal")[self.deck.config['revCardOrder']]
# FIXME: rewrite # FIXME: rewrite
def showFailedLast(self): def showFailedLast(self):
@ -485,8 +482,8 @@ and queue between 1 and 2""",
return "" return ""
def cardLimit(self, active, inactive, sql): def cardLimit(self, active, inactive, sql):
yes = parseTags(self.deck.limits.get(active)) yes = parseTags(self.deck.qconf.get(active))
no = parseTags(self.deck.limits.get(inactive)) no = parseTags(self.deck.qconf.get(inactive))
if yes: if yes:
yids = tagIds(self.db, yes).values() yids = tagIds(self.db, yes).values()
nids = tagIds(self.db, no).values() nids = tagIds(self.db, no).values()

View file

@ -90,13 +90,12 @@ def migrateDeck(s, engine):
insert into deck select id, created, modified, 0, 99, insert into deck select id, created, modified, 0, 99,
ifnull(syncName, ""), lastSync, utcOffset, "", "", "" from decks""") ifnull(syncName, ""), lastSync, utcOffset, "", "", "" from decks""")
# update selective study # update selective study
lim = deck.defaultLim.copy() qconf = deck.defaultQconf.copy()
# delete old selective study settings, which we can't auto-upgrade easily
keys = ("newActive", "newInactive", "revActive", "revInactive") keys = ("newActive", "newInactive", "revActive", "revInactive")
for k in keys: for k in keys:
lim[k] = s.execute("select value from deckVars where key=:k",
{'k':k}).scalar()
s.execute("delete from deckVars where key=:k", {'k':k}) s.execute("delete from deckVars where key=:k", {'k':k})
lim['newPerDay'] = s.execute( qconf['newPerDay'] = s.execute(
"select newCardsPerDay from decks").scalar() "select newCardsPerDay from decks").scalar()
# fetch remaining settings from decks table # fetch remaining settings from decks table
conf = deck.defaultConf.copy() conf = deck.defaultConf.copy()
@ -116,8 +115,8 @@ ifnull(syncName, ""), lastSync, utcOffset, "", "", "" from decks""")
data[k] = v data[k] = v
else: else:
conf[k] = v conf[k] = v
s.execute("update deck set limits = :l, config = :c, data = :d", s.execute("update deck set qconf = :l, config = :c, data = :d",
{'l':simplejson.dumps(lim), {'l':simplejson.dumps(qconf),
'c':simplejson.dumps(conf), 'c':simplejson.dumps(conf),
'd':simplejson.dumps(data)}) 'd':simplejson.dumps(data)})
# clean up # clean up
@ -205,8 +204,8 @@ cast(min(thinkingTime, 60)*1000 as int), 0 from reviewHistory""")
deck.db.statement("drop table if exists %sDeleted" % t) deck.db.statement("drop table if exists %sDeleted" % t)
# finally, update indices & optimize # finally, update indices & optimize
updateIndices(deck.db) updateIndices(deck.db)
# setup limits & config for dynamicIndices() # setup qconf & config for dynamicIndices()
deck.limits = simplejson.loads(deck._limits) deck.qconf = simplejson.loads(deck._qconf)
deck.config = simplejson.loads(deck._config) deck.config = simplejson.loads(deck._config)
# add default config # add default config
import deck as deckMod import deck as deckMod