roll back the vec cache changes

prepare_cached() is sufficiently fast, and allowing the vec cache
to persist across calls is complicated due to lifetime restrictions
This commit is contained in:
Damien Elmes 2020-03-29 09:26:09 +10:00
parent 1a1a00d50f
commit 2810d3883b
3 changed files with 68 additions and 116 deletions

View File

@ -39,7 +39,6 @@ slog-envlogger = "2.2.0"
serde_repr = "0.1.5" serde_repr = "0.1.5"
num_enum = "0.4.2" num_enum = "0.4.2"
unicase = "2.6.0" unicase = "2.6.0"
variant_count = "=1.0.0"
# pinned until rusqlite 0.22 comes out # pinned until rusqlite 0.22 comes out
[target.'cfg(target_vendor="apple")'.dependencies.rusqlite] [target.'cfg(target_vendor="apple")'.dependencies.rusqlite]

View File

@ -1,7 +1,6 @@
// 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 super::sqlite::CachedStatementKind;
use crate::card::{Card, CardID, CardQueue, CardType}; use crate::card::{Card, CardID, CardQueue, CardType};
use crate::err::Result; use crate::err::Result;
use crate::timestamp::TimestampMillis; use crate::timestamp::TimestampMillis;
@ -34,97 +33,81 @@ impl FromSql for CardQueue {
impl super::StorageContext<'_> { impl super::StorageContext<'_> {
pub fn get_card(&mut self, cid: CardID) -> Result<Option<Card>> { pub fn get_card(&mut self, cid: CardID) -> Result<Option<Card>> {
self.with_cached_stmt( let mut stmt = self.db.prepare_cached(include_str!("get_card.sql"))?;
CachedStatementKind::GetCard, stmt.query_row(params![cid], |row| {
include_str!("get_card.sql"), Ok(Card {
|stmt| { id: cid,
stmt.query_row(params![cid], |row| { nid: row.get(0)?,
Ok(Card { did: row.get(1)?,
id: cid, ord: row.get(2)?,
nid: row.get(0)?, mtime: row.get(3)?,
did: row.get(1)?, usn: row.get(4)?,
ord: row.get(2)?, ctype: row.get(5)?,
mtime: row.get(3)?, queue: row.get(6)?,
usn: row.get(4)?, due: row.get(7)?,
ctype: row.get(5)?, ivl: row.get(8)?,
queue: row.get(6)?, factor: row.get(9)?,
due: row.get(7)?, reps: row.get(10)?,
ivl: row.get(8)?, lapses: row.get(11)?,
factor: row.get(9)?, left: row.get(12)?,
reps: row.get(10)?, odue: row.get(13)?,
lapses: row.get(11)?, odid: row.get(14)?,
left: row.get(12)?, flags: row.get(15)?,
odue: row.get(13)?, data: row.get(16)?,
odid: row.get(14)?, })
flags: row.get(15)?, })
data: row.get(16)?, .optional()
}) .map_err(Into::into)
})
.optional()
.map_err(Into::into)
},
)
} }
pub(crate) fn update_card(&mut self, card: &Card) -> Result<()> { pub(crate) fn update_card(&mut self, card: &Card) -> Result<()> {
self.with_cached_stmt( let mut stmt = self.db.prepare_cached(include_str!("update_card.sql"))?;
CachedStatementKind::UpdateCard, stmt.execute(params![
include_str!("update_card.sql"), card.nid,
|stmt| { card.did,
stmt.execute(params![ card.ord,
card.nid, card.mtime,
card.did, card.usn,
card.ord, card.ctype as u8,
card.mtime, card.queue as i8,
card.usn, card.due,
card.ctype as u8, card.ivl,
card.queue as i8, card.factor,
card.due, card.reps,
card.ivl, card.lapses,
card.factor, card.left,
card.reps, card.odue,
card.lapses, card.odid,
card.left, card.flags,
card.odue, card.data,
card.odid, card.id,
card.flags, ])?;
card.data, Ok(())
card.id,
])?;
Ok(())
},
)
} }
pub(crate) fn add_card(&mut self, card: &mut Card) -> Result<()> { pub(crate) fn add_card(&mut self, card: &mut Card) -> Result<()> {
let now = TimestampMillis::now().0; let now = TimestampMillis::now().0;
self.with_cached_stmt( let mut stmt = self.db.prepare_cached(include_str!("add_card.sql"))?;
CachedStatementKind::AddCard, stmt.execute(params![
include_str!("add_card.sql"), now,
|stmt| { card.nid,
stmt.execute(params![ card.did,
now, card.ord,
card.nid, card.mtime,
card.did, card.usn,
card.ord, card.ctype as u8,
card.mtime, card.queue as i8,
card.usn, card.due,
card.ctype as u8, card.ivl,
card.queue as i8, card.factor,
card.due, card.reps,
card.ivl, card.lapses,
card.factor, card.left,
card.reps, card.odue,
card.lapses, card.odid,
card.left, card.flags,
card.odue, card.data,
card.odid, ])?;
card.flags,
card.data,
])?;
Ok(())
},
)?;
card.id = CardID(self.db.last_insert_rowid()); card.id = CardID(self.db.last_insert_rowid());
Ok(()) Ok(())
} }

View File

@ -24,7 +24,6 @@ use std::{
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
use unicase::UniCase; use unicase::UniCase;
use variant_count::VariantCount;
const SCHEMA_MIN_VERSION: u8 = 11; const SCHEMA_MIN_VERSION: u8 = 11;
const SCHEMA_MAX_VERSION: u8 = 11; const SCHEMA_MAX_VERSION: u8 = 11;
@ -204,53 +203,24 @@ impl SqliteStorage {
} }
} }
#[derive(Clone, Copy, VariantCount)]
#[allow(clippy::enum_variant_names)]
pub(super) enum CachedStatementKind {
GetCard,
UpdateCard,
AddCard,
}
pub(crate) struct StorageContext<'a> { pub(crate) struct StorageContext<'a> {
pub(crate) db: &'a Connection, pub(crate) db: &'a Connection,
server: bool, server: bool,
usn: Option<Usn>, usn: Option<Usn>,
timing_today: Option<SchedTimingToday>, timing_today: Option<SchedTimingToday>,
cached_statements: Vec<Option<rusqlite::CachedStatement<'a>>>,
} }
impl StorageContext<'_> { impl StorageContext<'_> {
fn new(db: &Connection, server: bool) -> StorageContext { fn new(db: &Connection, server: bool) -> StorageContext {
let stmt_len = CachedStatementKind::VARIANT_COUNT;
let mut statements = Vec::with_capacity(stmt_len);
statements.resize_with(stmt_len, Default::default);
StorageContext { StorageContext {
db, db,
server, server,
usn: None, usn: None,
timing_today: None, timing_today: None,
cached_statements: statements,
} }
} }
pub(super) fn with_cached_stmt<F, T>(
&mut self,
kind: CachedStatementKind,
sql: &str,
func: F,
) -> Result<T>
where
F: FnOnce(&mut rusqlite::CachedStatement) -> Result<T>,
{
if self.cached_statements[kind as usize].is_none() {
self.cached_statements[kind as usize] = Some(self.db.prepare_cached(sql)?);
}
func(self.cached_statements[kind as usize].as_mut().unwrap())
}
// Standard transaction start/stop // Standard transaction start/stop
////////////////////////////////////// //////////////////////////////////////