Card States - ghrgriner/anki-stats GitHub Wiki

Overview

This page is intended as supplementary reading to the information provided in Anki Statistical Reports. It is not necessary to understand how card state is represented in the database to understand the statistical reports generated by Anki. However, once a reader understands the card type, it is only a bit more work to understand the card state. It is recommended a reader read the Anki Statistical Reports page at least through the 'Card Type' section before reading this page.

Purpose

The card state is the card-specific information used in the Anki Rust backend when answering to determine the new type of the card and the due date(time) of the next review if a given answer button is pushed. It also contains properties (like the leeched field in ReviewState) that are updated as a result of the review but are not used to determine the new type or due date.

Card State Data Structure Overview

At the highest level is CardState, which is an enum that has variants Filtered (for cards in a filtered deck) and Normal. The Filtered variant is also an enum, and this has variants Rescheduling and Preview, representing whether or not the filtered deck has rescheduling enabled. The Rescheduling variant and the Normal variant of CardState both contain a NormalState enum with four variants indicating the card type New, Learning, Review, and Relearning. These final 4 variants no longer contain any more enums. They each contain a structure with the card-specific data that will be used to update the card state.

Note that the card queue is not contained anywhere in these data structures. We also find it interesting to observe that a RelearnState contains both a LearnState and a ReviewState.

Card State Data Structures

The code below gives the data structures defined in the Rust backend. In Rust, an enum can have values of different types associated with the different variants of the enum. The type of the associated value is in parentheses after the variant name. See the Rust tutorial for details.

pub enum CardState {
    Normal(NormalState),
    Filtered(FilteredState),
}

pub enum FilteredState {
    Preview(PreviewState),
    Rescheduling(ReschedulingFilterState),
}

pub struct PreviewState {
    pub scheduled_secs: u32,
    pub finished: bool,
}

pub struct ReschedulingFilterState {
    pub original_state: NormalState,
}

pub enum NormalState {
    New(NewState),
    Learning(LearnState),
    Review(ReviewState),
    Relearning(RelearnState),
}

pub struct NewState {
    pub position: u32,
}

pub struct LearnState {
    pub remaining_steps: u32,
    pub scheduled_secs: u32,
    pub elapsed_secs: u32,
    pub memory_state: Option<FsrsMemoryState>,
}

pub struct ReviewState {
    pub scheduled_days: u32,
    pub elapsed_days: u32,
    pub ease_factor: f32,
    pub lapses: u32,
    pub leeched: bool,
    pub memory_state: Option<FsrsMemoryState>,
}

pub struct RelearnState {
    pub learning: LearnState,
    pub review: ReviewState,
}

State Context

The non-card specific information (i.e., information defined by the scheduler) is stored in the StateContext. This is used with the CardState during state transitions to determine the next state.

/// Info required during state transitions.
pub(crate) struct StateContext<'a> {
    /// In range `0.0..1.0`. Used to pick the final interval from the fuzz
    /// range.
    pub fuzz_factor: Option<f32>,
    pub fsrs_next_states: Option<NextStates>,
    pub fsrs_short_term_with_steps_enabled: bool,
    pub fsrs_allow_short_term: bool,
    // learning
    pub steps: LearningSteps<'a>,
    pub graduating_interval_good: u32,
    pub graduating_interval_easy: u32,
    pub initial_ease_factor: f32,

    // reviewing
    pub hard_multiplier: f32,
    pub easy_multiplier: f32,
    pub interval_multiplier: f32,
    pub maximum_review_interval: u32,
    pub leech_threshold: u32,
    pub load_balancer: Option<LoadBalancerContext<'a>>,

    // relearning
    pub relearn_steps: LearningSteps<'a>,
    pub lapse_multiplier: f32,
    pub minimum_lapse_interval: u32,

    // filtered
    pub in_filtered_deck: bool,
    pub preview_delays: PreviewDelays,
}
⚠️ **GitHub.com Fallback** ⚠️