refactor single_card_revlog_to_item(s)

This commit is contained in:
Jarrett Ye 2024-12-15 19:40:57 +08:00
parent e04b382666
commit e6e7a58300
No known key found for this signature in database
GPG key ID: EBFC55E0C1A352BB
2 changed files with 29 additions and 46 deletions

View file

@ -284,20 +284,7 @@ pub(crate) fn single_card_revlog_to_item(
interval: f32,
ease_factor: f32,
}
let first_review = entries
.iter()
// ignore manual and rescheduled revlogs and revlogs before the cutoff
.find(|e| e.button_chosen > 0 && e.id.0 >= ignore_revlogs_before.0)
.map(|e| FirstReview {
interval: e.interval.max(1) as f32,
ease_factor: if e.ease_factor == 0 {
2500
} else {
e.ease_factor
} as f32
/ 1000.0,
});
if let Some((mut items, revlogs_complete, _)) =
if let Some((mut items, revlogs_complete, _, filtered_entries)) =
single_card_revlog_to_items(entries, next_day_at, false, ignore_revlogs_before)
{
let mut item = items.pop().unwrap();
@ -306,7 +293,16 @@ pub(crate) fn single_card_revlog_to_item(
item,
starting_state: None,
}))
} else if let Some(first_review) = first_review {
} else if let Some(first_non_manual_entry) = filtered_entries.first() {
let first_review = FirstReview {
interval: first_non_manual_entry.interval.max(1) as f32,
ease_factor: if first_non_manual_entry.ease_factor == 0 {
2500
} else {
first_non_manual_entry.ease_factor
} as f32
/ 1000.0,
};
// the revlog has been truncated, but not fully
let mut starting_state = fsrs.memory_state_from_sm2(
first_review.ease_factor,
@ -318,14 +314,10 @@ pub(crate) fn single_card_revlog_to_item(
starting_state.difficulty = (first_review.ease_factor - 0.1) * 9.0 + 1.0;
}
item.reviews.remove(0);
if item.reviews.is_empty() {
Ok(None)
} else {
Ok(Some(FsrsItemWithStartingState {
item,
starting_state: Some(starting_state),
}))
}
Ok(Some(FsrsItemWithStartingState {
item,
starting_state: Some(starting_state),
}))
} else {
// only manual and rescheduled revlogs; treat like empty
Ok(None)

View file

@ -258,13 +258,17 @@ pub(crate) fn single_card_revlog_to_items(
next_day_at: TimestampSecs,
training: bool,
ignore_revlogs_before: TimestampMillis,
) -> Option<(Vec<FSRSItem>, bool, usize)> {
) -> Option<(Vec<FSRSItem>, bool, usize, Vec<RevlogEntry>)> {
let mut first_of_last_learn_entries = None;
let mut first_relearn_entries = None;
let mut non_manual_entries = None;
let mut revlogs_complete = false;
for (index, entry) in entries.iter().enumerate().rev() {
if matches!(entry.button_chosen, 1..=4) {
non_manual_entries = Some(entry);
non_manual_entries = Some(index);
if entry.review_kind == RevlogReviewKind::Relearning {
first_relearn_entries = Some(index);
}
}
if matches!(
(entry.review_kind, entry.button_chosen),
@ -295,18 +299,6 @@ pub(crate) fn single_card_revlog_to_items(
}
}
}
if !revlogs_complete {
revlogs_complete = matches!(
entries.first(),
Some(RevlogEntry {
review_kind: RevlogReviewKind::Manual,
..
}) | Some(RevlogEntry {
review_kind: RevlogReviewKind::Rescheduled,
..
})
);
}
if training {
// While training ignore the entire card if the first learning step of the last
// group of learning steps is before the ignore_revlogs_before date
@ -333,14 +325,7 @@ pub(crate) fn single_card_revlog_to_items(
}
}
}
let first_relearn = entries
.iter()
.enumerate()
.find(|(_idx, e)| {
e.id.0 > ignore_revlogs_before.0 && e.review_kind == RevlogReviewKind::Relearning
})
.map(|(idx, _)| idx);
if let Some(idx) = first_of_last_learn_entries.or(first_relearn) {
if let Some(idx) = first_of_last_learn_entries.or(first_relearn_entries) {
// start from the (re)learning step
if idx > 0 {
entries.drain(..idx);
@ -348,6 +333,12 @@ pub(crate) fn single_card_revlog_to_items(
} else if training {
// when training, we ignore cards that don't have any learning steps
return None;
} else if let Some(idx) = non_manual_entries {
// if there are no (re)learning entries but there are non-manual entries,
// we ignore all entries before the first non-manual entry
if idx > 0 {
entries.drain(..idx);
}
}
// Filter out unwanted entries
@ -393,7 +384,7 @@ pub(crate) fn single_card_revlog_to_items(
if items.is_empty() {
None
} else {
Some((items, revlogs_complete, entries.len()))
Some((items, revlogs_complete, entries.len(), entries))
}
}