diff --git a/save/Cargo.toml b/save/Cargo.toml index c28141f4..3a8416c9 100644 --- a/save/Cargo.toml +++ b/save/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] prost = "0.12.2" -redb = "1.0" +redb = "2.0" thiserror = "1.0.38" zstd = { package = "zstd-safe", version = "7.1.0", default-features = false, features = ["std", "experimental"] } diff --git a/save/benches/bench.rs b/save/benches/bench.rs index fb958487..cac2bdb9 100644 --- a/save/benches/bench.rs +++ b/save/benches/bench.rs @@ -27,7 +27,7 @@ fn save(c: &mut Criterion) { .collect::>(); (file, save, node_ids) }, - |(_file, mut save, node_ids)| { + |(_file, save, node_ids)| { let mut tx = save.write().unwrap(); let mut writer = tx.get().unwrap(); for i in node_ids { @@ -49,7 +49,7 @@ fn save(c: &mut Criterion) { b.iter_batched( || { let file = tempfile::NamedTempFile::new().unwrap(); - let mut save = Save::open(file.path(), 12).unwrap(); + let save = Save::open(file.path(), 12).unwrap(); let node_ids = (&mut rng) .sample_iter(rand::distributions::Standard) .take(count as usize) @@ -66,8 +66,7 @@ fn save(c: &mut Criterion) { (file, save, node_ids) }, |(_file, save, node_ids)| { - let read = save.read().unwrap(); - let mut read = read.get().unwrap(); + let mut read = save.read().unwrap(); for i in node_ids { black_box(read.get_voxel_node(i).unwrap().unwrap()); } diff --git a/save/src/lib.rs b/save/src/lib.rs index f2cf7d6d..65f519f3 100644 --- a/save/src/lib.rs +++ b/save/src/lib.rs @@ -19,7 +19,7 @@ impl Save { let meta = { let tx = db.begin_read().map_err(redb::Error::from)?; // Intermediate variable to make borrowck happy - let meta = match tx.open_table(META_TABLE) { + match tx.open_table(META_TABLE) { Ok(meta) => { let Some(value) = meta.get(&[][..]).map_err(redb::Error::from)? else { return Err(OpenError::MissingMeta); @@ -39,8 +39,7 @@ impl Save { defaults } Err(e) => return Err(OpenError::Db(DbError(e.into()))), - }; - meta + } }; Ok(Self { meta, db }) } @@ -50,12 +49,18 @@ impl Save { &self.meta } - pub fn read(&self) -> Result, DbError> { + pub fn read(&self) -> Result { let tx = self.db.begin_read().map_err(redb::Error::from)?; - Ok(ReaderGuard { tx }) + Ok(Reader { + voxel_nodes: tx.open_table(VOXEL_NODE_TABLE)?, + entity_nodes: tx.open_table(ENTITY_NODE_TABLE)?, + characters: tx.open_table(CHARACTERS_BY_NAME_TABLE)?, + dctx: dctx(), + accum: Vec::new(), + }) } - pub fn write(&mut self) -> Result, DbError> { + pub fn write(&self) -> Result { let tx = self.db.begin_write().map_err(redb::Error::from)?; Ok(WriterGuard { tx }) } @@ -78,22 +83,6 @@ fn init_meta_table(db: &Database, value: &Meta) -> Result<(), redb::Error> { Ok(()) } -pub struct ReaderGuard<'a> { - tx: redb::ReadTransaction<'a>, -} - -impl ReaderGuard<'_> { - pub fn get(&self) -> Result, DbError> { - Ok(Reader { - voxel_nodes: self.tx.open_table(VOXEL_NODE_TABLE)?, - entity_nodes: self.tx.open_table(ENTITY_NODE_TABLE)?, - characters: self.tx.open_table(CHARACTERS_BY_NAME_TABLE)?, - dctx: dctx(), - accum: Vec::new(), - }) - } -} - fn dctx() -> zstd::DCtx<'static> { let mut dctx = zstd::DCtx::create(); dctx.set_parameter(zstd::DParameter::Format(zstd::FrameFormat::Magicless)) @@ -101,15 +90,15 @@ fn dctx() -> zstd::DCtx<'static> { dctx } -pub struct Reader<'a> { - voxel_nodes: redb::ReadOnlyTable<'a, u128, &'static [u8]>, - entity_nodes: redb::ReadOnlyTable<'a, u128, &'static [u8]>, - characters: redb::ReadOnlyTable<'a, &'static str, &'static [u8]>, +pub struct Reader { + voxel_nodes: redb::ReadOnlyTable, + entity_nodes: redb::ReadOnlyTable, + characters: redb::ReadOnlyTable<&'static str, &'static [u8]>, dctx: zstd::DCtx<'static>, accum: Vec, } -impl Reader<'_> { +impl Reader { pub fn get_voxel_node(&mut self, node_id: u128) -> Result, GetError> { let Some(node) = self.voxel_nodes.get(&node_id)? else { return Ok(None); @@ -173,12 +162,12 @@ fn decompress( } } -pub struct WriterGuard<'a> { - tx: redb::WriteTransaction<'a>, +pub struct WriterGuard { + tx: redb::WriteTransaction, } -impl<'a> WriterGuard<'a> { - pub fn get(&mut self) -> Result, DbError> { +impl WriterGuard { + pub fn get(&mut self) -> Result, DbError> { Ok(Writer { voxel_nodes: self .tx @@ -213,16 +202,16 @@ fn cctx() -> zstd::CCtx<'static> { cctx } -pub struct Writer<'save, 'guard> { - voxel_nodes: redb::Table<'save, 'guard, u128, &'static [u8]>, - entity_nodes: redb::Table<'save, 'guard, u128, &'static [u8]>, - characters: redb::Table<'save, 'guard, &'static str, &'static [u8]>, +pub struct Writer<'guard> { + voxel_nodes: redb::Table<'guard, u128, &'static [u8]>, + entity_nodes: redb::Table<'guard, u128, &'static [u8]>, + characters: redb::Table<'guard, &'static str, &'static [u8]>, cctx: zstd::CCtx<'static>, plain: Vec, compressed: Vec, } -impl Writer<'_, '_> { +impl Writer<'_> { pub fn put_voxel_node(&mut self, node_id: u128, state: &VoxelNode) -> Result<(), DbError> { prepare(&mut self.cctx, &mut self.plain, &mut self.compressed, state); self.voxel_nodes.insert(node_id, &*self.compressed)?; diff --git a/save/tests/heavy.rs b/save/tests/heavy.rs index 5e6c3c02..00751daf 100644 --- a/save/tests/heavy.rs +++ b/save/tests/heavy.rs @@ -8,7 +8,7 @@ use rand::{rngs::SmallRng, Rng, SeedableRng}; fn write() { let mut rng = SmallRng::from_entropy(); let file = tempfile::NamedTempFile::new().unwrap(); - let mut save = Save::open(file.path(), 12).unwrap(); + let save = Save::open(file.path(), 12).unwrap(); let node = save::VoxelNode { chunks: vec![save::Chunk { vertex: 0, diff --git a/save/tests/tests.rs b/save/tests/tests.rs index fe7fc4e1..bb97efbe 100644 --- a/save/tests/tests.rs +++ b/save/tests/tests.rs @@ -15,7 +15,7 @@ fn persist_meta() { #[test] fn persist_node() { let file = tempfile::NamedTempFile::new().unwrap(); - let mut save = Save::open(file.path(), 12).unwrap(); + let save = Save::open(file.path(), 12).unwrap(); let node = save::VoxelNode { chunks: vec![save::Chunk { vertex: 0, @@ -31,20 +31,14 @@ fn persist_node() { writer_guard.commit().unwrap(); assert_eq!( node, - save.read() - .unwrap() - .get() - .unwrap() - .get_voxel_node(0) - .unwrap() - .unwrap() + save.read().unwrap().get_voxel_node(0).unwrap().unwrap() ); } #[test] fn persist_character() { let file = tempfile::NamedTempFile::new().unwrap(); - let mut save = Save::open(file.path(), 12).unwrap(); + let save = Save::open(file.path(), 12).unwrap(); let mut writer_guard = save.write().unwrap(); let mut writer = writer_guard.get().unwrap(); let mut rng = SmallRng::from_entropy(); @@ -61,12 +55,6 @@ fn persist_character() { let save = Save::open(file.path(), 12).unwrap(); assert_eq!( ch, - save.read() - .unwrap() - .get() - .unwrap() - .get_character("asdf") - .unwrap() - .unwrap() + save.read().unwrap().get_character("asdf").unwrap().unwrap() ); } diff --git a/server/src/sim.rs b/server/src/sim.rs index 0793ac57..e7206989 100644 --- a/server/src/sim.rs +++ b/server/src/sim.rs @@ -111,8 +111,7 @@ impl Sim { } fn load_all_voxels(&mut self, save: &save::Save) -> anyhow::Result<()> { - let read_guard = save.read()?; - let mut read = read_guard.get()?; + let mut read = save.read()?; for node_hash in read.get_all_voxel_node_ids()? { let Some(voxel_node) = read.get_voxel_node(node_hash)? else { continue;