cache notetypes

This commit is contained in:
Damien Elmes 2020-04-18 10:23:14 +10:00
parent 1ca7fb4a80
commit a226f70733
5 changed files with 49 additions and 34 deletions

View file

@ -7,11 +7,12 @@ use crate::log::Logger;
use crate::timestamp::TimestampSecs;
use crate::types::Usn;
use crate::{
notetype::{NoteType, NoteTypeID},
sched::cutoff::{sched_timing_today, SchedTimingToday},
storage::SqliteStorage,
undo::UndoManager,
};
use std::path::PathBuf;
use std::{collections::HashMap, path::PathBuf, sync::Arc};
pub fn open_collection<P: Into<PathBuf>>(
path: P,
@ -50,6 +51,7 @@ pub struct CollectionState {
task_state: CollectionTaskState,
pub(crate) undo: UndoManager,
timing_today: Option<SchedTimingToday>,
pub(crate) notetype_cache: HashMap<NoteTypeID, Arc<NoteType>>,
}
#[derive(Debug, PartialEq)]

View file

@ -380,7 +380,7 @@ where
renamed: &HashMap<String, String>,
) -> Result<HashSet<String>> {
let mut referenced_files = HashSet::new();
let note_types = self.ctx.storage.get_all_notetype_core()?;
let note_types = self.ctx.get_all_notetypes()?;
let mut collection_modified = false;
let nids = self.ctx.search_notes("")?;

View file

@ -30,7 +30,10 @@ use crate::{
timestamp::TimestampSecs,
types::Usn,
};
use std::collections::{HashMap, HashSet};
use std::{
collections::{HashMap, HashSet},
sync::Arc,
};
use unicase::UniCase;
define_newtype!(NoteTypeID, i64);
@ -200,11 +203,45 @@ impl Collection {
.get_notetype(nt.id)?
.ok_or_else(|| AnkiError::invalid_input("no such notetype"))?;
col.update_notes_for_changed_fields(nt, existing_notetype.fields.len())?;
// fixme: card templates
// fixme: update cache instead of clearing
col.state.notetype_cache.remove(&nt.id);
Ok(())
})
}
pub fn get_notetype_by_name(&mut self, name: &str) -> Result<Option<NoteType>> {
self.storage.get_notetype_by_name(name)
pub fn get_notetype_by_name(&mut self, name: &str) -> Result<Option<Arc<NoteType>>> {
if let Some(ntid) = self.storage.get_notetype_id(name)? {
self.get_notetype(ntid)
} else {
Ok(None)
}
}
pub fn get_notetype(&mut self, ntid: NoteTypeID) -> Result<Option<Arc<NoteType>>> {
if let Some(nt) = self.state.notetype_cache.get(&ntid) {
return Ok(Some(nt.clone()));
}
if let Some(nt) = self.storage.get_notetype(ntid)? {
let nt = Arc::new(nt);
self.state.notetype_cache.insert(ntid, nt.clone());
Ok(Some(nt))
} else {
Ok(None)
}
}
pub fn get_all_notetypes(&mut self) -> Result<HashMap<NoteTypeID, Arc<NoteType>>> {
self.storage
.get_all_notetype_names()?
.into_iter()
.map(|(ntid, _)| {
self.get_notetype(ntid)
.transpose()
.unwrap()
.map(|nt| (ntid, nt))
})
.collect()
}
}

View file

@ -297,12 +297,11 @@ impl SqlWriter<'_> {
}
fn write_single_field(&mut self, field_name: &str, val: &str, is_re: bool) -> Result<()> {
let note_types = self.col.storage.get_all_notetype_core()?;
let note_types = self.col.get_all_notetypes()?;
let mut field_map = vec![];
for nt in note_types.values() {
let fields = self.col.storage.get_notetype_fields(nt.id)?;
for field in &fields {
for field in &nt.fields {
if matches_wildcard(&field.name, field_name) {
field_map.push((nt.id, field.ord));
}

View file

@ -46,21 +46,7 @@ impl SqliteStorage {
.transpose()
}
pub(crate) fn get_all_notetype_core(&self) -> Result<HashMap<NoteTypeID, NoteType>> {
let mut nts: HashMap<NoteTypeID, NoteType> = self
.db
.prepare_cached(include_str!("get_notetype.sql"))?
.query_and_then(NO_PARAMS, row_to_notetype_core)?
.map(|ntres| ntres.map(|nt| (nt.id, nt)))
.collect::<Result<_>>()?;
for nt in nts.values_mut() {
nt.fields = self.get_notetype_fields(nt.id)?;
}
Ok(nts)
}
// pub as currently used by searching code
pub(crate) fn get_notetype_fields(&self, ntid: NoteTypeID) -> Result<Vec<NoteField>> {
fn get_notetype_fields(&self, ntid: NoteTypeID) -> Result<Vec<NoteField>> {
self.db
.prepare_cached(include_str!("get_fields.sql"))?
.query_and_then(&[ntid], |row| {
@ -90,7 +76,7 @@ impl SqliteStorage {
.collect()
}
fn get_notetype_id(&self, name: &str) -> Result<Option<NoteTypeID>> {
pub(crate) fn get_notetype_id(&self, name: &str) -> Result<Option<NoteTypeID>> {
self.db
.prepare_cached("select id from notetypes where name = ?")?
.query_row(params![name], |row| row.get(0))
@ -98,16 +84,7 @@ impl SqliteStorage {
.map_err(Into::into)
}
pub fn get_notetype_by_name(&mut self, name: &str) -> Result<Option<NoteType>> {
if let Some(id) = self.get_notetype_id(name)? {
self.get_notetype(id)
} else {
Ok(None)
}
}
#[allow(dead_code)]
fn get_all_notetype_names(&self) -> Result<Vec<(NoteTypeID, String)>> {
pub fn get_all_notetype_names(&self) -> Result<Vec<(NoteTypeID, String)>> {
self.db
.prepare_cached(include_str!("get_notetype_names.sql"))?
.query_and_then(NO_PARAMS, |row| Ok((row.get(0)?, row.get(1)?)))?