From 07a679e7451423dfee19628a83bba48672cf7bb1 Mon Sep 17 00:00:00 2001 From: Avinash Sajjanshetty <640792+avinassh@users.noreply.github.com> Date: Tue, 4 Jun 2024 18:05:00 +0530 Subject: [PATCH] Generate `Eitherxx` variants (#1438) * Create a drop in replacement for `Either` with `Any` * generate Eitherxx variants * generate Eitherxx variants --------- Co-authored-by: ad hoc --- .../src/connection/connection_manager.rs | 1 - libsql-server/src/connection/libsql.rs | 12 +- libsql-server/src/lib.rs | 4 +- libsql-server/src/schema/scheduler.rs | 2 +- libsql-sys/src/wal/either.rs | 404 ++++++++---------- 5 files changed, 185 insertions(+), 238 deletions(-) diff --git a/libsql-server/src/connection/connection_manager.rs b/libsql-server/src/connection/connection_manager.rs index 1edffd2033..ed7ca5aef4 100644 --- a/libsql-server/src/connection/connection_manager.rs +++ b/libsql-server/src/connection/connection_manager.rs @@ -19,7 +19,6 @@ use super::libsql::Connection; use super::TXN_TIMEOUT; pub type ConnId = u64; - pub type InnerWalManager = Either>; pub type InnerWal = Either>; pub type ManagedConnectionWal = WrappedWal; diff --git a/libsql-server/src/connection/libsql.rs b/libsql-server/src/connection/libsql.rs index 8276d7fad4..21730d9217 100644 --- a/libsql-server/src/connection/libsql.rs +++ b/libsql-server/src/connection/libsql.rs @@ -182,7 +182,7 @@ impl LibSqlConnection { Default::default(), Arc::new(|_| unreachable!()), ConnectionManager::new(TXN_TIMEOUT), - Arc::new(|| Either::Left(Sqlite3WalManager::default())), + Arc::new(|| Either::A(Sqlite3WalManager::default())), ) .await .unwrap() @@ -769,7 +769,7 @@ mod test { None, Default::default(), Arc::new(|_| unreachable!()), - Arc::new(|| Either::Left(Sqlite3WalManager::default())), + Arc::new(|| Either::A(Sqlite3WalManager::default())), ) .await .unwrap(); @@ -816,7 +816,7 @@ mod test { None, Default::default(), Arc::new(|_| unreachable!()), - Arc::new(|| Either::Left(Sqlite3WalManager::default())), + Arc::new(|| Either::A(Sqlite3WalManager::default())), ) .await .unwrap(); @@ -867,7 +867,7 @@ mod test { None, Default::default(), Arc::new(|_| unreachable!()), - Arc::new(|| Either::Left(Sqlite3WalManager::default())), + Arc::new(|| Either::A(Sqlite3WalManager::default())), ) .await .unwrap(); @@ -952,7 +952,7 @@ mod test { None, Default::default(), Arc::new(|_| unreachable!()), - Arc::new(|| Either::Left(Sqlite3WalManager::default())), + Arc::new(|| Either::A(Sqlite3WalManager::default())), ) .await .unwrap(); @@ -1038,7 +1038,7 @@ mod test { None, Default::default(), Arc::new(|_| unreachable!()), - Arc::new(|| Either::Left(Sqlite3WalManager::default())), + Arc::new(|| Either::A(Sqlite3WalManager::default())), ) .await .unwrap(); diff --git a/libsql-server/src/lib.rs b/libsql-server/src/lib.rs index 659e5dea5e..1cf668f26e 100644 --- a/libsql-server/src/lib.rs +++ b/libsql-server/src/lib.rs @@ -682,11 +682,11 @@ where }); tracing::info!("using libsql wal"); - Ok((Arc::new(move || Either::Right(wal.clone())), shutdown_fut)) + Ok((Arc::new(move || Either::B(wal.clone())), shutdown_fut)) } else { tracing::info!("using sqlite3 wal"); Ok(( - Arc::new(|| Either::Left(Sqlite3WalManager::default())), + Arc::new(|| Either::A(Sqlite3WalManager::default())), Box::pin(ready(Ok(()))), )) } diff --git a/libsql-server/src/schema/scheduler.rs b/libsql-server/src/schema/scheduler.rs index 747337bc06..bb9e0fe644 100644 --- a/libsql-server/src/schema/scheduler.rs +++ b/libsql-server/src/schema/scheduler.rs @@ -896,7 +896,7 @@ mod test { bottomless_replication: None, scripted_backup: None, migration_scheduler, - make_wal_manager: Arc::new(|| Either::Left(Sqlite3WalManager::default())), + make_wal_manager: Arc::new(|| Either::A(Sqlite3WalManager::default())), } } diff --git a/libsql-sys/src/wal/either.rs b/libsql-sys/src/wal/either.rs index 6e6331a698..1f9a67609e 100644 --- a/libsql-sys/src/wal/either.rs +++ b/libsql-sys/src/wal/either.rs @@ -1,256 +1,204 @@ -use super::{Wal, WalManager}; -#[derive(Debug, Clone)] -pub enum Either { - Left(L), - Right(R), -} - -impl Wal for Either -where - L: Wal, - R: Wal, -{ - fn limit(&mut self, size: i64) { - match self { - Either::Left(l) => l.limit(size), - Either::Right(r) => r.limit(size), - } - } - - fn begin_read_txn(&mut self) -> super::Result { - match self { - Either::Left(l) => l.begin_read_txn(), - Either::Right(r) => r.begin_read_txn(), - } - } +macro_rules! create_either { + ( $name:ident< $($t:ident),* >) => { + #[derive(Debug, Clone)] + pub enum $name< $( $t ),* > { + $( $t($t) ),* + } + + impl< $( $t ),* > $crate::wal::Wal for $name< $( $t ),* > + where + $( $t: $crate::wal::Wal ),* + { + fn limit(&mut self, size: i64) { + match self { + $( $name::$t(inner) => inner.limit(size) ),* + } + } - fn end_read_txn(&mut self) { - match self { - Either::Left(l) => l.end_read_txn(), - Either::Right(r) => r.end_read_txn(), - } - } + fn begin_read_txn(&mut self) -> super::Result { + match self { + $( $name::$t(inner) => inner.begin_read_txn() ),* + } + } - fn find_frame( - &mut self, - page_no: std::num::NonZeroU32, - ) -> super::Result> { - match self { - Either::Left(l) => l.find_frame(page_no), - Either::Right(r) => r.find_frame(page_no), - } - } + fn end_read_txn(&mut self) { + match self { + $( $name::$t(inner) => inner.end_read_txn() ),* + } + } - fn read_frame( - &mut self, - frame_no: std::num::NonZeroU32, - buffer: &mut [u8], - ) -> super::Result<()> { - match self { - Either::Left(l) => l.read_frame(frame_no, buffer), - Either::Right(r) => r.read_frame(frame_no, buffer), - } - } + fn find_frame(&mut self, page_no: std::num::NonZeroU32) -> super::Result> { + match self { + $( $name::$t(inner) => inner.find_frame(page_no) ),* + } + } - fn db_size(&self) -> u32 { - match self { - Either::Left(l) => l.db_size(), - Either::Right(r) => r.db_size(), - } - } + fn read_frame(&mut self, frame_no: std::num::NonZeroU32, buffer: &mut [u8]) -> super::Result<()> { + match self { + $( $name::$t(inner) => inner.read_frame(frame_no, buffer) ),* + } + } - fn begin_write_txn(&mut self) -> super::Result<()> { - match self { - Either::Left(l) => l.begin_write_txn(), - Either::Right(r) => r.begin_write_txn(), - } - } + fn db_size(&self) -> u32 { + match self { + $( $name::$t(inner) => inner.db_size() ),* + } + } - fn end_write_txn(&mut self) -> super::Result<()> { - match self { - Either::Left(l) => l.end_write_txn(), - Either::Right(r) => r.end_write_txn(), - } - } + fn begin_write_txn(&mut self) -> super::Result<()> { + match self { + $( $name::$t(inner) => inner.begin_write_txn() ),* + } + } - fn undo(&mut self, handler: Option<&mut U>) -> super::Result<()> { - match self { - Either::Left(l) => l.undo(handler), - Either::Right(r) => r.undo(handler), - } - } + fn end_write_txn(&mut self) -> super::Result<()> { + match self { + $( $name::$t(inner) => inner.end_write_txn() ),* + } + } - fn savepoint(&mut self, rollback_data: &mut [u32]) { - match self { - Either::Left(l) => l.savepoint(rollback_data), - Either::Right(r) => r.savepoint(rollback_data), - } - } + fn undo(&mut self, handler: Option<&mut U>) -> super::Result<()> { + match self { + $( $name::$t(inner) => inner.undo(handler) ),* + } + } - fn savepoint_undo(&mut self, rollback_data: &mut [u32]) -> super::Result<()> { - match self { - Either::Left(l) => l.savepoint_undo(rollback_data), - Either::Right(r) => r.savepoint_undo(rollback_data), - } - } + fn savepoint(&mut self, rollback_data: &mut [u32]) { + match self { + $( $name::$t(inner) => inner.savepoint(rollback_data) ),* + } + } - fn insert_frames( - &mut self, - page_size: std::ffi::c_int, - page_headers: &mut super::PageHeaders, - size_after: u32, - is_commit: bool, - sync_flags: std::ffi::c_int, - ) -> super::Result { - match self { - Either::Left(l) => { - l.insert_frames(page_size, page_headers, size_after, is_commit, sync_flags) + fn savepoint_undo(&mut self, rollback_data: &mut [u32]) -> super::Result<()> { + match self { + $( $name::$t(inner) => inner.savepoint_undo(rollback_data) ),* + } } - Either::Right(r) => { - r.insert_frames(page_size, page_headers, size_after, is_commit, sync_flags) + + fn insert_frames( + &mut self, + page_size: std::ffi::c_int, + page_headers: &mut super::PageHeaders, + size_after: u32, + is_commit: bool, + sync_flags: std::ffi::c_int, + ) -> super::Result { + match self { + $( $name::$t(inner) => inner.insert_frames(page_size, page_headers, size_after, is_commit, sync_flags) ),* + } } - } - } - fn checkpoint( - &mut self, - db: &mut super::Sqlite3Db, - mode: super::CheckpointMode, - busy_handler: Option<&mut dyn super::BusyHandler>, - sync_flags: u32, - // temporary scratch buffer - buf: &mut [u8], - checkpoint_cb: Option<&mut dyn super::CheckpointCallback>, - in_wal: Option<&mut i32>, - backfilled: Option<&mut i32>, - ) -> super::Result<()> { - match self { - Either::Left(l) => l.checkpoint( - db, - mode, - busy_handler, - sync_flags, - buf, - checkpoint_cb, - in_wal, - backfilled, - ), - Either::Right(r) => r.checkpoint( - db, - mode, - busy_handler, - sync_flags, - buf, - checkpoint_cb, - in_wal, - backfilled, - ), - } - } + fn checkpoint( + &mut self, + db: &mut super::Sqlite3Db, + mode: super::CheckpointMode, + busy_handler: Option<&mut dyn super::BusyHandler>, + sync_flags: u32, + buf: &mut [u8], + checkpoint_cb: Option<&mut dyn super::CheckpointCallback>, + in_wal: Option<&mut i32>, + backfilled: Option<&mut i32>, + ) -> super::Result<()> { + match self { + $( $name::$t(inner) => inner.checkpoint(db, mode, busy_handler, sync_flags, buf, checkpoint_cb, in_wal, backfilled) ),* + } + } - fn exclusive_mode(&mut self, op: std::ffi::c_int) -> super::Result<()> { - match self { - Either::Left(l) => l.exclusive_mode(op), - Either::Right(r) => r.exclusive_mode(op), - } - } + fn exclusive_mode(&mut self, op: std::ffi::c_int) -> super::Result<()> { + match self { + $( $name::$t(inner) => inner.exclusive_mode(op) ),* + } + } - fn uses_heap_memory(&self) -> bool { - match self { - Either::Left(l) => l.uses_heap_memory(), - Either::Right(r) => r.uses_heap_memory(), - } - } + fn uses_heap_memory(&self) -> bool { + match self { + $( $name::$t(inner) => inner.uses_heap_memory() ),* + } + } - fn set_db(&mut self, db: &mut super::Sqlite3Db) { - match self { - Either::Left(l) => l.set_db(db), - Either::Right(r) => r.set_db(db), - } - } + fn set_db(&mut self, db: &mut super::Sqlite3Db) { + match self { + $( $name::$t(inner) => inner.set_db(db) ),* + } + } - fn callback(&self) -> i32 { - match self { - Either::Left(l) => l.callback(), - Either::Right(r) => r.callback(), - } - } + fn callback(&self) -> i32 { + match self { + $( $name::$t(inner) => inner.callback() ),* + } + } - fn frames_in_wal(&self) -> u32 { - match self { - Either::Left(l) => l.frames_in_wal(), - Either::Right(r) => r.frames_in_wal(), + fn frames_in_wal(&self) -> u32 { + match self { + $( $name::$t(inner) => inner.frames_in_wal() ),* + } + } } - } -} -impl WalManager for Either -where - L: WalManager, - R: WalManager, -{ - type Wal = Either; + impl< $( $t ),* > $crate::wal::WalManager for $name< $( $t ),* > + where + $( $t: $crate::wal::WalManager ),* + { + type Wal = $name< $( $t::Wal ),* >; - fn use_shared_memory(&self) -> bool { - match self { - Either::Left(l) => l.use_shared_memory(), - Either::Right(r) => r.use_shared_memory(), - } - } + fn use_shared_memory(&self) -> bool { + match self { + $( $name::$t(inner) => inner.use_shared_memory() ),* + } + } - fn open( - &self, - vfs: &mut super::Vfs, - file: &mut super::Sqlite3File, - no_shm_mode: std::ffi::c_int, - max_log_size: i64, - db_path: &std::ffi::CStr, - ) -> super::Result { - match self { - Either::Left(l) => l - .open(vfs, file, no_shm_mode, max_log_size, db_path) - .map(Either::Left), - Either::Right(r) => r - .open(vfs, file, no_shm_mode, max_log_size, db_path) - .map(Either::Right), - } - } + fn open( + &self, + vfs: &mut super::Vfs, + file: &mut super::Sqlite3File, + no_shm_mode: std::ffi::c_int, + max_log_size: i64, + db_path: &std::ffi::CStr, + ) -> super::Result { + match self { + $( $name::$t(inner) => inner.open(vfs, file, no_shm_mode, max_log_size, db_path).map($name::$t) ),* + } + } - fn close( - &self, - wal: &mut Self::Wal, - db: &mut super::Sqlite3Db, - sync_flags: std::ffi::c_int, - scratch: Option<&mut [u8]>, - ) -> super::Result<()> { - match (self, wal) { - (Either::Left(l), Either::Left(wal)) => l.close(wal, db, sync_flags, scratch), - (Either::Right(r), Either::Right(wal)) => r.close(wal, db, sync_flags, scratch), - _ => unreachable!(), - } - } + fn close( + &self, + wal: &mut Self::Wal, + db: &mut super::Sqlite3Db, + sync_flags: std::ffi::c_int, + scratch: Option<&mut [u8]>, + ) -> super::Result<()> { + match (self, wal) { + $( + ($name::$t(inner), $name::$t(wal)) => inner.close(wal, db, sync_flags, scratch), + )* + _ => unreachable!(), + } + } - fn destroy_log(&self, vfs: &mut super::Vfs, db_path: &std::ffi::CStr) -> super::Result<()> { - match self { - Either::Left(l) => l.destroy_log(vfs, db_path), - Either::Right(r) => r.destroy_log(vfs, db_path), - } - } + fn destroy_log(&self, vfs: &mut super::Vfs, db_path: &std::ffi::CStr) -> super::Result<()> { + match self { + $( $name::$t(inner) => inner.destroy_log(vfs, db_path) ),* + } + } - fn log_exists(&self, vfs: &mut super::Vfs, db_path: &std::ffi::CStr) -> super::Result { - match self { - Either::Left(l) => l.log_exists(vfs, db_path), - Either::Right(r) => r.log_exists(vfs, db_path), - } - } + fn log_exists(&self, vfs: &mut super::Vfs, db_path: &std::ffi::CStr) -> super::Result { + match self { + $( $name::$t(inner) => inner.log_exists(vfs, db_path) ),* + } + } - fn destroy(self) - where - Self: Sized, - { - match self { - Either::Left(l) => l.destroy(), - Either::Right(r) => r.destroy(), + fn destroy(self) + where + Self: Sized, + { + match self { + $( $name::$t(inner) => inner.destroy() ),* + } + } } - } + }; } + +create_either!(Either); +create_either!(Either3); +create_either!(Either4);