mirror of
https://github.com/ankitects/anki.git
synced 2025-09-21 23:42:23 -04:00

* start of load balancer * add configuration options; option to load balance per deck * formatting * clippy * add myself to contributors * cleanup * cargo fmt * copyright header on load_balancer.rs * remove extra space * more formatting * python formatting * ignore this being None only doing this cause python has awful lambdas and can't loop in a meaningful way without doing this * only calculate notes on each day if we are trying to avoid siblings * don't fuzz intervals if the load balancer is enabled * force generator to eval so this actually happens * load balance instead of fuzzing, rather than in addition to * use builtin fuzz_bounds rather than reinvent something new * print some debug info on how its load balancing * clippy * more accurately load balance only when we want to fuzz * incorrectly doublechecking the presence of the load balancer * more printfs for debugging * avoid siblings -> disperse siblings * load balance learning graduating intervals * load balancer: respect min/max intervals; graduating easy should be at least +1 good * filter out after-days under minimum interval * this is an inclusive check * switch load balancer to caching instead of on the fly calculation * handle case where load balancer would balance outside of its bounds * disable lb when unselecting it in preferences * call load_balancer in StateContext::with_review_fuzz instead of next to * rebuild load balancer when card queue is rebuilt * remove now-unused configuration options * add note option to notetype to enable/disable sibling dispersion * add options to exclude decks from load balancing * theres a lint checking that the link actually exists so I guess I'll add the anchor back in later? * how did I even update this * move load balancer to cardqueue * remove per-deck balancing options * improve determining whether to disperse siblings when load balancing * don't recalculate notes on days every time * remove debug code * remove all configuration; load balancer enabled by default; disperse siblings if bury_reviews is set * didn't fully remove caring about decks from load balancer sql query * load balancer should only count cards in the same preset * fuzz interval if its outside of load balancer's range * also check minimum when bailing out of load balancer * cleanup; make tests happy * experimental weight-based load balance fuzzing * take into account interval when weighting as it seems to help * if theres no cards the interval weight is just 1.0 * make load balancer disableable through debug console * remove debug prints * typo * remove debugging print * explain a bit how load balancer works * properly balance per preset * use inclusive range rather than +1 * -1 type cast * move type hint somewhere less ugly; fix comment typo * Reuse existing deck list from parent function (dae) Minor optimisation
140 lines
5.6 KiB
Rust
140 lines
5.6 KiB
Rust
// Copyright: Ankitects Pty Ltd and contributors
|
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
|
|
use anki_proto::config::config_key::Bool as BoolKeyProto;
|
|
use anki_proto::config::config_key::String as StringKeyProto;
|
|
use anki_proto::generic;
|
|
use serde_json::Value;
|
|
|
|
use crate::config::BoolKey;
|
|
use crate::config::StringKey;
|
|
use crate::prelude::*;
|
|
|
|
impl From<BoolKeyProto> for BoolKey {
|
|
fn from(k: BoolKeyProto) -> Self {
|
|
match k {
|
|
BoolKeyProto::BrowserTableShowNotesMode => BoolKey::BrowserTableShowNotesMode,
|
|
BoolKeyProto::PreviewBothSides => BoolKey::PreviewBothSides,
|
|
BoolKeyProto::CollapseTags => BoolKey::CollapseTags,
|
|
BoolKeyProto::CollapseNotetypes => BoolKey::CollapseNotetypes,
|
|
BoolKeyProto::CollapseDecks => BoolKey::CollapseDecks,
|
|
BoolKeyProto::CollapseSavedSearches => BoolKey::CollapseSavedSearches,
|
|
BoolKeyProto::CollapseToday => BoolKey::CollapseToday,
|
|
BoolKeyProto::CollapseCardState => BoolKey::CollapseCardState,
|
|
BoolKeyProto::CollapseFlags => BoolKey::CollapseFlags,
|
|
BoolKeyProto::Sched2021 => BoolKey::Sched2021,
|
|
BoolKeyProto::AddingDefaultsToCurrentDeck => BoolKey::AddingDefaultsToCurrentDeck,
|
|
BoolKeyProto::HideAudioPlayButtons => BoolKey::HideAudioPlayButtons,
|
|
BoolKeyProto::InterruptAudioWhenAnswering => BoolKey::InterruptAudioWhenAnswering,
|
|
BoolKeyProto::PasteImagesAsPng => BoolKey::PasteImagesAsPng,
|
|
BoolKeyProto::PasteStripsFormatting => BoolKey::PasteStripsFormatting,
|
|
BoolKeyProto::NormalizeNoteText => BoolKey::NormalizeNoteText,
|
|
BoolKeyProto::IgnoreAccentsInSearch => BoolKey::IgnoreAccentsInSearch,
|
|
BoolKeyProto::RestorePositionBrowser => BoolKey::RestorePositionBrowser,
|
|
BoolKeyProto::RestorePositionReviewer => BoolKey::RestorePositionReviewer,
|
|
BoolKeyProto::ResetCountsBrowser => BoolKey::ResetCountsBrowser,
|
|
BoolKeyProto::ResetCountsReviewer => BoolKey::ResetCountsReviewer,
|
|
BoolKeyProto::RandomOrderReposition => BoolKey::RandomOrderReposition,
|
|
BoolKeyProto::ShiftPositionOfExistingCards => BoolKey::ShiftPositionOfExistingCards,
|
|
BoolKeyProto::RenderLatex => BoolKey::RenderLatex,
|
|
BoolKeyProto::LoadBalancerEnabled => BoolKey::LoadBalancerEnabled,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<StringKeyProto> for StringKey {
|
|
fn from(k: StringKeyProto) -> Self {
|
|
match k {
|
|
StringKeyProto::SetDueBrowser => StringKey::SetDueBrowser,
|
|
StringKeyProto::SetDueReviewer => StringKey::SetDueReviewer,
|
|
StringKeyProto::DefaultSearchText => StringKey::DefaultSearchText,
|
|
StringKeyProto::CardStateCustomizer => StringKey::CardStateCustomizer,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl crate::services::ConfigService for Collection {
|
|
fn get_config_json(&mut self, input: generic::String) -> Result<generic::Json> {
|
|
let val: Option<Value> = self.get_config_optional(input.val.as_str());
|
|
val.or_not_found(input.val)
|
|
.and_then(|v| serde_json::to_vec(&v).map_err(Into::into))
|
|
.map(Into::into)
|
|
}
|
|
|
|
fn set_config_json(
|
|
&mut self,
|
|
input: anki_proto::config::SetConfigJsonRequest,
|
|
) -> Result<anki_proto::collection::OpChanges> {
|
|
let val: Value = serde_json::from_slice(&input.value_json)?;
|
|
self.set_config_json(input.key.as_str(), &val, input.undoable)
|
|
.map(Into::into)
|
|
}
|
|
|
|
fn set_config_json_no_undo(
|
|
&mut self,
|
|
input: anki_proto::config::SetConfigJsonRequest,
|
|
) -> Result<()> {
|
|
let val: Value = serde_json::from_slice(&input.value_json)?;
|
|
self.transact_no_undo(|col| col.set_config(input.key.as_str(), &val).map(|_| ()))
|
|
.map(Into::into)
|
|
}
|
|
|
|
fn remove_config(
|
|
&mut self,
|
|
input: generic::String,
|
|
) -> Result<anki_proto::collection::OpChanges> {
|
|
self.remove_config(input.val.as_str()).map(Into::into)
|
|
}
|
|
|
|
fn get_all_config(&mut self) -> Result<generic::Json> {
|
|
let conf = self.storage.get_all_config()?;
|
|
serde_json::to_vec(&conf)
|
|
.map_err(Into::into)
|
|
.map(Into::into)
|
|
}
|
|
|
|
fn get_config_bool(
|
|
&mut self,
|
|
input: anki_proto::config::GetConfigBoolRequest,
|
|
) -> Result<generic::Bool> {
|
|
Ok(generic::Bool {
|
|
val: Collection::get_config_bool(self, input.key().into()),
|
|
})
|
|
}
|
|
|
|
fn set_config_bool(
|
|
&mut self,
|
|
input: anki_proto::config::SetConfigBoolRequest,
|
|
) -> Result<anki_proto::collection::OpChanges> {
|
|
self.set_config_bool(input.key().into(), input.value, input.undoable)
|
|
.map(Into::into)
|
|
}
|
|
|
|
fn get_config_string(
|
|
&mut self,
|
|
input: anki_proto::config::GetConfigStringRequest,
|
|
) -> Result<generic::String> {
|
|
Ok(generic::String {
|
|
val: Collection::get_config_string(self, input.key().into()),
|
|
})
|
|
}
|
|
|
|
fn set_config_string(
|
|
&mut self,
|
|
input: anki_proto::config::SetConfigStringRequest,
|
|
) -> Result<anki_proto::collection::OpChanges> {
|
|
self.set_config_string(input.key().into(), &input.value, input.undoable)
|
|
.map(Into::into)
|
|
}
|
|
|
|
fn get_preferences(&mut self) -> Result<anki_proto::config::Preferences> {
|
|
Collection::get_preferences(self)
|
|
}
|
|
|
|
fn set_preferences(
|
|
&mut self,
|
|
input: anki_proto::config::Preferences,
|
|
) -> Result<anki_proto::collection::OpChanges> {
|
|
self.set_preferences(input).map(Into::into)
|
|
}
|
|
}
|