diff --git a/proto/anki/decks.proto b/proto/anki/decks.proto index 4d56ee334..6bc7159a5 100644 --- a/proto/anki/decks.proto +++ b/proto/anki/decks.proto @@ -126,7 +126,6 @@ message AddOrUpdateDeckLegacyRequest { message DeckTreeRequest { // if non-zero, counts for the provided timestamp will be included int64 now = 1; - int64 top_deck_id = 2; } message DeckTreeNode { diff --git a/pylib/anki/decks.py b/pylib/anki/decks.py index fd528a8fd..6c540ae5a 100644 --- a/pylib/anki/decks.py +++ b/pylib/anki/decks.py @@ -174,7 +174,7 @@ class DeckManager(DeprecatedNamesMixin): return deck def deck_tree(self) -> DeckTreeNode: - return self.col._backend.deck_tree(top_deck_id=0, now=0) + return self.col._backend.deck_tree(now=0) @classmethod def find_deck_in_tree( diff --git a/pylib/anki/scheduler/base.py b/pylib/anki/scheduler/base.py index 39e3e1fe9..1fcdb746c 100644 --- a/pylib/anki/scheduler/base.py +++ b/pylib/anki/scheduler/base.py @@ -49,10 +49,13 @@ class SchedulerBase(DeprecatedNamesMixin): # Deck list ########################################################################## - def deck_due_tree(self, top_deck_id: int = 0) -> DeckTreeNode: + def deck_due_tree(self, top_deck_id: DeckId | None = None) -> DeckTreeNode | None: """Returns a tree of decks with counts. - If top_deck_id provided, counts are limited to that node.""" - return self.col._backend.deck_tree(top_deck_id=top_deck_id, now=int_time()) + If top_deck_id provided, only the according subtree is returned.""" + tree = self.col._backend.deck_tree(now=int_time()) + if top_deck_id: + return self.col.decks.find_deck_in_tree(tree, top_deck_id) + return tree # Deck finished state & custom study ########################################################################## diff --git a/pylib/anki/scheduler/v2.py b/pylib/anki/scheduler/v2.py index dd351782a..5918e2f17 100644 --- a/pylib/anki/scheduler/v2.py +++ b/pylib/anki/scheduler/v2.py @@ -85,8 +85,7 @@ class Scheduler(SchedulerBaseWithLegacy): self._haveQueues = True def _reset_counts(self) -> None: - tree = self.deck_due_tree(self._current_deck_id) - node = self.col.decks.find_deck_in_tree(tree, self._current_deck_id) + node = self.deck_due_tree(self._current_deck_id) if not node: # current deck points to a missing deck self.newCount = 0 diff --git a/qt/aqt/overview.py b/qt/aqt/overview.py index c65318d7e..c4c718803 100644 --- a/qt/aqt/overview.py +++ b/qt/aqt/overview.py @@ -222,8 +222,7 @@ class Overview: def _table(self) -> str | None: counts = list(self.mw.col.sched.counts()) current_did = self.mw.col.decks.get_current_id() - deck_tree = self.mw.col.sched.deck_due_tree(current_did) - deck_node = self.mw.col.decks.find_deck_in_tree(deck_tree, current_did) + deck_node = self.mw.col.sched.deck_due_tree(current_did) but = self.mw.button buried_new = deck_node.new_count - counts[0] diff --git a/rslib/src/backend/decks.rs b/rslib/src/backend/decks.rs index 08a7935ef..93d9e8695 100644 --- a/rslib/src/backend/decks.rs +++ b/rslib/src/backend/decks.rs @@ -42,18 +42,13 @@ impl DecksService for Backend { } fn deck_tree(&self, input: pb::DeckTreeRequest) -> Result { - let lim = if input.top_deck_id > 0 { - Some(DeckId(input.top_deck_id)) - } else { - None - }; self.with_col(|col| { let now = if input.now == 0 { None } else { Some(TimestampSecs(input.now)) }; - col.deck_tree(now, lim) + col.deck_tree(now) }) } diff --git a/rslib/src/decks/counts.rs b/rslib/src/decks/counts.rs index c2b84ca10..1d86805dd 100644 --- a/rslib/src/decks/counts.rs +++ b/rslib/src/decks/counts.rs @@ -34,14 +34,9 @@ impl Collection { &mut self, days_elapsed: u32, learn_cutoff: u32, - limit_to: Option<&str>, ) -> Result> { - self.storage.due_counts( - self.scheduler_version(), - days_elapsed, - learn_cutoff, - limit_to, - ) + self.storage + .due_counts(self.scheduler_version(), days_elapsed, learn_cutoff) } pub(crate) fn counts_for_deck_today( diff --git a/rslib/src/decks/tree.rs b/rslib/src/decks/tree.rs index 3f910c2be..9979c598b 100644 --- a/rslib/src/decks/tree.rs +++ b/rslib/src/decks/tree.rs @@ -287,14 +287,7 @@ impl Collection { /// - Buried cards from previous days will be unburied if necessary. Because /// this does not happen for future stamps, future due numbers may not be /// accurate. - /// - If top_deck_id is provided, only the node starting at the provided - /// deck ID will have the counts populated. Currently the entire tree is - /// returned in this case, but this may change in the future. - pub fn deck_tree( - &mut self, - timestamp: Option, - top_deck_id: Option, - ) -> Result { + pub fn deck_tree(&mut self, timestamp: Option) -> Result { let names = self.storage.get_all_deck_names()?; let mut tree = deck_names_to_tree(names.into_iter()); @@ -311,14 +304,12 @@ impl Collection { let timing_today = self.timing_today()?; self.unbury_if_day_rolled_over(timing_today)?; - let limit = top_deck_id - .and_then(|did| decks_map.get(&did).map(|deck| deck.name.as_native_str())); let timing_at_stamp = self.timing_for_timestamp(timestamp)?; let days_elapsed = timing_at_stamp.days_elapsed; let learn_cutoff = (timestamp.0 as u32) + self.learn_ahead_secs(); let sched_ver = self.scheduler_version(); let v3 = self.get_config_bool(BoolKey::Sched2021); - let counts = self.due_counts(days_elapsed, learn_cutoff, limit)?; + let counts = self.due_counts(days_elapsed, learn_cutoff)?; let dconf = self.storage.get_deck_config_map()?; add_counts(&mut tree, &counts); let limits = remaining_limits_map(decks_map.values(), &dconf, days_elapsed, v3); @@ -338,7 +329,7 @@ impl Collection { pub fn current_deck_tree(&mut self) -> Result> { let target = self.get_current_deck_id(); - let tree = self.deck_tree(Some(TimestampSecs::now()), Some(target))?; + let tree = self.deck_tree(Some(TimestampSecs::now()))?; Ok(get_subnode(tree, target)) } @@ -365,7 +356,7 @@ impl Collection { impl Collection { pub(crate) fn legacy_deck_tree(&mut self) -> Result { - let tree = self.deck_tree(Some(TimestampSecs::now()), None)?; + let tree = self.deck_tree(Some(TimestampSecs::now()))?; Ok(LegacyDueCounts::from(tree)) } @@ -404,7 +395,7 @@ mod test { col.get_or_create_normal_deck("2::c::A")?; col.get_or_create_normal_deck("3")?; - let tree = col.deck_tree(None, None)?; + let tree = col.deck_tree(None)?; assert_eq!(tree.children.len(), 3); @@ -427,7 +418,7 @@ mod test { col.storage.remove_deck(col.get_deck_id("2")?.unwrap())?; col.storage.remove_deck(col.get_deck_id("2::3")?.unwrap())?; - let tree = col.deck_tree(None, None)?; + let tree = col.deck_tree(None)?; assert_eq!(tree.children.len(), 1); Ok(()) @@ -446,7 +437,7 @@ mod test { note.set_field(0, "{{c1::}} {{c2::}} {{c3::}} {{c4::}}")?; col.add_note(&mut note, child_deck.id)?; - let tree = col.deck_tree(Some(TimestampSecs::now()), None)?; + let tree = col.deck_tree(Some(TimestampSecs::now()))?; assert_eq!(tree.children[0].new_count, 4); assert_eq!(tree.children[0].children[0].new_count, 4); @@ -457,7 +448,7 @@ mod test { col.add_or_update_deck(&mut parent_deck)?; // with the default limit of 20, there should still be 4 due - let tree = col.deck_tree(Some(TimestampSecs::now()), None)?; + let tree = col.deck_tree(Some(TimestampSecs::now()))?; assert_eq!(tree.children[0].new_count, 4); assert_eq!(tree.children[0].children[0].new_count, 4); @@ -466,7 +457,7 @@ mod test { conf.inner.new_per_day = 4; col.add_or_update_deck_config(&mut conf)?; - let tree = col.deck_tree(Some(TimestampSecs::now()), None)?; + let tree = col.deck_tree(Some(TimestampSecs::now()))?; assert_eq!(tree.children[0].new_count, 3); assert_eq!(tree.children[0].children[0].new_count, 3); @@ -505,7 +496,7 @@ mod test { note.id.0 = 0; col.add_note(&mut note, grandchild_2.id)?; - let parent = &col.deck_tree(Some(TimestampSecs::now()), None)?.children[0]; + let parent = &col.deck_tree(Some(TimestampSecs::now()))?.children[0]; // grandchildren: own cards, limited by own new limits assert_eq!(parent.children[0].children[0].new_count, 2); assert_eq!(parent.children[0].children[1].new_count, 1); diff --git a/rslib/src/scheduler/answering/mod.rs b/rslib/src/scheduler/answering/mod.rs index 4baf57b67..04924a365 100644 --- a/rslib/src/scheduler/answering/mod.rs +++ b/rslib/src/scheduler/answering/mod.rs @@ -579,7 +579,7 @@ mod test { macro_rules! assert_counts { ($col:ident, $new:expr, $learn:expr, $review:expr) => {{ - let tree = $col.deck_tree(Some(TimestampSecs::now()), None).unwrap(); + let tree = $col.deck_tree(Some(TimestampSecs::now())).unwrap(); assert_eq!(tree.new_count, $new); assert_eq!(tree.learn_count, $learn); assert_eq!(tree.review_count, $review); diff --git a/rslib/src/storage/deck/mod.rs b/rslib/src/storage/deck/mod.rs index 698b1b09f..da1c5d0f7 100644 --- a/rslib/src/storage/deck/mod.rs +++ b/rslib/src/storage/deck/mod.rs @@ -265,10 +265,9 @@ impl SqliteStorage { sched: SchedulerVersion, day_cutoff: u32, learn_cutoff: u32, - top_deck: Option<&str>, ) -> Result> { let sched_ver = sched as u8; - let mut params = named_params! { + let params = named_params! { ":new_queue": CardQueue::New as u8, ":review_queue": CardQueue::Review as u8, ":day_cutoff": day_cutoff, @@ -279,30 +278,7 @@ impl SqliteStorage { ":preview_queue": CardQueue::PreviewRepeat as u8, } .to_vec(); - - let sql; - let prefix_start; - let prefix_end; - let top; - if let Some(top_inner) = top_deck { - // limited to deck node - top = top_inner; - prefix_start = format!("{}\x1f", top); - prefix_end = format!("{}\x20", top); - params.extend(named_params! { - ":top_deck": top, - ":prefix_start": prefix_start, - ":prefix_end": prefix_end, - }); - sql = concat!( - include_str!("due_counts.sql"), - " where did in (select id from decks where name = :top_deck ", - "or (name >= :prefix_start and name < :prefix_end)) group by did " - ); - } else { - // entire tree - sql = concat!(include_str!("due_counts.sql"), " group by did"); - } + let sql = concat!(include_str!("due_counts.sql"), " group by did"); self.db .prepare_cached(sql)?