From c5eaeaa91e52052e4af6c1abacc503ec86af720d Mon Sep 17 00:00:00 2001 From: Jarrett Ye Date: Thu, 31 Jul 2025 18:45:09 +0800 Subject: [PATCH] Implement is_cramming method in RevlogEntry and update scheduling logic This commit adds the `is_cramming` method to the `RevlogEntry` struct, which identifies entries representing cramming operations. The scheduling logic in `params.rs` has been updated to utilize this new method, improving the clarity and maintainability of the code. --- rslib/src/revlog/mod.rs | 12 +++++++++++- rslib/src/scheduler/fsrs/params.rs | 4 ++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/rslib/src/revlog/mod.rs b/rslib/src/revlog/mod.rs index 2cd734b0a..336302eaa 100644 --- a/rslib/src/revlog/mod.rs +++ b/rslib/src/revlog/mod.rs @@ -92,6 +92,16 @@ impl RevlogEntry { self.review_kind == RevlogReviewKind::Manual && self.ease_factor == 0 } + /// Returns true if this entry represents a cramming operation. + /// These entries are created when a card is previewed using + /// [`crate::scheduler::answering::CardStateUpdater::apply_preview_state`]. + /// The `ease_factor` should be 0 because + /// [`crate::scheduler::states::ReviewState::revlog_kind`] returns + /// `RevlogReviewKind::Filtered` when `days_late() < 0`. + pub(crate) fn is_cramming(&self) -> bool { + self.review_kind == RevlogReviewKind::Filtered && self.ease_factor == 0 + } + /// Returns true if the review entry is not manually rescheduled and not /// cramming. Used to filter out entries that shouldn't be considered /// for statistics and scheduling. @@ -99,7 +109,7 @@ impl RevlogEntry { // not rescheduled/set due date/reset self.button_chosen > 0 // not cramming - && (self.review_kind != RevlogReviewKind::Filtered || self.ease_factor != 0) + && !self.is_cramming() } } diff --git a/rslib/src/scheduler/fsrs/params.rs b/rslib/src/scheduler/fsrs/params.rs index 7d556367b..a96062b99 100644 --- a/rslib/src/scheduler/fsrs/params.rs +++ b/rslib/src/scheduler/fsrs/params.rs @@ -394,7 +394,7 @@ pub(crate) fn reviews_for_fsrs( let mut revlogs_complete = false; // Working backwards from the latest review... for (index, entry) in entries.iter().enumerate().rev() { - if entry.review_kind == RevlogReviewKind::Filtered && entry.ease_factor == 0 { + if entry.is_cramming() { continue; } // For incomplete review histories, initial memory state is based on the first @@ -474,7 +474,7 @@ pub(crate) fn reviews_for_fsrs( // set due date, reset or rescheduled (entry.review_kind == RevlogReviewKind::Manual || entry.button_chosen == 0) || // cram - (entry.review_kind == RevlogReviewKind::Filtered && entry.ease_factor == 0) + entry.is_cramming() || // rescheduled (entry.review_kind == RevlogReviewKind::Rescheduled) )