mirror of
https://github.com/isar/rusqlite.git
synced 2025-04-20 08:17:44 +08:00
Use a real LruCache instead of a VecDeque.
This commit is contained in:
parent
20b93bdb96
commit
d923d8c670
@ -22,6 +22,7 @@ trace = []
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
time = "~0.1.0"
|
time = "~0.1.0"
|
||||||
bitflags = "0.7"
|
bitflags = "0.7"
|
||||||
|
lru-cache = "0.0.7"
|
||||||
libc = "~0.2"
|
libc = "~0.2"
|
||||||
clippy = {version = "~0.0.58", optional = true}
|
clippy = {version = "~0.0.58", optional = true}
|
||||||
chrono = { version = "~0.2", optional = true }
|
chrono = { version = "~0.2", optional = true }
|
||||||
|
35
src/cache.rs
35
src/cache.rs
@ -1,8 +1,8 @@
|
|||||||
//! Prepared statements cache for faster execution.
|
//! Prepared statements cache for faster execution.
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::VecDeque;
|
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
use lru_cache::LruCache;
|
||||||
use {Result, Connection, Statement};
|
use {Result, Connection, Statement};
|
||||||
use raw_statement::RawStatement;
|
use raw_statement::RawStatement;
|
||||||
|
|
||||||
@ -40,9 +40,7 @@ impl Connection {
|
|||||||
|
|
||||||
/// Prepared statements LRU cache.
|
/// Prepared statements LRU cache.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StatementCache {
|
pub struct StatementCache(RefCell<LruCache<String, RawStatement>>);
|
||||||
cache: RefCell<VecDeque<RawStatement>>, // back = LRU
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Cacheable statement.
|
/// Cacheable statement.
|
||||||
///
|
///
|
||||||
@ -92,7 +90,7 @@ impl<'conn> CachedStatement<'conn> {
|
|||||||
impl StatementCache {
|
impl StatementCache {
|
||||||
/// Create a statement cache.
|
/// Create a statement cache.
|
||||||
pub fn with_capacity(capacity: usize) -> StatementCache {
|
pub fn with_capacity(capacity: usize) -> StatementCache {
|
||||||
StatementCache { cache: RefCell::new(VecDeque::with_capacity(capacity)) }
|
StatementCache(RefCell::new(LruCache::new(capacity)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Search the cache for a prepared-statement object that implements `sql`.
|
/// Search the cache for a prepared-statement object that implements `sql`.
|
||||||
@ -106,27 +104,20 @@ impl StatementCache {
|
|||||||
conn: &'conn Connection,
|
conn: &'conn Connection,
|
||||||
sql: &str)
|
sql: &str)
|
||||||
-> Result<CachedStatement<'conn>> {
|
-> Result<CachedStatement<'conn>> {
|
||||||
let mut cache = self.cache.borrow_mut();
|
let mut cache = self.0.borrow_mut();
|
||||||
let stmt = match cache.iter()
|
let stmt = match cache.remove(sql) {
|
||||||
.rposition(|entry| entry.sql().to_bytes().eq(sql.as_bytes())) {
|
Some(raw_stmt) => Ok(Statement::new(conn, raw_stmt)),
|
||||||
Some(index) => {
|
None => conn.prepare(sql),
|
||||||
let raw_stmt = cache.swap_remove_front(index).unwrap(); // FIXME Not LRU compliant
|
|
||||||
Ok(Statement::new(conn, raw_stmt))
|
|
||||||
}
|
|
||||||
_ => conn.prepare(sql),
|
|
||||||
};
|
};
|
||||||
stmt.map(|stmt| CachedStatement::new(stmt, self))
|
stmt.map(|stmt| CachedStatement::new(stmt, self))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a statement to the cache.
|
// Return a statement to the cache.
|
||||||
fn cache_stmt(&self, stmt: RawStatement) {
|
fn cache_stmt(&self, stmt: RawStatement) {
|
||||||
let mut cache = self.cache.borrow_mut();
|
let mut cache = self.0.borrow_mut();
|
||||||
if cache.capacity() == cache.len() {
|
|
||||||
// is full
|
|
||||||
cache.pop_back(); // LRU dropped
|
|
||||||
}
|
|
||||||
stmt.clear_bindings();
|
stmt.clear_bindings();
|
||||||
cache.push_front(stmt)
|
let sql = String::from_utf8_lossy(stmt.sql().to_bytes()).to_string();
|
||||||
|
cache.insert(sql, stmt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,15 +128,15 @@ mod test {
|
|||||||
|
|
||||||
impl StatementCache {
|
impl StatementCache {
|
||||||
fn clear(&self) {
|
fn clear(&self) {
|
||||||
self.cache.borrow_mut().clear();
|
self.0.borrow_mut().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
self.cache.borrow().len()
|
self.0.borrow().len()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn capacity(&self) -> usize {
|
fn capacity(&self) -> usize {
|
||||||
self.cache.borrow().capacity()
|
self.0.borrow().capacity()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
|
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
extern crate libsqlite3_sys as ffi;
|
extern crate libsqlite3_sys as ffi;
|
||||||
|
extern crate lru_cache;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate bitflags;
|
extern crate bitflags;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user