mirror of
https://github.com/ankitects/anki.git
synced 2025-09-21 07:22:23 -04:00
rewrite groupCounts()
Instead of collecting the exact number of cards, we just record whether a group has any reviews or new cards. By not needing to calculate the exact numbers, it runs a lot faster than before. Also, changed the group code to ensure parents are automatically created when a group is added.
This commit is contained in:
parent
de8a5b69ed
commit
28d045feef
3 changed files with 55 additions and 38 deletions
|
@ -94,8 +94,9 @@ class GroupManager(object):
|
|||
# if it's a top level group, it gets the top level config
|
||||
g = defaultTopConf.copy()
|
||||
else:
|
||||
# not top level. calling code should ensure parents already exist?
|
||||
# not top level; ensure all parents exist
|
||||
g = {}
|
||||
self._ensureParents(name)
|
||||
g['name'] = name
|
||||
g['conf'] = 1
|
||||
while 1:
|
||||
|
@ -122,6 +123,16 @@ class GroupManager(object):
|
|||
"A list of all groups."
|
||||
return self.groups.values()
|
||||
|
||||
def _ensureParents(self, name):
|
||||
path = name.split("::")
|
||||
s = ""
|
||||
for p in path[:-1]:
|
||||
if not s:
|
||||
s += p
|
||||
else:
|
||||
s += "::" + p
|
||||
self.id(s)
|
||||
|
||||
# Group utils
|
||||
#############################################################
|
||||
|
||||
|
@ -164,8 +175,7 @@ class GroupManager(object):
|
|||
return
|
||||
# save the top level group
|
||||
name = self.groups[str(gid)]['name']
|
||||
path = name.split("::")
|
||||
self.deck.conf['topGroup'] = self.id(path[0])
|
||||
self.deck.conf['topGroup'] = self.topFor(name)
|
||||
# current group
|
||||
self.deck.conf['curGroup'] = gid
|
||||
# and active groups (current + all children)
|
||||
|
@ -174,3 +184,8 @@ class GroupManager(object):
|
|||
if g['name'].startswith(name + "::"):
|
||||
actv.append(g['id'])
|
||||
self.deck.conf['activeGroups'] = actv
|
||||
|
||||
def topFor(self, name):
|
||||
"The top level gid for NAME."
|
||||
path = name.split("::")
|
||||
return self.id(path[0])
|
||||
|
|
|
@ -108,15 +108,28 @@ order by due""" % self._groupLimit(),
|
|||
##########################################################################
|
||||
|
||||
def groupCounts(self):
|
||||
"Returns [groupname, cards, due, new]"
|
||||
"Returns [groupname, hasDue, hasNew]"
|
||||
# find groups with 1 or more due cards
|
||||
gids = {}
|
||||
for (gid, all, rev, new) in self.deck.db.execute("""
|
||||
select gid, count(),
|
||||
sum(case when queue = 2 and due <= ? then 1 else 0 end),
|
||||
sum(case when queue = 0 then 1 else 0 end)
|
||||
from cards group by gid""", self.today):
|
||||
gids[gid] = [all, rev, new]
|
||||
return [[grp['name'], int(gid)]+gids.get(int(gid), [0, 0, 0])
|
||||
for g in self.deck.groups.all():
|
||||
hasDue = self.deck.db.scalar("""
|
||||
select 1 from cards where gid = ? and
|
||||
((queue = 2 and due <= ?) or (queue = 1 and due < ?)) limit 1""",
|
||||
g['id'], self.today, intTime())
|
||||
top = self.deck.groups.get(
|
||||
self.deck.groups.topFor(g['name']))
|
||||
if top['newToday'][0] != self.today:
|
||||
# it's a new day; reset counts
|
||||
top['newToday'] = [self.today, 0]
|
||||
hasNew = max(0, top['newPerDay'] - top['newToday'][1])
|
||||
if hasNew:
|
||||
# if the limit hasn't run out, check to see if there are
|
||||
# actually cards
|
||||
hasNew = self.deck.db.scalar(
|
||||
"select 1 from cards where queue = 0 and gid = ? limit 1",
|
||||
g['id'])
|
||||
gids[g['id']] = [hasDue or 0, hasNew or 0]
|
||||
return [[grp['name'], int(gid)]+gids.get(int(gid))
|
||||
for (gid, grp) in self._orderedGroups()]
|
||||
|
||||
def _orderedGroups(self):
|
||||
|
@ -145,7 +158,6 @@ from cards group by gid""", self.today):
|
|||
for (head, tail) in itertools.groupby(grps, key=key):
|
||||
tail = list(tail)
|
||||
gid = None
|
||||
all = 0
|
||||
rev = 0
|
||||
new = 0
|
||||
children = []
|
||||
|
@ -153,9 +165,8 @@ from cards group by gid""", self.today):
|
|||
if len(c[0]) == 1:
|
||||
# current node
|
||||
gid = c[1]
|
||||
all += c[2]
|
||||
rev += c[3]
|
||||
new += c[4]
|
||||
rev += c[2]
|
||||
new += c[3]
|
||||
else:
|
||||
# set new string to tail
|
||||
c[0] = c[0][1]
|
||||
|
@ -163,10 +174,9 @@ from cards group by gid""", self.today):
|
|||
children = self._groupChildren(children)
|
||||
# tally up children counts
|
||||
for ch in children:
|
||||
all += ch[2]
|
||||
rev += ch[3]
|
||||
new += ch[4]
|
||||
tree.append((head, gid, all, rev, new, children))
|
||||
rev += ch[2]
|
||||
new += ch[3]
|
||||
tree.append((head, gid, rev, new, children))
|
||||
return tuple(tree)
|
||||
|
||||
# Getting the next card
|
||||
|
|
|
@ -695,32 +695,24 @@ def test_groupCounts():
|
|||
d.addFact(f)
|
||||
d.reset()
|
||||
assert d.sched.counts() == (3, 0, 1)
|
||||
assert len(d.groups.groups) == 4
|
||||
assert len(d.groups.groups) == 5
|
||||
cnts = d.sched.groupCounts()
|
||||
assert cnts[0] == ["Default", 1, 1, 0, 1]
|
||||
assert cnts[1] == ["Default::1", default1, 1, 1, 0]
|
||||
assert cnts[2] == ["foo::bar", foobar, 1, 0, 1]
|
||||
assert cnts[3] == ["foo::baz", foobaz, 1, 0, 1]
|
||||
assert cnts[0] == ["Default", 1, 0, 1]
|
||||
assert cnts[1] == ["Default::1", default1, 1, 0]
|
||||
assert cnts[2] == ["foo", d.groups.id("foo"), 0, 0]
|
||||
assert cnts[3] == ["foo::bar", foobar, 0, 1]
|
||||
assert cnts[4] == ["foo::baz", foobaz, 0, 1]
|
||||
tree = d.sched.groupCountTree()
|
||||
assert tree[0][0] == "Default"
|
||||
# sum of child and parent
|
||||
assert tree[0][1] == 1
|
||||
assert tree[0][2] == 2
|
||||
assert tree[0][2] == 1
|
||||
assert tree[0][3] == 1
|
||||
assert tree[0][4] == 1
|
||||
# child count is just review
|
||||
assert tree[0][5][0][0] == "1"
|
||||
assert tree[0][5][0][1] == default1
|
||||
assert tree[0][5][0][2] == 1
|
||||
assert tree[0][5][0][3] == 1
|
||||
assert tree[0][5][0][4] == 0
|
||||
# event if parent group didn't exist, it should have been created with a
|
||||
# counts summary, with an empty gid
|
||||
assert tree[1][0] == "foo"
|
||||
assert tree[1][1] == None
|
||||
assert tree[1][2] == 2
|
||||
assert tree[1][3] == 0
|
||||
assert tree[1][4] == 2
|
||||
assert tree[0][4][0][0] == "1"
|
||||
assert tree[0][4][0][1] == default1
|
||||
assert tree[0][4][0][2] == 1
|
||||
assert tree[0][4][0][3] == 0
|
||||
|
||||
def test_reorder():
|
||||
d = getEmptyDeck()
|
||||
|
|
Loading…
Reference in a new issue