diff --git a/fugue-core/src/project/mod.rs b/fugue-core/src/project/mod.rs index 5fb79df..54dd94f 100644 --- a/fugue-core/src/project/mod.rs +++ b/fugue-core/src/project/mod.rs @@ -34,7 +34,7 @@ pub struct ProjectRawViewMmaped { } pub struct ProjectRawViewMmapedReader<'a> { - backing: MmapTableReader<'a, U64, Vec>, + backing: MmapTableReader<'a, U64>, ranges: &'a [Range
], } @@ -82,9 +82,7 @@ impl ProjectRawView for ProjectRawViewMmaped { let mut ranges = Vec::new(); let mut backing = MmapTable::temporary("binary-view").map_err(ProjectRawViewError::backing)?; - let mut tx = backing - .writer::>() - .map_err(ProjectRawViewError::backing)?; + let mut tx = backing.writer().map_err(ProjectRawViewError::backing)?; // Load the segments into the backing store (and keep track of the ranges) // @@ -100,7 +98,7 @@ impl ProjectRawView for ProjectRawViewMmaped { // TODO: can we avoid owning the data--it seems needless for what we want to do with // it here? // - tx.set(addr, data.into_owned()) + tx.set(addr, data.as_ref()) .map_err(ProjectRawViewError::backing)?; ranges.push(addr..addr + size); @@ -283,7 +281,7 @@ mod test { let input = BytesOrMapping::from_file("tests/ls.elf")?; // Create the project from the mapping object - let _prj = Project::::new(&Object::new(input)?)?; + let _prj = Project::::new(&Object::new(input)?)?; Ok(()) } diff --git a/fugue-core/src/util/table.rs b/fugue-core/src/util/table.rs index 9a17c91..c1ba2f7 100644 --- a/fugue-core/src/util/table.rs +++ b/fugue-core/src/util/table.rs @@ -14,7 +14,7 @@ pub struct MmapTable { temporary: Option, } -pub struct MmapTableReader<'a, K, T> +pub struct MmapTypedTableReader<'a, K, T> where T: Archive, { @@ -23,7 +23,7 @@ where _marker: PhantomData, } -pub struct MmapTableWriter<'a, K, T> +pub struct MmapTypedTableWriter<'a, K, T> where T: Archive, { @@ -32,6 +32,16 @@ where _marker: PhantomData, } +pub struct MmapTableReader<'a, K> { + table: &'a MmapTable, + txn: RoTxn<'a>, +} + +pub struct MmapTableWriter<'a, K> { + table: &'a MmapTable, + txn: RwTxn<'a>, +} + #[derive(Debug, Error)] pub enum MmapTableError { #[error(transparent)] @@ -102,7 +112,25 @@ where Ok(slf) } - pub fn reader<'a, T>(&'a self) -> Result, MmapTableError> + pub fn reader<'a>(&'a self) -> Result, MmapTableError> { + let txn = self + .environment + .read_txn() + .map_err(MmapTableError::database)?; + + Ok(MmapTableReader { table: self, txn }) + } + + pub fn writer<'a>(&'a mut self) -> Result, MmapTableError> { + let txn = self + .environment + .write_txn() + .map_err(MmapTableError::database)?; + + Ok(MmapTableWriter { table: self, txn }) + } + + pub fn typed_reader<'a, T>(&'a self) -> Result, MmapTableError> where T: Archive, { @@ -110,14 +138,17 @@ where .environment .read_txn() .map_err(MmapTableError::database)?; - Ok(MmapTableReader { + + Ok(MmapTypedTableReader { table: self, txn, _marker: PhantomData, }) } - pub fn writer<'a, T>(&'a mut self) -> Result, MmapTableError> + pub fn typed_writer<'a, T>( + &'a mut self, + ) -> Result, MmapTableError> where T: Archive, { @@ -125,7 +156,8 @@ where .environment .write_txn() .map_err(MmapTableError::database)?; - Ok(MmapTableWriter { + + Ok(MmapTypedTableWriter { table: self, txn, _marker: PhantomData, @@ -133,7 +165,7 @@ where } } -impl<'a, K, T> MmapTableReader<'a, K, T> +impl<'a, K, T> MmapTypedTableReader<'a, K, T> where T: Archive, { @@ -152,7 +184,20 @@ where } } -impl<'a, K, T> MmapTableWriter<'a, K, T> +impl<'a, K> MmapTableReader<'a, K> { + pub fn get(&self, key: impl AsRef) -> Result, MmapTableError> + where + K: for<'b> BytesEncode<'b, EItem = KE>, + KE: ?Sized + 'static, + { + self.table + .database + .get(&self.txn, key.as_ref()) + .map_err(MmapTableError::database) + } +} + +impl<'a, K, T> MmapTypedTableWriter<'a, K, T> where T: Archive + Serialize>, { @@ -216,6 +261,66 @@ where } } +impl<'a, K> MmapTableWriter<'a, K> { + pub fn get(&self, key: impl AsRef) -> Result, MmapTableError> + where + K: for<'b> BytesEncode<'b, EItem = KE>, + KE: ?Sized + 'static, + { + self.table + .database + .get(&self.txn, key.as_ref()) + .map_err(MmapTableError::database) + } + + pub fn set( + &mut self, + key: impl AsRef, + val: impl AsRef<[u8]>, + ) -> Result<(), MmapTableError> + where + K: for<'b> BytesEncode<'b, EItem = KE>, + KE: ?Sized + 'static, + { + self.table + .database + .put(&mut self.txn, key.as_ref(), val.as_ref()) + .map_err(MmapTableError::database)?; + + Ok(()) + } + + pub fn clear(&mut self) -> Result<(), MmapTableError> { + self.table + .database + .clear(&mut self.txn) + .map_err(MmapTableError::database)?; + + Ok(()) + } + + pub fn remove(&mut self, key: impl AsRef) -> Result<(), MmapTableError> + where + K: for<'b> BytesEncode<'b, EItem = KE>, + KE: ?Sized + 'static, + { + self.table + .database + .delete(&mut self.txn, key.as_ref()) + .map_err(MmapTableError::database)?; + + Ok(()) + } + + pub fn abort(self) { + self.txn.abort() + } + + pub fn commit(self) -> Result<(), MmapTableError> { + self.txn.commit().map_err(MmapTableError::database) + } +} + #[cfg(test)] mod test { use heed::types::Str; @@ -227,7 +332,7 @@ mod test { let mut pt = MmapTable::::temporary("project")?; { - let mut writer = pt.writer::>()?; + let mut writer = pt.writer()?; writer.set("mapping1", vec![0u8; 10])?; writer.set("mapping2", vec![0u8; 100 * 1024 * 1024])?; @@ -237,7 +342,7 @@ mod test { } { - let reader = pt.reader::>()?; + let reader = pt.reader()?; let bytes = reader.get("mapping2")?.unwrap(); diff --git a/fugue-ir/src/address.rs b/fugue-ir/src/address.rs index 8af2bb9..e347f0b 100644 --- a/fugue-ir/src/address.rs +++ b/fugue-ir/src/address.rs @@ -36,6 +36,18 @@ impl Address { } } +impl AsRef
for Address { + fn as_ref(&self) -> &Address { + self + } +} + +impl AsRef for Address { + fn as_ref(&self) -> &u64 { + &self.0 + } +} + impl PartialEq for Address { fn eq(&self, other: &u8) -> bool { self.0 == *other as u64