mirror of
https://github.com/ankitects/anki.git
synced 2026-01-13 14:03:55 -05:00
backend
This commit is contained in:
parent
344cac1ef4
commit
233c5c19a9
2 changed files with 44 additions and 1 deletions
|
|
@ -389,6 +389,11 @@ message FsrsReview {
|
||||||
uint32 delta_t = 2;
|
uint32 delta_t = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum CMRRTarget {
|
||||||
|
memorised = 0;
|
||||||
|
stability = 1;
|
||||||
|
};
|
||||||
|
|
||||||
message SimulateFsrsReviewRequest {
|
message SimulateFsrsReviewRequest {
|
||||||
repeated float params = 1;
|
repeated float params = 1;
|
||||||
float desired_retention = 2;
|
float desired_retention = 2;
|
||||||
|
|
@ -402,6 +407,8 @@ message SimulateFsrsReviewRequest {
|
||||||
repeated float easy_days_percentages = 10;
|
repeated float easy_days_percentages = 10;
|
||||||
deck_config.DeckConfig.Config.ReviewCardOrder review_order = 11;
|
deck_config.DeckConfig.Config.ReviewCardOrder review_order = 11;
|
||||||
optional uint32 suspend_after_lapse_count = 12;
|
optional uint32 suspend_after_lapse_count = 12;
|
||||||
|
// For CMRR
|
||||||
|
optional CMRRTarget target = 13;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SimulateFsrsReviewResponse {
|
message SimulateFsrsReviewResponse {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
|
use anki_proto::scheduler::CmrrTarget;
|
||||||
// Copyright: Ankitects Pty Ltd and contributors
|
// Copyright: Ankitects Pty Ltd and contributors
|
||||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
use anki_proto::scheduler::SimulateFsrsReviewRequest;
|
use anki_proto::scheduler::SimulateFsrsReviewRequest;
|
||||||
use fsrs::extract_simulator_config;
|
use fsrs::extract_simulator_config;
|
||||||
|
use fsrs::SimulationResult;
|
||||||
use fsrs::SimulatorConfig;
|
use fsrs::SimulatorConfig;
|
||||||
use fsrs::FSRS;
|
use fsrs::FSRS;
|
||||||
|
|
||||||
|
|
@ -16,6 +18,40 @@ pub struct ComputeRetentionProgress {
|
||||||
|
|
||||||
impl Collection {
|
impl Collection {
|
||||||
pub fn compute_optimal_retention(&mut self, req: SimulateFsrsReviewRequest) -> Result<f32> {
|
pub fn compute_optimal_retention(&mut self, req: SimulateFsrsReviewRequest) -> Result<f32> {
|
||||||
|
// Helper macro to wrap the closure for "CMRRTargetFn"s
|
||||||
|
macro_rules! wrap {
|
||||||
|
($f:expr) => {
|
||||||
|
Some(fsrs::CMRRTargetFn(std::sync::Arc::new($f)))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let target = req
|
||||||
|
.target
|
||||||
|
.map(TryInto::try_into)
|
||||||
|
.transpose()
|
||||||
|
.unwrap_or(None);
|
||||||
|
|
||||||
|
let days_to_simulate = req.days_to_simulate as f32;
|
||||||
|
|
||||||
|
let target = match target {
|
||||||
|
Some(CmrrTarget::Memorised) => None,
|
||||||
|
Some(CmrrTarget::Stability) => {
|
||||||
|
wrap!(move |SimulationResult {
|
||||||
|
cards,
|
||||||
|
cost_per_day,
|
||||||
|
..
|
||||||
|
},
|
||||||
|
params| {
|
||||||
|
let total_cost = cost_per_day.iter().sum::<f32>();
|
||||||
|
total_cost
|
||||||
|
/ cards.iter().fold(0., |p, c| {
|
||||||
|
p + (c.retention_on(params, days_to_simulate) * c.stability)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
let mut anki_progress = self.new_progress_handler::<ComputeRetentionProgress>();
|
let mut anki_progress = self.new_progress_handler::<ComputeRetentionProgress>();
|
||||||
let fsrs = FSRS::new(None)?;
|
let fsrs = FSRS::new(None)?;
|
||||||
if req.days_to_simulate == 0 {
|
if req.days_to_simulate == 0 {
|
||||||
|
|
@ -34,7 +70,7 @@ impl Collection {
|
||||||
.is_ok()
|
.is_ok()
|
||||||
},
|
},
|
||||||
Some(cards),
|
Some(cards),
|
||||||
None,
|
target,
|
||||||
)?
|
)?
|
||||||
.clamp(0.7, 0.95))
|
.clamp(0.7, 0.95))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue