Clear memory state when user disables FSRS

This commit is contained in:
Damien Elmes 2023-09-17 10:55:59 +10:00
parent 75de1f9709
commit 25d5e56397
2 changed files with 19 additions and 12 deletions

View file

@ -204,7 +204,7 @@ impl Collection {
.map(|c| c.inner.fsrs_enabled) .map(|c| c.inner.fsrs_enabled)
.unwrap_or_default(); .unwrap_or_default();
let current_weights = current_config.map(|c| &c.inner.fsrs_weights); let current_weights = current_config.map(|c| &c.inner.fsrs_weights);
if current_fsrs_on && (!previous_fsrs_on || previous_weights != current_weights) { if current_fsrs_on != previous_fsrs_on || previous_weights != current_weights {
decks_needing_memory_recompute decks_needing_memory_recompute
.entry(current_config_id) .entry(current_config_id)
.or_default() .or_default()
@ -216,15 +216,16 @@ impl Collection {
} }
if !decks_needing_memory_recompute.is_empty() { if !decks_needing_memory_recompute.is_empty() {
let input: Vec<(Weights, Vec<SearchNode>)> = decks_needing_memory_recompute let input: Vec<(Option<Weights>, Vec<SearchNode>)> = decks_needing_memory_recompute
.into_iter() .into_iter()
.map(|(conf_id, search)| { .map(|(conf_id, search)| {
let weights = configs_after_update let weights = configs_after_update.get(&conf_id).and_then(|c| {
.get(&conf_id) if c.inner.fsrs_enabled {
.or_not_found(conf_id)? Some(c.inner.fsrs_weights.clone())
.inner } else {
.fsrs_weights None
.clone(); }
});
Ok((weights, search)) Ok((weights, search))
}) })
.collect::<Result<_>>()?; .collect::<Result<_>>()?;

View file

@ -21,9 +21,11 @@ impl Collection {
/// For each provided set of weights, locate cards with the provided search, /// For each provided set of weights, locate cards with the provided search,
/// and update their memory state. /// and update their memory state.
/// Should be called inside a transaction. /// Should be called inside a transaction.
/// If Weights are None, it means the user disabled FSRS, and the existing
/// memory state should be removed.
pub(crate) fn update_memory_state( pub(crate) fn update_memory_state(
&mut self, &mut self,
entries: Vec<(Weights, Vec<SearchNode>)>, entries: Vec<(Option<Weights>, Vec<SearchNode>)>,
) -> Result<()> { ) -> Result<()> {
let timing = self.timing_today()?; let timing = self.timing_today()?;
let usn = self.usn()?; let usn = self.usn()?;
@ -32,15 +34,19 @@ impl Collection {
.and(SearchNode::State(StateKind::New).negated()); .and(SearchNode::State(StateKind::New).negated());
let revlog = self.revlog_for_srs(search)?; let revlog = self.revlog_for_srs(search)?;
let items = fsrs_items_for_memory_state(revlog, timing.next_day_at); let items = fsrs_items_for_memory_state(revlog, timing.next_day_at);
let fsrs = FSRS::new(Some(&weights))?; let fsrs = FSRS::new(weights.as_deref())?;
let mut progress = self.new_progress_handler::<ComputeMemoryProgress>(); let mut progress = self.new_progress_handler::<ComputeMemoryProgress>();
progress.update(false, |s| s.total_cards = items.len() as u32)?; progress.update(false, |s| s.total_cards = items.len() as u32)?;
for (idx, (card_id, item)) in items.into_iter().enumerate() { for (idx, (card_id, item)) in items.into_iter().enumerate() {
progress.update(true, |state| state.current_cards = idx as u32 + 1)?; progress.update(true, |state| state.current_cards = idx as u32 + 1)?;
let state = fsrs.memory_state(item);
let mut card = self.storage.get_card(card_id)?.or_not_found(card_id)?; let mut card = self.storage.get_card(card_id)?.or_not_found(card_id)?;
let original = card.clone(); let original = card.clone();
if weights.is_some() {
let state = fsrs.memory_state(item);
card.memory_state = Some(state.into()); card.memory_state = Some(state.into());
} else {
card.memory_state = None;
}
self.update_card_inner(&mut card, original, usn)?; self.update_card_inner(&mut card, original, usn)?;
} }
} }