mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
refactor single_card_revlog_to_item(s)
This commit is contained in:
parent
e04b382666
commit
e6e7a58300
2 changed files with 29 additions and 46 deletions
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue