backend part

This commit is contained in:
Luc Mcgrady 2025-07-13 09:53:03 +01:00
parent 3b18097550
commit dc8a687b33
No known key found for this signature in database
GPG key ID: 4F3D7A0B17CC3D9C
3 changed files with 40 additions and 0 deletions

View file

@ -55,6 +55,8 @@ service SchedulerService {
returns (ComputeOptimalRetentionResponse); returns (ComputeOptimalRetentionResponse);
rpc SimulateFsrsReview(SimulateFsrsReviewRequest) rpc SimulateFsrsReview(SimulateFsrsReviewRequest)
returns (SimulateFsrsReviewResponse); returns (SimulateFsrsReviewResponse);
rpc SimulateFsrsWorkload(SimulateFsrsReviewRequest)
returns (SimulateFsrsWorkloadResponse);
rpc EvaluateParams(EvaluateParamsRequest) returns (EvaluateParamsResponse); rpc EvaluateParams(EvaluateParamsRequest) returns (EvaluateParamsResponse);
rpc EvaluateParamsLegacy(EvaluateParamsLegacyRequest) rpc EvaluateParamsLegacy(EvaluateParamsLegacyRequest)
returns (EvaluateParamsResponse); returns (EvaluateParamsResponse);
@ -414,6 +416,10 @@ message SimulateFsrsReviewResponse {
repeated float daily_time_cost = 4; repeated float daily_time_cost = 4;
} }
message SimulateFsrsWorkloadResponse {
map<uint32, float> dr_workload = 1;
}
message ComputeOptimalRetentionResponse { message ComputeOptimalRetentionResponse {
float optimal_retention = 1; float optimal_retention = 1;
} }

View file

@ -1,3 +1,4 @@
use std::collections::HashMap;
// 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 std::sync::Arc; use std::sync::Arc;
@ -6,6 +7,7 @@ use anki_proto::deck_config::deck_config::config::ReviewCardOrder;
use anki_proto::deck_config::deck_config::config::ReviewCardOrder::*; use anki_proto::deck_config::deck_config::config::ReviewCardOrder::*;
use anki_proto::scheduler::SimulateFsrsReviewRequest; use anki_proto::scheduler::SimulateFsrsReviewRequest;
use anki_proto::scheduler::SimulateFsrsReviewResponse; use anki_proto::scheduler::SimulateFsrsReviewResponse;
use anki_proto::scheduler::SimulateFsrsWorkloadResponse;
use fsrs::simulate; use fsrs::simulate;
use fsrs::PostSchedulingFn; use fsrs::PostSchedulingFn;
use fsrs::ReviewPriorityFn; use fsrs::ReviewPriorityFn;
@ -267,6 +269,30 @@ impl Collection {
daily_time_cost: result.cost_per_day, daily_time_cost: result.cost_per_day,
}) })
} }
pub fn simulate_workload(
&mut self,
req: SimulateFsrsReviewRequest,
) -> Result<SimulateFsrsWorkloadResponse> {
let (config, cards) = self.simulate_request_to_config(&req)?;
let dr_workload = (70u32..=99u32)
.map(|dr| {
let result = simulate(
&config,
&req.params,
dr as f32 / 100.,
None,
Some(cards.clone()),
)?;
Ok((
dr,
result.memorized_cnt_per_day.last().unwrap_or(&0.)
/ result.cost_per_day.iter().sum::<f32>(),
))
})
.collect::<Result<HashMap<_, _>>>()?;
Ok(SimulateFsrsWorkloadResponse { dr_workload })
}
} }
impl Card { impl Card {

View file

@ -16,6 +16,7 @@ use anki_proto::scheduler::FuzzDeltaResponse;
use anki_proto::scheduler::GetOptimalRetentionParametersResponse; use anki_proto::scheduler::GetOptimalRetentionParametersResponse;
use anki_proto::scheduler::SimulateFsrsReviewRequest; use anki_proto::scheduler::SimulateFsrsReviewRequest;
use anki_proto::scheduler::SimulateFsrsReviewResponse; use anki_proto::scheduler::SimulateFsrsReviewResponse;
use anki_proto::scheduler::SimulateFsrsWorkloadResponse;
use fsrs::ComputeParametersInput; use fsrs::ComputeParametersInput;
use fsrs::FSRSItem; use fsrs::FSRSItem;
use fsrs::FSRSReview; use fsrs::FSRSReview;
@ -283,6 +284,13 @@ impl crate::services::SchedulerService for Collection {
self.simulate_review(input) self.simulate_review(input)
} }
fn simulate_fsrs_workload(
&mut self,
input: SimulateFsrsReviewRequest,
) -> Result<SimulateFsrsWorkloadResponse> {
self.simulate_workload(input)
}
fn compute_optimal_retention( fn compute_optimal_retention(
&mut self, &mut self,
input: SimulateFsrsReviewRequest, input: SimulateFsrsReviewRequest,