diff --git a/Cargo.toml b/Cargo.toml index a744993..647c550 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ all-features = true [features] default = [] -disktree = [ +hexdb = [ "byteorder", "memmap", "serde", diff --git a/benches/benches.rs b/benches/benches.rs index d5e4215..625cb6c 100644 --- a/benches/benches.rs +++ b/benches/benches.rs @@ -48,13 +48,13 @@ fn set_lookup(c: &mut Criterion) { } } -#[cfg(not(feature = "disktree"))] +#[cfg(not(feature = "hexdb"))] fn disk_set_lookup(_c: &mut Criterion) {} -#[cfg(feature = "disktree")] +#[cfg(feature = "hexdb")] fn disk_set_lookup(c: &mut Criterion) { - use hextree::disktree::DiskTreeMap; - let mut group = c.benchmark_group("US915 DiskTreeSet lookup"); + use hextree::hexdb::HexDb; + let mut group = c.benchmark_group("US915 HexDbSet lookup"); let us915_disk_set = { let us915_set: HexTreeSet = PLAIN_US915_INDICES @@ -63,9 +63,9 @@ fn disk_set_lookup(c: &mut Criterion) { .collect(); let mut file = tempfile::tempfile().unwrap(); us915_set - .to_disktree(&mut file, |_, _| Ok::<(), std::io::Error>(())) + .to_hexdb(&mut file, |_, _| Ok::<(), std::io::Error>(())) .unwrap(); - DiskTreeMap::memmap(&file).unwrap() + HexDb::memmap(&file).unwrap() }; let tarpon_springs = coord! {x: -82.753822, y: 28.15215}; diff --git a/src/disktree/dtseek.rs b/src/disktree/dtseek.rs deleted file mode 100644 index 3cc2689..0000000 --- a/src/disktree/dtseek.rs +++ /dev/null @@ -1,26 +0,0 @@ -use crate::disktree::dptr::Dp; - -pub(crate) trait DtSeek { - fn pos(&mut self) -> std::io::Result; - - fn seek(&mut self, dp: Dp) -> std::io::Result; - - fn fast_forward(&mut self) -> std::io::Result; -} - -impl DtSeek for S -where - S: std::io::Seek, -{ - fn pos(&mut self) -> std::io::Result { - self.stream_position().map(Dp::from) - } - - fn seek(&mut self, dp: Dp) -> std::io::Result { - self.seek(std::io::SeekFrom::Start(dp.into())).map(Dp::from) - } - - fn fast_forward(&mut self) -> std::io::Result { - self.seek(std::io::SeekFrom::End(0)).map(Dp::from) - } -} diff --git a/src/error.rs b/src/error.rs index ba8110a..9b807b3 100644 --- a/src/error.rs +++ b/src/error.rs @@ -9,31 +9,31 @@ pub enum Error { Index(u64), /// An io error. - #[cfg(feature = "disktree")] + #[cfg(feature = "hexdb")] Io(std::io::Error), - /// Not a disktree. - #[cfg(feature = "disktree")] - NotDisktree, + /// Not a hexdb. + #[cfg(feature = "hexdb")] + NotHexDb, /// Unsupported version. - #[cfg(feature = "disktree")] + #[cfg(feature = "hexdb")] Version(u8), - /// Invalid value tag found in disktree. - #[cfg(feature = "disktree")] + /// Invalid value tag found in hexdb. + #[cfg(feature = "hexdb")] InvalidTag(u8, u64), - /// Invalid value size bytes found in disktree header. - #[cfg(feature = "disktree")] + /// Invalid value size bytes found in hexdb header. + #[cfg(feature = "hexdb")] Varint(u32), /// User-provided serializer failed. - #[cfg(feature = "disktree")] + #[cfg(feature = "hexdb")] Writer(Box), } -#[cfg(feature = "disktree")] +#[cfg(feature = "hexdb")] impl std::convert::From for Error { fn from(other: std::io::Error) -> Self { Error::Io(other) @@ -45,22 +45,22 @@ impl std::error::Error for Error { match self { Error::Index(_) => None, - #[cfg(feature = "disktree")] + #[cfg(feature = "hexdb")] Error::Io(inner) => inner.source(), - #[cfg(feature = "disktree")] - Error::NotDisktree => None, + #[cfg(feature = "hexdb")] + Error::NotHexDb => None, - #[cfg(feature = "disktree")] + #[cfg(feature = "hexdb")] Error::Version(_) => None, - #[cfg(feature = "disktree")] + #[cfg(feature = "hexdb")] Error::InvalidTag(_, _) => None, - #[cfg(feature = "disktree")] + #[cfg(feature = "hexdb")] Error::Varint(_) => None, - #[cfg(feature = "disktree")] + #[cfg(feature = "hexdb")] Error::Writer(inner) => inner.source(), } } @@ -71,30 +71,30 @@ impl std::fmt::Display for Error { match self { Error::Index(bits) => write!(f, "raw u64 is not a valid H3 index: {bits}"), - #[cfg(feature = "disktree")] + #[cfg(feature = "hexdb")] Error::Io(io_error) => io_error.fmt(f), - #[cfg(feature = "disktree")] - Error::NotDisktree => { + #[cfg(feature = "hexdb")] + Error::NotHexDb => { write!(f, "file missing magic header") } - #[cfg(feature = "disktree")] + #[cfg(feature = "hexdb")] Error::Version(version) => { write!(f, "unsupported version, got {version}") } - #[cfg(feature = "disktree")] + #[cfg(feature = "hexdb")] Error::InvalidTag(tag, pos) => { write!(f, "invalid tag, got {tag}, pos {pos}") } - #[cfg(feature = "disktree")] + #[cfg(feature = "hexdb")] Error::Varint(val) => { write!(f, "byte sequence is not a valid varint, got {val}") } - #[cfg(feature = "disktree")] + #[cfg(feature = "hexdb")] Error::Writer(writer_error) => { write!(f, "provided writer returned an error, got {writer_error}") } diff --git a/src/hexdb/dbseek.rs b/src/hexdb/dbseek.rs new file mode 100644 index 0000000..c6a8627 --- /dev/null +++ b/src/hexdb/dbseek.rs @@ -0,0 +1,26 @@ +use crate::hexdb::dptr::P; + +pub(crate) trait DbSeek { + fn pos(&mut self) -> std::io::Result

; + + fn seek(&mut self, dp: P) -> std::io::Result

; + + fn fast_forward(&mut self) -> std::io::Result

; +} + +impl DbSeek for S +where + S: std::io::Seek, +{ + fn pos(&mut self) -> std::io::Result

{ + self.stream_position().map(P::from) + } + + fn seek(&mut self, dp: P) -> std::io::Result

{ + self.seek(std::io::SeekFrom::Start(dp.into())).map(P::from) + } + + fn fast_forward(&mut self) -> std::io::Result

{ + self.seek(std::io::SeekFrom::End(0)).map(P::from) + } +} diff --git a/src/disktree/dptr.rs b/src/hexdb/dptr.rs similarity index 69% rename from src/disktree/dptr.rs rename to src/hexdb/dptr.rs index 35731d4..dbaa72d 100644 --- a/src/disktree/dptr.rs +++ b/src/hexdb/dptr.rs @@ -9,9 +9,9 @@ use std::{ /// A 'disk' pointer. #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] #[repr(transparent)] -pub(crate) struct Dp(u64); +pub(crate) struct P(u64); -impl Dp { +impl P { #[allow(clippy::cast_possible_truncation)] const MAX: u64 = 2_u64.pow(Self::DISK_REPR_SZ as u32 * 8) - 1; const DISK_REPR_SZ: usize = 5; @@ -21,15 +21,16 @@ impl Dp { self.0 == Self::NULL } - pub(crate) const fn null() -> Dp { - Dp(Self::NULL) + pub(crate) const fn null() -> P { + P(Self::NULL) } pub(crate) const fn size() -> usize { Self::DISK_REPR_SZ } - /// Read 5 bytes from disk and parses them as little-endian `u64`. + /// Read [`DISK_REPR_SZ`][Self::DISK_REPR_SZ] bytes from disk and + /// parses them as little-endian `u64`. pub(crate) fn read(src: &mut R) -> Result where R: Read, @@ -42,7 +43,7 @@ impl Dp { /// Read 5 * `n` bytes from disk, for up to n=7, and parses them as /// little-endian `u64`s. - pub(crate) fn read_n(src: &mut R, n: usize) -> Result> + pub(crate) fn read_n(src: &mut R, n: usize) -> Result> where R: Read, { @@ -56,7 +57,7 @@ impl Dp { buf[..Self::DISK_REPR_SZ].copy_from_slice(chunk); u64::from_le_bytes(buf) }) - .map(Dp::from) + .map(P::from) .collect()) } @@ -70,51 +71,51 @@ impl Dp { } } -impl Add for Dp { - type Output = Dp; +impl Add for P { + type Output = P; - fn add(self, rhs: usize) -> Dp { - Dp::from(self.0 + rhs as u64) + fn add(self, rhs: usize) -> P { + P::from(self.0 + rhs as u64) } } -impl Add for Dp { - type Output = Dp; +impl Add for P { + type Output = P; - fn add(self, rhs: u64) -> Dp { - Dp::from(self.0 + rhs) + fn add(self, rhs: u64) -> P { + P::from(self.0 + rhs) } } -impl Add for Dp { - type Output = Dp; +impl Add for P { + type Output = P; - fn add(self, rhs: u32) -> Dp { - Dp::from(self.0 + rhs as u64) + fn add(self, rhs: u32) -> P { + P::from(self.0 + rhs as u64) } } -impl From for u64 { - fn from(Dp(raw): Dp) -> u64 { +impl From

for u64 { + fn from(P(raw): P) -> u64 { raw } } -impl From for Dp { - fn from(raw: u64) -> Dp { +impl From for P { + fn from(raw: u64) -> P { assert!(raw <= Self::MAX); - Dp(raw) + P(raw) } } -impl From for Dp { - fn from(raw: usize) -> Dp { - Dp::from(raw as u64) +impl From for P { + fn from(raw: usize) -> P { + P::from(raw as u64) } } -impl From for usize { - fn from(Dp(raw): Dp) -> usize { +impl From

for usize { + fn from(P(raw): P) -> usize { usize::try_from(raw).unwrap() } } diff --git a/src/disktree/iter.rs b/src/hexdb/iter.rs similarity index 76% rename from src/disktree/iter.rs rename to src/hexdb/iter.rs index 91966e3..fd4b769 100644 --- a/src/disktree/iter.rs +++ b/src/hexdb/iter.rs @@ -1,7 +1,7 @@ use crate::{ cell::CellStack, - disktree::{dptr::Dp, dtseek::DtSeek, tree::HDR_SZ, varint}, error::{Error, Result}, + hexdb::{dbseek::DbSeek, dptr::P, tree::HDR_SZ, varint}, Cell, }; use byteorder::ReadBytesExt; @@ -9,26 +9,26 @@ use std::io::Cursor; pub(crate) struct Iter<'a> { cell_stack: CellStack, - curr_node: Option<(u8, Dp)>, - disktree_buf: &'a [u8], - disktree_csr: Cursor<&'a [u8]>, - node_stack: Vec>, - recycle_bin: Vec>, + curr_node: Option<(u8, P)>, + hexdb_buf: &'a [u8], + hexdb_csr: Cursor<&'a [u8]>, + node_stack: Vec>, + recycle_bin: Vec>, } enum Node { // File position for the fist byte of value data. - Leaf(Dp), + Leaf(P), // (H3 Cell digit, file position of child's node tag) - Parent(Vec<(u8, Dp)>), + Parent(Vec<(u8, P)>), } impl<'a> Iter<'a> { - pub(crate) fn read_base_nodes(rdr: &mut Cursor<&[u8]>) -> Result> { + pub(crate) fn read_base_nodes(rdr: &mut Cursor<&[u8]>) -> Result> { let mut buf = Vec::with_capacity(122); rdr.seek(HDR_SZ.into())?; for digit in 0..122 { - let dptr = Dp::read(rdr)?; + let dptr = P::read(rdr)?; if !dptr.is_null() { buf.push((digit, dptr)); } @@ -38,15 +38,15 @@ impl<'a> Iter<'a> { } // `pos` is a position in the file of this node's tag. - fn read_node(&mut self, dptr: Dp) -> Result { + fn read_node(&mut self, dptr: P) -> Result { let dptr = self.seek(dptr)?; - let node_tag = self.disktree_csr.read_u8()?; + let node_tag = self.hexdb_csr.read_u8()?; if 0 == node_tag & 0b1000_0000 { Ok(Node::Leaf(dptr)) } else { let mut children = self.node_buf(); let n_children = (node_tag & 0b0111_1111).count_ones() as usize; - let child_dptrs = Dp::read_n(&mut self.disktree_csr, n_children)?; + let child_dptrs = P::read_n(&mut self.hexdb_csr, n_children)?; children.extend( (0..7) .rev() @@ -61,7 +61,7 @@ impl<'a> Iter<'a> { /// allocates a new one. /// /// See [`Iter::recycle_node_buf`]. - fn node_buf(&mut self) -> Vec<(u8, Dp)> { + fn node_buf(&mut self) -> Vec<(u8, P)> { let buf = self .recycle_bin .pop() @@ -73,7 +73,7 @@ impl<'a> Iter<'a> { /// Accepts a used, empty, node buffer for later reuse. /// /// See [`Iter::node_buf`]. - fn recycle_node_buf(&mut self, buf: Vec<(u8, Dp)>) { + fn recycle_node_buf(&mut self, buf: Vec<(u8, P)>) { debug_assert!(buf.is_empty()); self.recycle_bin.push(buf); } @@ -86,12 +86,12 @@ impl<'a> Iter<'a> { self.curr_node = None; } - pub(crate) fn new(disktree_buf: &'a [u8]) -> Result> { - let mut disktree_csr = Cursor::new(disktree_buf); + pub(crate) fn new(hexdb_buf: &'a [u8]) -> Result> { + let mut hexdb_csr = Cursor::new(hexdb_buf); let mut cell_stack = CellStack::new(); let mut node_stack = Vec::new(); let recycle_bin = Vec::new(); - let mut base_nodes = Self::read_base_nodes(&mut disktree_csr)?; + let mut base_nodes = Self::read_base_nodes(&mut hexdb_csr)?; let curr_node = base_nodes.pop(); node_stack.push(base_nodes); if let Some((digit, _)) = curr_node { @@ -100,8 +100,8 @@ impl<'a> Iter<'a> { Ok(Self { cell_stack, curr_node, - disktree_buf, - disktree_csr, + hexdb_buf, + hexdb_csr, recycle_bin, node_stack, }) @@ -148,14 +148,14 @@ impl<'a> Iterator for Iter<'a> { self.stop_yielding(); return Some(Err(Error::from(e))); } - match varint::read(&mut self.disktree_csr) { + match varint::read(&mut self.hexdb_csr) { Err(e) => { self.stop_yielding(); return Some(Err(e)); } Ok((val_len, _n_read)) => { - let pos = self.disktree_csr.position() as usize; - let val_buf = &self.disktree_buf[pos..][..val_len as usize]; + let pos = self.hexdb_csr.position() as usize; + let val_buf = &self.hexdb_buf[pos..][..val_len as usize]; return Some(Ok(( *self.cell_stack.cell().expect("corrupted cell-stack"), val_buf, @@ -169,16 +169,16 @@ impl<'a> Iterator for Iter<'a> { } } -impl DtSeek for Iter<'_> { - fn pos(&mut self) -> std::io::Result { - self.disktree_csr.pos() +impl DbSeek for Iter<'_> { + fn pos(&mut self) -> std::io::Result

{ + self.hexdb_csr.pos() } - fn seek(&mut self, dp: Dp) -> std::io::Result { - self.disktree_csr.seek(dp) + fn seek(&mut self, dp: P) -> std::io::Result

{ + self.hexdb_csr.seek(dp) } - fn fast_forward(&mut self) -> std::io::Result { - self.disktree_csr.fast_forward() + fn fast_forward(&mut self) -> std::io::Result

{ + self.hexdb_csr.fast_forward() } } diff --git a/src/disktree/mod.rs b/src/hexdb/mod.rs similarity index 77% rename from src/disktree/mod.rs rename to src/hexdb/mod.rs index dfbc683..cc01579 100644 --- a/src/disktree/mod.rs +++ b/src/hexdb/mod.rs @@ -1,12 +1,12 @@ //! An on-disk hextree. #[cfg(not(target_pointer_width = "64"))] -compile_warning!("disktree may silently fail on non-64bit systems"); +compile_warning!("hexdb may silently fail on non-64bit systems"); -pub use tree::DiskTreeMap; +pub use tree::HexDb; +mod dbseek; mod dptr; -mod dtseek; mod iter; mod node; mod tree; @@ -51,11 +51,11 @@ mod tests { let file = tempfile::NamedTempFile::new().unwrap(); let (mut file, path) = file.keep().unwrap(); - println!("disktree path: {path:?}"); + println!("hexdb path: {path:?}"); monaco - .to_disktree(&mut file, |wtr, val| bincode::serialize_into(wtr, val)) + .to_hexdb(&mut file, |wtr, val| bincode::serialize_into(wtr, val)) .unwrap(); - let monaco_disktree = DiskTreeMap::open(path).unwrap(); + let monaco_hexdb = HexDb::open(path).unwrap(); assert_eq!(monaco.get(point_2), None); assert_eq!( @@ -70,13 +70,13 @@ mod tests { )); assert!(matches!( - monaco_disktree.get_raw(point_1_res8).unwrap(), - Some((cell, crate::disktree::node::Node::Parent(_))) if cell == point_1_res8 + monaco_hexdb.get_raw(point_1_res8).unwrap(), + Some((cell, crate::hexdb::node::Node::Parent(_))) if cell == point_1_res8 )); for (ht_cell, &ht_val) in monaco.iter() { let now = std::time::Instant::now(); - let (dt_cell, val_buf) = monaco_disktree.get(ht_cell).unwrap().unwrap(); + let (dt_cell, val_buf) = monaco_hexdb.get(ht_cell).unwrap().unwrap(); let dt_val = bincode::deserialize_from(val_buf).unwrap(); let lookup_duration = now.elapsed(); println!("loookup of {dt_cell} took {lookup_duration:?}"); @@ -141,34 +141,34 @@ mod tests { map }; - let monaco_disktree: DiskTreeMap = { + let monaco_hexdb: HexDb = { let file = tempfile::NamedTempFile::new().unwrap(); let (mut file, path) = file.keep().unwrap(); monaco_hextree - .to_disktree(&mut file, |wtr, val| wtr.write_all(val)) + .to_hexdb(&mut file, |wtr, val| wtr.write_all(val)) .unwrap(); let _ = file; - DiskTreeMap::open(path).unwrap() + HexDb::open(path).unwrap() }; - // Assert neither hashmap nor disktree contain reserved cells. + // Assert neither hashmap nor hexdb contain reserved cells. for cell in test_cells { assert!(!monaco_hashmap.contains_key(&cell)); - assert!(!monaco_disktree.contains(cell).unwrap()); + assert!(!monaco_hexdb.contains(cell).unwrap()); } - // Assert disktree contains all the same values as the + // Assert hexdb contains all the same values as the // hashmap. for (cell, val) in monaco_hashmap .iter() .map(|(cell, vec)| (**cell, vec.as_slice())) { - assert_eq!((cell, val), monaco_disktree.get(cell).unwrap().unwrap()) + assert_eq!((cell, val), monaco_hexdb.get(cell).unwrap().unwrap()) } // Assert hashmap contains all the same values as the - // disktree. - for (cell, val) in monaco_disktree.iter().unwrap().map(|entry| entry.unwrap()) { + // hexdb. + for (cell, val) in monaco_hexdb.iter().unwrap().map(|entry| entry.unwrap()) { assert_eq!( (cell, val), ( @@ -198,19 +198,19 @@ mod tests { let file = tempfile::NamedTempFile::new().unwrap(); let (mut file, path) = file.keep().unwrap(); - println!("disktree path: {path:?}"); + println!("hexdb path: {path:?}"); monaco - .to_disktree(&mut file, |wtr, val| bincode::serialize_into(wtr, val)) + .to_hexdb(&mut file, |wtr, val| bincode::serialize_into(wtr, val)) .unwrap(); - let monaco_disktree = DiskTreeMap::open(path).unwrap(); + let monaco_hexdb = HexDb::open(path).unwrap(); // Create the iterator with the user-defined deserialzer. - let disktree_iter = monaco_disktree.iter().unwrap(); + let hexdb_iter = monaco_hexdb.iter().unwrap(); let start = std::time::Instant::now(); - let mut disktree_collection = Vec::new(); - for res in disktree_iter { + let mut hexdb_collection = Vec::new(); + for res in hexdb_iter { let (cell, val_buf) = res.unwrap(); - disktree_collection.push((cell, bincode::deserialize_from(val_buf).unwrap())); + hexdb_collection.push((cell, bincode::deserialize_from(val_buf).unwrap())); } let elapsed = start.elapsed(); println!("{elapsed:?}"); @@ -221,20 +221,20 @@ mod tests { assert_eq!( hextree_collection, - disktree_collection, - "iterating a disktree should yield identically ordered elements as the hextree tree it was derived from" + hexdb_collection, + "iterating a hexdb should yield identically ordered elements as the hextree tree it was derived from" ); } #[test] - fn test_empty_disktree() { + fn test_empty_hexdb() { use crate::HexTreeMap; use std::io::Cursor; let mut wtr = vec![]; HexTreeMap::<&[u8]>::new() - .to_disktree(Cursor::new(&mut wtr), |wtr, val| wtr.write_all(val)) + .to_hexdb(Cursor::new(&mut wtr), |wtr, val| wtr.write_all(val)) .unwrap(); - let disktree = DiskTreeMap::with_buf(wtr).unwrap(); - assert_eq!(0, disktree.iter().unwrap().count()); + let hexdb = HexDb::with_buf(wtr).unwrap(); + assert_eq!(0, hexdb.iter().unwrap().count()); } } diff --git a/src/disktree/node.rs b/src/hexdb/node.rs similarity index 78% rename from src/disktree/node.rs rename to src/hexdb/node.rs index 6981083..082c2d0 100644 --- a/src/disktree/node.rs +++ b/src/hexdb/node.rs @@ -1,25 +1,25 @@ use crate::{ - disktree::{dptr::Dp, dtseek::DtSeek, varint}, error::Result, + hexdb::{dbseek::DbSeek, dptr::P, varint}, }; use byteorder::ReadBytesExt; use std::{io::Read, mem::size_of, ops::Range}; // Enough bytes to read node tag and 7 child dptrs. -const NODE_BUF_SZ: usize = size_of::() + 7 * Dp::size(); +const NODE_BUF_SZ: usize = size_of::() + 7 * P::size(); #[derive(Debug)] pub(crate) enum Node { // value_begin..value_end Leaf(Range), // (H3 Cell digit, file position of child's node tag) - Parent([Option; 7]), + Parent([Option

; 7]), } impl Node { pub(crate) fn read(rdr: &mut R) -> Result where - R: Read + DtSeek, + R: Read + DbSeek, { let start_pos = rdr.pos()?; let mut buf = [0u8; NODE_BUF_SZ]; @@ -32,12 +32,12 @@ impl Node { let end = begin + val_len; Ok(Node::Leaf(usize::from(begin)..usize::from(end))) } else { - let mut children: [Option; 7] = [None, None, None, None, None, None, None]; + let mut children: [Option

; 7] = [None, None, None, None, None, None, None]; for (_digit, child) in (0..7) .zip(children.iter_mut()) .filter(|(digit, _)| node_tag & (1 << digit) != 0) { - *child = Some(Dp::read(buf_rdr)?); + *child = Some(P::read(buf_rdr)?); } Ok(Node::Parent(children)) } diff --git a/src/disktree/tree.rs b/src/hexdb/tree.rs similarity index 85% rename from src/disktree/tree.rs rename to src/hexdb/tree.rs index ac7897e..a2e1549 100755 --- a/src/disktree/tree.rs +++ b/src/hexdb/tree.rs @@ -1,7 +1,7 @@ use crate::{ digits::Digits, - disktree::{dptr::Dp, iter::Iter, node::Node}, error::Result, + hexdb::{dptr::P, iter::Iter, node::Node}, Cell, Error, }; use byteorder::ReadBytesExt; @@ -16,24 +16,24 @@ use std::{ pub(crate) const HDR_MAGIC: &[u8] = b"hextree\0"; pub(crate) const HDR_SZ: usize = HDR_MAGIC.len() + 1; -/// An on-disk hextree map. -pub struct DiskTreeMap(pub(crate) Box + Send + Sync + 'static>); +/// An on-disk, read-only, hextree mapping [Cell]s to bytes. +pub struct HexDb(pub(crate) Box + Send + Sync + 'static>); -impl DiskTreeMap { - /// Opens a `DiskTree` at the specified path. +impl HexDb { + /// Opens a `HexDb` at the specified path. pub fn open>(path: P) -> Result { let file = File::open(path)?; Self::memmap(&file) } - /// Memory maps the provided disktree-containing file. + /// Memory maps the provided hexdb-containing file. pub fn memmap(file: &File) -> Result { #[allow(unsafe_code)] let mm = unsafe { MmapOptions::new().map(file)? }; Self::with_buf(mm) } - /// Opens a `DiskTree` with a provided buffer. + /// Opens a `HexDb` with a provided buffer. pub fn with_buf(buf: B) -> Result where B: AsRef<[u8]> + Send + Sync + 'static, @@ -45,7 +45,7 @@ impl DiskTreeMap { buf }; if magic != HDR_MAGIC { - return Err(Error::NotDisktree); + return Err(Error::NotHexDb); } let version = { @@ -74,7 +74,7 @@ impl DiskTreeMap { let base_cell_pos = Self::base_cell_dptr(cell); let mut csr = Cursor::new((*self.0).as_ref()); csr.seek(SeekFrom::Start(base_cell_pos.into()))?; - let node_dptr = Dp::read(&mut csr)?; + let node_dptr = P::read(&mut csr)?; if node_dptr.is_null() { return Ok(None); } @@ -85,7 +85,7 @@ impl DiskTreeMap { fn _get_raw( csr: &mut Cursor<&[u8]>, res: u8, - node_dptr: Dp, + node_dptr: P, cell: Cell, mut digits: Digits, ) -> Result> { @@ -116,7 +116,7 @@ impl DiskTreeMap { } /// Returns the DPtr to a base (res0) cell dptr. - fn base_cell_dptr(cell: Cell) -> Dp { - Dp::from(HDR_SZ + Dp::size() * cell.base() as usize) + fn base_cell_dptr(cell: Cell) -> P { + P::from(HDR_SZ + P::size() * cell.base() as usize) } } diff --git a/src/disktree/varint.rs b/src/hexdb/varint.rs similarity index 100% rename from src/disktree/varint.rs rename to src/hexdb/varint.rs diff --git a/src/disktree/writer.rs b/src/hexdb/writer.rs similarity index 80% rename from src/disktree/writer.rs rename to src/hexdb/writer.rs index 11cfd9e..596e215 100644 --- a/src/disktree/writer.rs +++ b/src/hexdb/writer.rs @@ -1,7 +1,7 @@ use crate::{ compaction::Compactor, - disktree::{dptr::Dp, dtseek::DtSeek, tree::HDR_MAGIC, varint}, error::{Error, Result}, + hexdb::{dbseek::DbSeek, dptr::P, tree::HDR_MAGIC, varint}, node::Node, HexTreeMap, }; @@ -12,30 +12,30 @@ impl HexTreeMap where C: Compactor, { - /// Write self to disk. - pub fn to_disktree(&self, wtr: W, f: F) -> Result + /// Encode self as a [HexDb](crate::hexdb::HexDb) to the provided writer. + pub fn to_hexdb(&self, wtr: W, f: F) -> Result where W: Write + std::io::Seek, F: Fn(&mut dyn Write, &V) -> std::result::Result<(), E>, E: std::error::Error + Sync + Send + 'static, { - DiskTreeWriter::new(wtr).write(self, f) + HexDbWriter::new(wtr).write(self, f) } } -pub(crate) struct DiskTreeWriter { +pub(crate) struct HexDbWriter { scratch_pad: Vec, wtr: W, } -impl DiskTreeWriter { +impl HexDbWriter { pub fn new(wtr: W) -> Self { let scratch_pad = Vec::new(); Self { wtr, scratch_pad } } } -impl DiskTreeWriter +impl HexDbWriter where W: Write + std::io::Seek, { @@ -50,15 +50,15 @@ where const VERSION: u8 = 0; self.wtr.write_u8(0xFE - VERSION)?; - let mut fixups: Vec<(Dp, &Node)> = Vec::new(); + let mut fixups: Vec<(P, &Node)> = Vec::new(); // Write base cells placeholder offsets. for base in hextree.nodes.iter() { match base.as_deref() { - None => Dp::null().write(&mut self.wtr)?, + None => P::null().write(&mut self.wtr)?, Some(node) => { fixups.push((self.pos()?, node)); - Dp::null().write(&mut self.wtr)? + P::null().write(&mut self.wtr)? } } } @@ -72,13 +72,13 @@ where Ok(()) } - fn write_node(&mut self, node: &Node, f: &mut F) -> Result + fn write_node(&mut self, node: &Node, f: &mut F) -> Result

where F: FnMut(&mut dyn Write, &V) -> std::result::Result<(), E>, E: std::error::Error + Sync + Send + 'static, { let node_pos = self.fast_forward()?; - let mut node_fixups: Vec<(Dp, &Node)> = Vec::new(); + let mut node_fixups: Vec<(P, &Node)> = Vec::new(); match node { Node::Leaf(val) => { self.scratch_pad.clear(); @@ -105,7 +105,7 @@ where // this node is empty. tag = (tag >> 1) | 0b1000_0000; node_fixups.push((self.pos()?, node)); - Dp::null().write(&mut self.wtr)?; + P::null().write(&mut self.wtr)?; } }; } @@ -126,19 +126,19 @@ where } } -impl DtSeek for DiskTreeWriter +impl DbSeek for HexDbWriter where W: std::io::Seek, { - fn pos(&mut self) -> std::io::Result { + fn pos(&mut self) -> std::io::Result

{ self.wtr.pos() } - fn seek(&mut self, dp: Dp) -> std::io::Result { - DtSeek::seek(&mut self.wtr, dp) + fn seek(&mut self, dp: P) -> std::io::Result

{ + DbSeek::seek(&mut self.wtr, dp) } - fn fast_forward(&mut self) -> std::io::Result { + fn fast_forward(&mut self) -> std::io::Result

{ self.wtr.fast_forward() } } diff --git a/src/lib.rs b/src/lib.rs index 34c0314..f7f32c6 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,12 +4,12 @@ mod cell; pub mod compaction; mod digits; -#[cfg(feature = "disktree")] -pub mod disktree; mod entry; mod error; pub mod hex_tree_map; mod hex_tree_set; +#[cfg(feature = "hexdb")] +pub mod hexdb; mod iteration; mod node; @@ -17,5 +17,5 @@ pub use crate::cell::Cell; pub use crate::hex_tree_map::HexTreeMap; pub use crate::hex_tree_set::HexTreeSet; pub use error::{Error, Result}; -#[cfg(feature = "disktree")] +#[cfg(feature = "hexdb")] pub use memmap;