cli: Add --experimental-mvcc option to enable MVCC

This commit is contained in:
Pekka Enberg
2025-03-06 09:06:51 +02:00
parent 5d0982f5db
commit 96175cccf7
14 changed files with 27 additions and 18 deletions

View File

@@ -25,7 +25,7 @@ pub unsafe extern "C" fn db_open(path: *const c_char) -> *mut c_void {
p if p.contains(":memory:") => Arc::new(limbo_core::MemoryIO::new()),
_ => Arc::new(limbo_core::PlatformIO::new().expect("Failed to create IO")),
};
let db = Database::open_file(io.clone(), path);
let db = Database::open_file(io.clone(), path, false);
match db {
Ok(db) => {
let conn = db.connect().unwrap();

View File

@@ -67,7 +67,7 @@ pub extern "system" fn Java_tech_turso_core_LimboDB_openUtf8<'local>(
}
};
let db = match Database::open_file(io.clone(), &path) {
let db = match Database::open_file(io.clone(), &path, false) {
Ok(db) => db,
Err(e) => {
set_err_msg_and_throw_exception(&mut env, obj, LIMBO_ETC, e.to_string());

View File

@@ -277,7 +277,7 @@ pub fn connect(path: &str) -> Result<Connection> {
io: Arc<dyn limbo_core::IO>,
path: &str,
) -> std::result::Result<Arc<limbo_core::Database>, PyErr> {
limbo_core::Database::open_file(io, path).map_err(|e| {
limbo_core::Database::open_file(io, path, false).map_err(|e| {
PyErr::new::<DatabaseError, _>(format!("Failed to open database: {:?}", e))
})
}

View File

@@ -42,12 +42,12 @@ impl Builder {
match self.path.as_str() {
":memory:" => {
let io: Arc<dyn limbo_core::IO> = Arc::new(limbo_core::MemoryIO::new());
let db = limbo_core::Database::open_file(io, self.path.as_str())?;
let db = limbo_core::Database::open_file(io, self.path.as_str(), false)?;
Ok(Database { inner: db })
}
path => {
let io: Arc<dyn limbo_core::IO> = Arc::new(limbo_core::PlatformIO::new()?);
let db = limbo_core::Database::open_file(io, path)?;
let db = limbo_core::Database::open_file(io, path, false)?;
Ok(Database { inner: db })
}
}

View File

@@ -32,7 +32,7 @@ impl Database {
let wal_path = format!("{}-wal", path);
let wal_shared = WalFileShared::open_shared(&io, wal_path.as_str(), page_size).unwrap();
let db = limbo_core::Database::open(io, page_io, wal_shared).unwrap();
let db = limbo_core::Database::open(io, page_io, wal_shared, false).unwrap();
let conn = db.connect().unwrap();
Database { db, conn }
}

View File

@@ -51,6 +51,8 @@ pub struct Opts {
\t'io-uring' when built for Linux with feature 'io_uring'\n"
)]
pub io: Io,
#[clap(long, help = "Enable experimental MVCC feature")]
pub experimental_mvcc: bool,
}
#[derive(Debug, Clone)]
@@ -210,7 +212,7 @@ impl<'a> Limbo<'a> {
_path => get_io(DbLocation::Path, opts.io)?,
}
};
let db = Database::open_file(io.clone(), &db_file)?;
let db = Database::open_file(io.clone(), &db_file, opts.experimental_mvcc)?;
let conn = db.connect().unwrap();
let h = LimboHelper::new(conn.clone(), io.clone());
rl.set_helper(Some(h));
@@ -412,7 +414,7 @@ impl<'a> Limbo<'a> {
}
};
self.io = Arc::clone(&io);
let db = Database::open_file(self.io.clone(), path)?;
let db = Database::open_file(self.io.clone(), path, self.opts.experimental_mvcc)?;
self.conn = db.connect().unwrap();
self.opts.db_file = path.to_string();
Ok(())

View File

@@ -65,6 +65,7 @@ pub struct Settings {
pub echo: bool,
pub is_stdout: bool,
pub io: Io,
pub experimental_mvcc: bool,
}
impl From<&Opts> for Settings {
@@ -80,6 +81,7 @@ impl From<&Opts> for Settings {
.as_ref()
.map_or(":memory:".to_string(), |p| p.to_string_lossy().to_string()),
io: opts.io,
experimental_mvcc: opts.experimental_mvcc,
}
}
}

View File

@@ -18,7 +18,7 @@ fn bench(criterion: &mut Criterion) {
#[allow(clippy::arc_with_non_send_sync)]
let io = Arc::new(PlatformIO::new().unwrap());
let db = Database::open_file(io.clone(), "../testing/testing.db").unwrap();
let db = Database::open_file(io.clone(), "../testing/testing.db", false).unwrap();
let limbo_conn = db.connect().unwrap();
let queries = [

View File

@@ -101,7 +101,7 @@ unsafe impl Sync for Database {}
impl Database {
#[cfg(feature = "fs")]
pub fn open_file(io: Arc<dyn IO>, path: &str) -> Result<Arc<Database>> {
pub fn open_file(io: Arc<dyn IO>, path: &str, enable_mvcc: bool) -> Result<Arc<Database>> {
use storage::wal::WalFileShared;
let file = io.open_file(path, OpenFlags::Create, true)?;
@@ -112,7 +112,7 @@ impl Database {
io.run_once()?;
let page_size = db_header.lock().unwrap().page_size;
let wal_shared = WalFileShared::open_shared(&io, wal_path.as_str(), page_size)?;
Self::open(io, page_io, wal_shared)
Self::open(io, page_io, wal_shared, enable_mvcc)
}
#[allow(clippy::arc_with_non_send_sync)]
@@ -120,6 +120,7 @@ impl Database {
io: Arc<dyn IO>,
page_io: Arc<dyn DatabaseStorage>,
shared_wal: Arc<RwLock<WalFileShared>>,
enable_mvcc: bool,
) -> Result<Arc<Database>> {
let db_header = Pager::begin_open(page_io.clone())?;
io.run_once()?;

View File

@@ -2811,7 +2811,7 @@ mod tests {
.unwrap();
}
let io: Arc<dyn IO> = Arc::new(PlatformIO::new().unwrap());
let db = Database::open_file(io.clone(), path.to_str().unwrap()).unwrap();
let db = Database::open_file(io.clone(), path.to_str().unwrap(), false).unwrap();
db
}

View File

@@ -308,8 +308,12 @@ fn doublecheck(
) {
{
let mut env_ = env.lock().unwrap();
env_.db =
Database::open_file(env_.io.clone(), paths.doublecheck_db.to_str().unwrap()).unwrap();
env_.db = Database::open_file(
env_.io.clone(),
paths.doublecheck_db.to_str().unwrap(),
false,
)
.unwrap();
}
// Run the simulation again

View File

@@ -87,7 +87,7 @@ impl SimulatorEnv {
std::fs::remove_file(db_path).unwrap();
}
let db = match Database::open_file(io.clone(), db_path.to_str().unwrap()) {
let db = match Database::open_file(io.clone(), db_path.to_str().unwrap(), false) {
Ok(db) => db,
Err(e) => {
panic!("error opening simulator test file {:?}: {:?}", db_path, e);

View File

@@ -116,7 +116,7 @@ pub unsafe extern "C" fn sqlite3_open(
Err(_) => return SQLITE_MISUSE,
},
};
match limbo_core::Database::open_file(io, filename) {
match limbo_core::Database::open_file(io, filename, false) {
Ok(db) => {
let conn = db.connect().unwrap();
*db_out = Box::leak(Box::new(sqlite3::new(db, conn)));

View File

@@ -42,7 +42,7 @@ impl TempDatabase {
pub fn connect_limbo(&self) -> Rc<limbo_core::Connection> {
log::debug!("conneting to limbo");
let db = Database::open_file(self.io.clone(), self.path.to_str().unwrap()).unwrap();
let db = Database::open_file(self.io.clone(), self.path.to_str().unwrap(), false).unwrap();
let conn = db.connect().unwrap();
log::debug!("connected to limbo");
@@ -51,7 +51,7 @@ impl TempDatabase {
pub fn limbo_database(&self) -> Arc<limbo_core::Database> {
log::debug!("conneting to limbo");
Database::open_file(self.io.clone(), self.path.to_str().unwrap()).unwrap()
Database::open_file(self.io.clone(), self.path.to_str().unwrap(), false).unwrap()
}
}