From 15506328e95ed853364759099123c94c7567d214 Mon Sep 17 00:00:00 2001 From: Jarrett Ye Date: Fri, 29 Mar 2024 17:34:26 +0800 Subject: [PATCH] rename sm2 retention to historical retention (#3101) * rename sm2 retention to historical retention * ninja format * keep sm2_retention in DeckConfSchema11 * update wording * Update schema11.rs --- ftl/core/deck-config.ftl | 20 ++++++++++++------ proto/anki/deck_config.proto | 2 +- rslib/src/deckconfig/mod.rs | 9 ++++++-- rslib/src/deckconfig/schema11.rs | 5 +++-- rslib/src/deckconfig/update.rs | 2 +- rslib/src/scheduler/answering/mod.rs | 4 ++-- rslib/src/scheduler/fsrs/memory_state.rs | 26 ++++++++++++------------ ts/deck-options/AdvancedOptions.svelte | 16 ++++++++------- 8 files changed, 50 insertions(+), 34 deletions(-) diff --git a/ftl/core/deck-config.ftl b/ftl/core/deck-config.ftl index ebe58fb9d..9caea6c19 100644 --- a/ftl/core/deck-config.ftl +++ b/ftl/core/deck-config.ftl @@ -350,7 +350,7 @@ deck-config-ignore-before = Ignore reviews before deck-config-optimize-all-tip = You can optimize all presets at once by using the dropdown button next to "Save". deck-config-evaluate-button = Evaluate deck-config-desired-retention = Desired retention -deck-config-sm2-retention = SM2 retention +deck-config-historical-retention = Historical Retention deck-config-smaller-is-better = Smaller numbers indicate a better fit to your review history. deck-config-steps-too-large-for-fsrs = When FSRS is enabled, steps of 1 day or more are not recommended. deck-config-get-params = Get Params @@ -377,11 +377,19 @@ deck-config-desired-retention-tooltip = less frequently, and you will forget more of them. Be conservative when adjusting this - higher values will greatly increase your workload, and lower values can be demoralizing when you forget a lot of material. -deck-config-sm2-retention-tooltip = - If your actual retention before switching to FSRS was significantly different from 0.9, adjusting - this value will allow Anki to better estimate your memory state when it encounters cards that are - missing review logs. Since review logs typically won't be missing unless you explicitly deleted them - to free up space, most users will not need to adjust this. +deck-config-historical-retention-tooltip = + When some of your review history is missing, FSRS needs to fill in the gaps. By default, it will + assume that when you did those old reviews, you remembered 90% of the material. If your old retention + was appreciably higher or lower than 90%, adjusting this option will allow FSRS to better approximate + the missing reviews. + + Your review history may be incomplete for two reasons: + 1. Because you've used the 'ignore reviews before' option. + 2. Because you previously deleted review logs to free up space, or imported material from a different + SRS program. + + The latter is quite rare, so unless you've used the former option, you probably don't need to adjust + this setting. deck-config-weights-tooltip = FSRS parameters affect how cards are scheduled. Anki will start with default parameters. Once you've accumulated 1000+ reviews, you can use the option below to optimize the parameters to best diff --git a/proto/anki/deck_config.proto b/proto/anki/deck_config.proto index 6519d1fea..f44fbb366 100644 --- a/proto/anki/deck_config.proto +++ b/proto/anki/deck_config.proto @@ -157,7 +157,7 @@ message DeckConfig { string ignore_revlogs_before_date = 46; // used for fsrs_reschedule in the past reserved 39; - float sm2_retention = 40; + float historical_retention = 40; string weight_search = 45; bytes other = 255; diff --git a/rslib/src/deckconfig/mod.rs b/rslib/src/deckconfig/mod.rs index fb30353cb..271a3c514 100644 --- a/rslib/src/deckconfig/mod.rs +++ b/rslib/src/deckconfig/mod.rs @@ -75,7 +75,7 @@ const DEFAULT_DECK_CONFIG_INNER: DeckConfigInner = DeckConfigInner { fsrs_weights: vec![], desired_retention: 0.9, other: Vec::new(), - sm2_retention: 0.9, + historical_retention: 0.9, weight_search: String::new(), ignore_revlogs_before_date: String::new(), }; @@ -282,7 +282,12 @@ pub(crate) fn ensure_deck_config_values_valid(config: &mut DeckConfigInner) { 0.7, 0.99, ); - ensure_f32_valid(&mut config.sm2_retention, default.sm2_retention, 0.7, 0.97) + ensure_f32_valid( + &mut config.historical_retention, + default.historical_retention, + 0.7, + 0.97, + ) } fn ensure_f32_valid(val: &mut f32, default: f32, min: f32, max: f32) { diff --git a/rslib/src/deckconfig/schema11.rs b/rslib/src/deckconfig/schema11.rs index 3e0c55263..8775c3442 100644 --- a/rslib/src/deckconfig/schema11.rs +++ b/rslib/src/deckconfig/schema11.rs @@ -86,6 +86,7 @@ pub struct DeckConfSchema11 { #[serde(default = "wait_for_audio_default")] wait_for_audio: bool, #[serde(default)] + /// historical retention sm2_retention: f32, #[serde(default)] weight_search: String, @@ -373,7 +374,7 @@ impl From for DeckConfig { fsrs_weights: c.fsrs_weights, ignore_revlogs_before_date: c.ignore_revlogs_before_date, desired_retention: c.desired_retention, - sm2_retention: c.sm2_retention, + historical_retention: c.sm2_retention, weight_search: c.weight_search, other: other_bytes, }, @@ -479,7 +480,7 @@ impl From for DeckConfSchema11 { bury_interday_learning: i.bury_interday_learning, fsrs_weights: i.fsrs_weights, desired_retention: i.desired_retention, - sm2_retention: i.sm2_retention, + sm2_retention: i.historical_retention, weight_search: i.weight_search, ignore_revlogs_before_date: i.ignore_revlogs_before_date, } diff --git a/rslib/src/deckconfig/update.rs b/rslib/src/deckconfig/update.rs index b1b8417a5..71ffb1105 100644 --- a/rslib/src/deckconfig/update.rs +++ b/rslib/src/deckconfig/update.rs @@ -263,7 +263,7 @@ impl Collection { desired_retention: c.inner.desired_retention, max_interval: c.inner.maximum_review_interval, reschedule: req.fsrs_reschedule, - sm2_retention: c.inner.sm2_retention, + historical_retention: c.inner.historical_retention, }) } else { None diff --git a/rslib/src/scheduler/answering/mod.rs b/rslib/src/scheduler/answering/mod.rs index 6c4d947d2..ecf08625e 100644 --- a/rslib/src/scheduler/answering/mod.rs +++ b/rslib/src/scheduler/answering/mod.rs @@ -382,10 +382,10 @@ impl Collection { &fsrs, revlog, timing.next_day_at, - config.inner.sm2_retention, + config.inner.historical_retention, ignore_revlogs_before_ms_from_config(&config)?, )?; - card.set_memory_state(&fsrs, item, config.inner.sm2_retention)?; + card.set_memory_state(&fsrs, item, config.inner.historical_retention)?; } let days_elapsed = self .storage diff --git a/rslib/src/scheduler/fsrs/memory_state.rs b/rslib/src/scheduler/fsrs/memory_state.rs index 44f78130c..4fe4c5c4a 100644 --- a/rslib/src/scheduler/fsrs/memory_state.rs +++ b/rslib/src/scheduler/fsrs/memory_state.rs @@ -32,7 +32,7 @@ pub struct ComputeMemoryProgress { pub(crate) struct UpdateMemoryStateRequest { pub weights: Weights, pub desired_retention: f32, - pub sm2_retention: f32, + pub historical_retention: f32, pub max_interval: u32, pub reschedule: bool, } @@ -70,12 +70,12 @@ impl Collection { None }; let fsrs = FSRS::new(req.as_ref().map(|w| &w.weights[..]).or(Some([].as_slice())))?; - let sm2_retention = req.as_ref().map(|w| w.sm2_retention); + let historical_retention = req.as_ref().map(|w| w.historical_retention); let items = fsrs_items_for_memory_state( &fsrs, revlog, timing.next_day_at, - sm2_retention.unwrap_or(0.9), + historical_retention.unwrap_or(0.9), ignore_before, )?; let desired_retention = req.as_ref().map(|w| w.desired_retention); @@ -86,7 +86,7 @@ impl Collection { let mut card = self.storage.get_card(card_id)?.or_not_found(card_id)?; let original = card.clone(); if let Some(req) = &req { - card.set_memory_state(&fsrs, item, sm2_retention.unwrap())?; + card.set_memory_state(&fsrs, item, historical_retention.unwrap())?; card.desired_retention = desired_retention; // if rescheduling if let Some(reviews) = &last_revlog_info { @@ -153,17 +153,17 @@ impl Collection { .get_deck_config(conf_id)? .or_not_found(conf_id)?; let desired_retention = config.inner.desired_retention; - let sm2_retention = config.inner.sm2_retention; + let historical_retention = config.inner.historical_retention; let fsrs = FSRS::new(Some(&config.inner.fsrs_weights))?; let revlog = self.revlog_for_srs(SearchNode::CardIds(card.id.to_string()))?; let item = single_card_revlog_to_item( &fsrs, revlog, self.timing_today()?.next_day_at, - sm2_retention, + historical_retention, ignore_revlogs_before_ms_from_config(&config)?, )?; - card.set_memory_state(&fsrs, item, sm2_retention)?; + card.set_memory_state(&fsrs, item, historical_retention)?; Ok(ComputeMemoryStateResponse { state: card.memory_state.map(Into::into), desired_retention, @@ -176,7 +176,7 @@ impl Card { &mut self, fsrs: &FSRS, item: Option, - sm2_retention: f32, + historical_retention: f32, ) -> Result<()> { let memory_state = if let Some(i) = item { Some(fsrs.memory_state(i.item, i.starting_state)?) @@ -187,7 +187,7 @@ impl Card { Some(fsrs.memory_state_from_sm2( self.ease_factor(), self.interval as f32, - sm2_retention, + historical_retention, )?) }; self.memory_state = memory_state.map(Into::into); @@ -209,7 +209,7 @@ pub(crate) fn fsrs_items_for_memory_state( fsrs: &FSRS, revlogs: Vec, next_day_at: TimestampSecs, - sm2_retention: f32, + historical_retention: f32, ignore_revlogs_before: TimestampMillis, ) -> Result)>> { revlogs @@ -223,7 +223,7 @@ pub(crate) fn fsrs_items_for_memory_state( fsrs, group.collect(), next_day_at, - sm2_retention, + historical_retention, ignore_revlogs_before, )?, )) @@ -277,7 +277,7 @@ pub(crate) fn single_card_revlog_to_item( fsrs: &FSRS, entries: Vec, next_day_at: TimestampSecs, - sm2_retention: f32, + historical_retention: f32, ignore_revlogs_before: TimestampMillis, ) -> Result> { struct FirstReview { @@ -310,7 +310,7 @@ pub(crate) fn single_card_revlog_to_item( let starting_state = fsrs.memory_state_from_sm2( first_review.ease_factor, first_review.interval, - sm2_retention, + historical_retention, )?; item.reviews.remove(0); if item.reviews.is_empty() { diff --git a/ts/deck-options/AdvancedOptions.svelte b/ts/deck-options/AdvancedOptions.svelte index b5f6aed69..be87cc24c 100644 --- a/ts/deck-options/AdvancedOptions.svelte +++ b/ts/deck-options/AdvancedOptions.svelte @@ -33,9 +33,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html help: tr.deckConfigMaximumIntervalTooltip(), url: HelpPage.DeckOptions.maximumInterval, }, - sm2Retention: { - title: tr.deckConfigSm2Retention(), - help: tr.deckConfigSm2RetentionTooltip(), + historicalRetention: { + title: tr.deckConfigHistoricalRetention(), + help: tr.deckConfigHistoricalRetentionTooltip(), sched: HelpItemScheduler.FSRS, }, startingEase: { @@ -201,16 +201,18 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html {:else} - openHelpModal(Object.keys(settings).indexOf("sm2Retention"))} + openHelpModal( + Object.keys(settings).indexOf("historicalRetention"), + )} > - {tr.deckConfigSm2Retention()} + {tr.deckConfigHistoricalRetention()} {/if}