mirror of
https://github.com/ankitects/anki.git
synced 2025-09-25 01:06:35 -04:00
Avoid creating CardGenContexts for every note
This requires CardGenContext to be generic, so it works both with an owned and borrowed notetype.
This commit is contained in:
parent
fe862523e6
commit
b740be6554
5 changed files with 47 additions and 31 deletions
|
@ -262,7 +262,11 @@ impl Collection {
|
|||
|
||||
// write note, updating tags and generating missing cards
|
||||
let ctx = genctx.get_or_insert_with(|| {
|
||||
CardGenContext::new(&nt, self.get_last_deck_added_to_for_notetype(nt.id), usn)
|
||||
CardGenContext::new(
|
||||
nt.as_ref(),
|
||||
self.get_last_deck_added_to_for_notetype(nt.id),
|
||||
usn,
|
||||
)
|
||||
});
|
||||
self.update_note_inner_generating_cards(
|
||||
ctx, &mut note, &original, false, norm, true,
|
||||
|
|
|
@ -32,6 +32,7 @@ struct Context<'a> {
|
|||
deck_ids: HashMap<String, Option<DeckId>>,
|
||||
usn: Usn,
|
||||
normalize_notes: bool,
|
||||
card_gen_ctxs: HashMap<(NotetypeId, DeckId), CardGenContext<Arc<Notetype>>>,
|
||||
//progress: IncrementableProgress<ImportProgress>,
|
||||
}
|
||||
|
||||
|
@ -52,6 +53,7 @@ impl<'a> Context<'a> {
|
|||
normalize_notes,
|
||||
notetypes,
|
||||
deck_ids,
|
||||
card_gen_ctxs: HashMap::new(),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -89,7 +91,7 @@ impl<'a> Context<'a> {
|
|||
for foreign in notes {
|
||||
if let Some(notetype) = self.notetype_for_note(&foreign)? {
|
||||
if let Some(deck_id) = self.deck_id_for_note(&foreign)? {
|
||||
let log_note = self.import_foreign_note(foreign, ¬etype, deck_id)?;
|
||||
let log_note = self.import_foreign_note(foreign, notetype, deck_id)?;
|
||||
log.new.push(log_note);
|
||||
}
|
||||
}
|
||||
|
@ -100,12 +102,12 @@ impl<'a> Context<'a> {
|
|||
fn import_foreign_note(
|
||||
&mut self,
|
||||
foreign: ForeignNote,
|
||||
notetype: &Notetype,
|
||||
notetype: Arc<Notetype>,
|
||||
deck_id: DeckId,
|
||||
) -> Result<LogNote> {
|
||||
let today = self.col.timing_today()?.days_elapsed;
|
||||
let (mut note, mut cards) = foreign.into_native(notetype, deck_id, today);
|
||||
self.import_note(&mut note, notetype)?;
|
||||
let (mut note, mut cards) = foreign.into_native(¬etype, deck_id, today);
|
||||
self.import_note(&mut note, ¬etype)?;
|
||||
self.import_cards(&mut cards, note.id)?;
|
||||
self.generate_missing_cards(notetype, deck_id, ¬e)?;
|
||||
Ok(note.into_log_note())
|
||||
|
@ -128,13 +130,16 @@ impl<'a> Context<'a> {
|
|||
|
||||
fn generate_missing_cards(
|
||||
&mut self,
|
||||
notetype: &Notetype,
|
||||
notetype: Arc<Notetype>,
|
||||
deck_id: DeckId,
|
||||
note: &Note,
|
||||
) -> Result<()> {
|
||||
let card_gen_context = CardGenContext::new(notetype, Some(deck_id), self.usn);
|
||||
let card_gen_context = self
|
||||
.card_gen_ctxs
|
||||
.entry((notetype.id, deck_id))
|
||||
.or_insert_with(|| CardGenContext::new(notetype, Some(deck_id), self.usn));
|
||||
self.col
|
||||
.generate_cards_for_existing_note(&card_gen_context, note)
|
||||
.generate_cards_for_existing_note(card_gen_context, note)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ impl Collection {
|
|||
.get_notetype(note.notetype_id)?
|
||||
.ok_or_else(|| AnkiError::invalid_input("missing note type"))?;
|
||||
let last_deck = col.get_last_deck_added_to_for_notetype(note.notetype_id);
|
||||
let ctx = CardGenContext::new(&nt, last_deck, col.usn()?);
|
||||
let ctx = CardGenContext::new(nt.as_ref(), last_deck, col.usn()?);
|
||||
let norm = col.get_config_bool(BoolKey::NormalizeNoteText);
|
||||
col.add_note_inner(&ctx, note, did, norm)
|
||||
})
|
||||
|
@ -334,7 +334,7 @@ impl Collection {
|
|||
|
||||
pub(crate) fn add_note_inner(
|
||||
&mut self,
|
||||
ctx: &CardGenContext,
|
||||
ctx: &CardGenContext<&Notetype>,
|
||||
note: &mut Note,
|
||||
did: DeckId,
|
||||
normalize_text: bool,
|
||||
|
@ -397,7 +397,7 @@ impl Collection {
|
|||
.get_notetype(note.notetype_id)?
|
||||
.ok_or_else(|| AnkiError::invalid_input("missing note type"))?;
|
||||
let last_deck = self.get_last_deck_added_to_for_notetype(note.notetype_id);
|
||||
let ctx = CardGenContext::new(&nt, last_deck, self.usn()?);
|
||||
let ctx = CardGenContext::new(nt.as_ref(), last_deck, self.usn()?);
|
||||
let norm = self.get_config_bool(BoolKey::NormalizeNoteText);
|
||||
self.update_note_inner_generating_cards(&ctx, note, &existing_note, true, norm, true)?;
|
||||
Ok(())
|
||||
|
@ -405,7 +405,7 @@ impl Collection {
|
|||
|
||||
pub(crate) fn update_note_inner_generating_cards(
|
||||
&mut self,
|
||||
ctx: &CardGenContext,
|
||||
ctx: &CardGenContext<&Notetype>,
|
||||
note: &mut Note,
|
||||
original: &Note,
|
||||
mark_note_modified: bool,
|
||||
|
@ -508,7 +508,7 @@ impl Collection {
|
|||
if out.generate_cards {
|
||||
let ctx = genctx.get_or_insert_with(|| {
|
||||
CardGenContext::new(
|
||||
&nt,
|
||||
nt.as_ref(),
|
||||
self.get_last_deck_added_to_for_notetype(nt.id),
|
||||
usn,
|
||||
)
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
ops::Deref,
|
||||
};
|
||||
|
||||
use itertools::Itertools;
|
||||
use rand::{rngs::StdRng, Rng, SeedableRng};
|
||||
|
@ -38,9 +41,9 @@ pub(crate) struct SingleCardGenContext {
|
|||
|
||||
/// Info required to determine which cards should be generated when note added/updated,
|
||||
/// and where they should be placed.
|
||||
pub(crate) struct CardGenContext<'a> {
|
||||
pub(crate) struct CardGenContext<N: Deref<Target = Notetype>> {
|
||||
pub usn: Usn,
|
||||
pub notetype: &'a Notetype,
|
||||
pub notetype: N,
|
||||
/// The last deck that was added to with this note type
|
||||
pub last_deck: Option<DeckId>,
|
||||
cards: Vec<SingleCardGenContext>,
|
||||
|
@ -53,20 +56,21 @@ pub(crate) struct CardGenCache {
|
|||
deck_configs: HashMap<DeckId, DeckConfig>,
|
||||
}
|
||||
|
||||
impl CardGenContext<'_> {
|
||||
pub(crate) fn new(nt: &Notetype, last_deck: Option<DeckId>, usn: Usn) -> CardGenContext<'_> {
|
||||
impl<N: Deref<Target = Notetype>> CardGenContext<N> {
|
||||
pub(crate) fn new(nt: N, last_deck: Option<DeckId>, usn: Usn) -> CardGenContext<N> {
|
||||
let cards = nt
|
||||
.templates
|
||||
.iter()
|
||||
.map(|tmpl| SingleCardGenContext {
|
||||
template: tmpl.parsed_question(),
|
||||
target_deck_id: tmpl.target_deck_id(),
|
||||
})
|
||||
.collect();
|
||||
CardGenContext {
|
||||
usn,
|
||||
last_deck,
|
||||
notetype: nt,
|
||||
cards: nt
|
||||
.templates
|
||||
.iter()
|
||||
.map(|tmpl| SingleCardGenContext {
|
||||
template: tmpl.parsed_question(),
|
||||
target_deck_id: tmpl.target_deck_id(),
|
||||
})
|
||||
.collect(),
|
||||
cards,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,7 +213,7 @@ pub(crate) fn extract_data_from_existing_cards(
|
|||
impl Collection {
|
||||
pub(crate) fn generate_cards_for_new_note(
|
||||
&mut self,
|
||||
ctx: &CardGenContext,
|
||||
ctx: &CardGenContext<impl Deref<Target = Notetype>>,
|
||||
note: &Note,
|
||||
target_deck_id: DeckId,
|
||||
) -> Result<()> {
|
||||
|
@ -224,7 +228,7 @@ impl Collection {
|
|||
|
||||
pub(crate) fn generate_cards_for_existing_note(
|
||||
&mut self,
|
||||
ctx: &CardGenContext,
|
||||
ctx: &CardGenContext<impl Deref<Target = Notetype>>,
|
||||
note: &Note,
|
||||
) -> Result<()> {
|
||||
let existing = self.storage.existing_cards_for_note(note.id)?;
|
||||
|
@ -233,7 +237,7 @@ impl Collection {
|
|||
|
||||
fn generate_cards_for_note(
|
||||
&mut self,
|
||||
ctx: &CardGenContext,
|
||||
ctx: &CardGenContext<impl Deref<Target = Notetype>>,
|
||||
note: &Note,
|
||||
existing: &[AlreadyGeneratedCardInfo],
|
||||
target_deck_id: Option<DeckId>,
|
||||
|
@ -246,7 +250,10 @@ impl Collection {
|
|||
self.add_generated_cards(note.id, &cards, target_deck_id, cache)
|
||||
}
|
||||
|
||||
pub(crate) fn generate_cards_for_notetype(&mut self, ctx: &CardGenContext) -> Result<()> {
|
||||
pub(crate) fn generate_cards_for_notetype(
|
||||
&mut self,
|
||||
ctx: &CardGenContext<impl Deref<Target = Notetype>>,
|
||||
) -> Result<()> {
|
||||
let existing_cards = self.storage.existing_cards_for_notetype(ctx.notetype.id)?;
|
||||
let by_note = group_generated_cards_by_note(existing_cards);
|
||||
let mut cache = CardGenCache::default();
|
||||
|
|
|
@ -255,7 +255,7 @@ impl Collection {
|
|||
.get_notetype(new_notetype_id)?
|
||||
.ok_or(AnkiError::NotFound)?;
|
||||
let last_deck = self.get_last_deck_added_to_for_notetype(notetype.id);
|
||||
let ctx = CardGenContext::new(¬etype, last_deck, usn);
|
||||
let ctx = CardGenContext::new(notetype.as_ref(), last_deck, usn);
|
||||
|
||||
for nid in note_ids {
|
||||
let mut note = self.storage.get_note(*nid)?.ok_or(AnkiError::NotFound)?;
|
||||
|
|
Loading…
Reference in a new issue