mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-23 17:05:36 +01:00
Use sieve algorithm in page cache in place of full LRU
This commit is contained in:
10
core/lib.rs
10
core/lib.rs
@@ -80,7 +80,7 @@ use std::{
|
||||
use storage::database::DatabaseFile;
|
||||
pub use storage::database::IOContext;
|
||||
pub use storage::encryption::{EncryptionContext, EncryptionKey};
|
||||
use storage::page_cache::DumbLruPageCache;
|
||||
use storage::page_cache::PageCache;
|
||||
use storage::pager::{AtomicDbState, DbState};
|
||||
use storage::sqlite3_ondisk::PageSize;
|
||||
pub use storage::{
|
||||
@@ -187,7 +187,7 @@ pub struct Database {
|
||||
buffer_pool: Arc<BufferPool>,
|
||||
// Shared structures of a Database are the parts that are common to multiple threads that might
|
||||
// create DB connections.
|
||||
_shared_page_cache: Arc<RwLock<DumbLruPageCache>>,
|
||||
_shared_page_cache: Arc<RwLock<PageCache>>,
|
||||
shared_wal: Arc<RwLock<WalFileShared>>,
|
||||
db_state: Arc<AtomicDbState>,
|
||||
init_lock: Arc<Mutex<()>>,
|
||||
@@ -385,7 +385,7 @@ impl Database {
|
||||
DbState::Initialized
|
||||
};
|
||||
|
||||
let shared_page_cache = Arc::new(RwLock::new(DumbLruPageCache::default()));
|
||||
let shared_page_cache = Arc::new(RwLock::new(PageCache::default()));
|
||||
let syms = SymbolTable::new();
|
||||
let arena_size = if std::env::var("TESTING").is_ok_and(|v| v.eq_ignore_ascii_case("true")) {
|
||||
BufferPool::TEST_ARENA_SIZE
|
||||
@@ -576,7 +576,7 @@ impl Database {
|
||||
self.db_file.clone(),
|
||||
Some(wal),
|
||||
self.io.clone(),
|
||||
Arc::new(RwLock::new(DumbLruPageCache::default())),
|
||||
Arc::new(RwLock::new(PageCache::default())),
|
||||
buffer_pool.clone(),
|
||||
db_state,
|
||||
self.init_lock.clone(),
|
||||
@@ -599,7 +599,7 @@ impl Database {
|
||||
self.db_file.clone(),
|
||||
None,
|
||||
self.io.clone(),
|
||||
Arc::new(RwLock::new(DumbLruPageCache::default())),
|
||||
Arc::new(RwLock::new(PageCache::default())),
|
||||
buffer_pool.clone(),
|
||||
db_state,
|
||||
Arc::new(Mutex::new(())),
|
||||
|
||||
@@ -7376,7 +7376,7 @@ mod tests {
|
||||
schema::IndexColumn,
|
||||
storage::{
|
||||
database::DatabaseFile,
|
||||
page_cache::DumbLruPageCache,
|
||||
page_cache::PageCache,
|
||||
pager::{AtomicDbState, DbState},
|
||||
sqlite3_ondisk::PageSize,
|
||||
},
|
||||
@@ -8631,7 +8631,7 @@ mod tests {
|
||||
db_file,
|
||||
Some(wal),
|
||||
io,
|
||||
Arc::new(parking_lot::RwLock::new(DumbLruPageCache::new(10))),
|
||||
Arc::new(parking_lot::RwLock::new(PageCache::new(10))),
|
||||
buffer_pool,
|
||||
Arc::new(AtomicDbState::new(DbState::Uninitialized)),
|
||||
Arc::new(Mutex::new(())),
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,7 +25,7 @@ use std::sync::{Arc, Mutex};
|
||||
use tracing::{instrument, trace, Level};
|
||||
|
||||
use super::btree::btree_init_page;
|
||||
use super::page_cache::{CacheError, CacheResizeResult, DumbLruPageCache, PageCacheKey};
|
||||
use super::page_cache::{CacheError, CacheResizeResult, PageCache, PageCacheKey};
|
||||
use super::sqlite3_ondisk::begin_write_btree_page;
|
||||
use super::wal::CheckpointMode;
|
||||
use crate::storage::encryption::{CipherMode, EncryptionContext, EncryptionKey};
|
||||
@@ -129,7 +129,7 @@ pub struct PageInner {
|
||||
/// requests unpinning via [Page::unpin], the pin count will still be >0 if the outer
|
||||
/// code path has not yet requested to unpin the page as well.
|
||||
///
|
||||
/// Note that [DumbLruPageCache::clear] evicts the pages even if pinned, so as long as
|
||||
/// Note that [PageCache::clear] evicts the pages even if pinned, so as long as
|
||||
/// we clear the page cache on errors, pins will not 'leak'.
|
||||
pub pin_count: AtomicUsize,
|
||||
/// The WAL frame number this page was loaded from (0 if loaded from main DB file)
|
||||
@@ -464,7 +464,7 @@ pub struct Pager {
|
||||
/// in-memory databases, ephemeral tables and ephemeral indexes do not have a WAL.
|
||||
pub(crate) wal: Option<Rc<RefCell<dyn Wal>>>,
|
||||
/// A page cache for the database.
|
||||
page_cache: Arc<RwLock<DumbLruPageCache>>,
|
||||
page_cache: Arc<RwLock<PageCache>>,
|
||||
/// Buffer pool for temporary data storage.
|
||||
pub buffer_pool: Arc<BufferPool>,
|
||||
/// I/O interface for input/output operations.
|
||||
@@ -564,7 +564,7 @@ impl Pager {
|
||||
db_file: Arc<dyn DatabaseStorage>,
|
||||
wal: Option<Rc<RefCell<dyn Wal>>>,
|
||||
io: Arc<dyn crate::io::IO>,
|
||||
page_cache: Arc<RwLock<DumbLruPageCache>>,
|
||||
page_cache: Arc<RwLock<PageCache>>,
|
||||
buffer_pool: Arc<BufferPool>,
|
||||
db_state: Arc<AtomicDbState>,
|
||||
init_lock: Arc<Mutex<()>>,
|
||||
@@ -1153,7 +1153,7 @@ impl Pager {
|
||||
&self,
|
||||
page_idx: usize,
|
||||
page: PageRef,
|
||||
page_cache: &mut DumbLruPageCache,
|
||||
page_cache: &mut PageCache,
|
||||
) -> Result<()> {
|
||||
let page_key = PageCacheKey::new(page_idx);
|
||||
match page_cache.insert(page_key, page.clone()) {
|
||||
@@ -1981,7 +1981,7 @@ impl Pager {
|
||||
trunk_page.get_contents().as_ptr().fill(0);
|
||||
let page_key = PageCacheKey::new(trunk_page.get().id);
|
||||
{
|
||||
let mut page_cache = self.page_cache.write();
|
||||
let page_cache = self.page_cache.read();
|
||||
turso_assert!(
|
||||
page_cache.contains_key(&page_key),
|
||||
"page {} is not in cache",
|
||||
@@ -2013,7 +2013,7 @@ impl Pager {
|
||||
leaf_page.get_contents().as_ptr().fill(0);
|
||||
let page_key = PageCacheKey::new(leaf_page.get().id);
|
||||
{
|
||||
let mut page_cache = self.page_cache.write();
|
||||
let page_cache = self.page_cache.read();
|
||||
turso_assert!(
|
||||
page_cache.contains_key(&page_key),
|
||||
"page {} is not in cache",
|
||||
@@ -2402,14 +2402,14 @@ mod tests {
|
||||
|
||||
use parking_lot::RwLock;
|
||||
|
||||
use crate::storage::page_cache::{DumbLruPageCache, PageCacheKey};
|
||||
use crate::storage::page_cache::{PageCache, PageCacheKey};
|
||||
|
||||
use super::Page;
|
||||
|
||||
#[test]
|
||||
fn test_shared_cache() {
|
||||
// ensure cache can be shared between threads
|
||||
let cache = Arc::new(RwLock::new(DumbLruPageCache::new(10)));
|
||||
let cache = Arc::new(RwLock::new(PageCache::new(10)));
|
||||
|
||||
let thread = {
|
||||
let cache = cache.clone();
|
||||
@@ -2442,7 +2442,7 @@ mod ptrmap_tests {
|
||||
use crate::io::{MemoryIO, OpenFlags, IO};
|
||||
use crate::storage::buffer_pool::BufferPool;
|
||||
use crate::storage::database::{DatabaseFile, DatabaseStorage};
|
||||
use crate::storage::page_cache::DumbLruPageCache;
|
||||
use crate::storage::page_cache::PageCache;
|
||||
use crate::storage::pager::Pager;
|
||||
use crate::storage::sqlite3_ondisk::PageSize;
|
||||
use crate::storage::wal::{WalFile, WalFileShared};
|
||||
@@ -2471,7 +2471,7 @@ mod ptrmap_tests {
|
||||
let pages = initial_db_pages + 10;
|
||||
let sz = std::cmp::max(std::cmp::min(pages, 64), pages);
|
||||
let buffer_pool = BufferPool::begin_init(&io, (sz * page_size) as usize);
|
||||
let page_cache = Arc::new(RwLock::new(DumbLruPageCache::new(sz as usize)));
|
||||
let page_cache = Arc::new(RwLock::new(PageCache::new(sz as usize)));
|
||||
|
||||
let wal = Rc::new(RefCell::new(WalFile::new(
|
||||
io.clone(),
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::storage::btree::{
|
||||
integrity_check, IntegrityCheckError, IntegrityCheckState, PageCategory,
|
||||
};
|
||||
use crate::storage::database::DatabaseFile;
|
||||
use crate::storage::page_cache::DumbLruPageCache;
|
||||
use crate::storage::page_cache::PageCache;
|
||||
use crate::storage::pager::{AtomicDbState, CreateBTreeFlags, DbState};
|
||||
use crate::storage::sqlite3_ondisk::read_varint;
|
||||
use crate::translate::collate::CollationSeq;
|
||||
@@ -6996,7 +6996,7 @@ pub fn op_open_ephemeral(
|
||||
.get();
|
||||
|
||||
let buffer_pool = program.connection._db.buffer_pool.clone();
|
||||
let page_cache = Arc::new(RwLock::new(DumbLruPageCache::default()));
|
||||
let page_cache = Arc::new(RwLock::new(PageCache::default()));
|
||||
|
||||
let pager = Rc::new(Pager::new(
|
||||
db_file,
|
||||
|
||||
Reference in New Issue
Block a user