Skip to content

Commit

Permalink
[disktree] remove serde dep entirely
Browse files Browse the repository at this point in the history
  • Loading branch information
JayKickliter committed Jul 28, 2023
1 parent 438d40c commit 3033d7f
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 44 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ all-features = true

[features]
default = ["disktree"]
disktree = ["serde", "bincode", "byteorder"]
disktree = ["serde", "byteorder"]
serde = ["dep:serde"]

[dependencies]
bincode = { version = "1.3.3", optional = true }
byteorder = { version = "1", optional = true }
serde = { version = "1", optional = true, features = ["derive"] }

[dev-dependencies]
bincode = { version = "1.3.3" }
byteorder = "1"
criterion = { version = "0.3", features = ["html_reports"] }
geo-types = "0.7"
Expand Down
7 changes: 5 additions & 2 deletions src/disktree/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,18 @@ mod tests {
let file = tempfile::NamedTempFile::new().unwrap();
let (mut file, path) = file.keep().unwrap();
println!("disktree path: {path:?}");
monaco.to_disktree(&mut file).unwrap();
monaco
.to_disktree(&mut file, |wtr, val| bincode::serialize_into(wtr, val))
.unwrap();
let mut monaco_disktree = DiskTree::from_reader(file).unwrap();

assert_eq!(monaco.get(point_2).unzip().1, None);
assert_eq!(monaco.get(point_1).unzip().1, Some(&Region::Monaco));

for (ht_cell, &ht_val) in monaco.iter() {
let now = std::time::Instant::now();
let (dt_cell, dt_val) = monaco_disktree.get(ht_cell).unwrap().unwrap();
let (dt_cell, dt_val_rdr) = monaco_disktree.seek_to_cell(ht_cell).unwrap().unwrap();
let dt_val = bincode::deserialize_from(dt_val_rdr).unwrap();
let lookup_duration = now.elapsed();
println!("loookup of {dt_cell} took {lookup_duration:?}");
assert_eq!(ht_val, dt_val);
Expand Down
25 changes: 8 additions & 17 deletions src/disktree/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use crate::{
Cell,
};
use byteorder::ReadBytesExt;
use serde::de::DeserializeOwned;
use std::{
fs::File,
io::{Read, Seek, SeekFrom},
Expand Down Expand Up @@ -48,25 +47,17 @@ impl<R: Read + Seek> DiskTree<R> {
}
}

/// Returns a the value corresponding to the given target cell or
/// one of its parents.
///
/// Note that this method also returns a Cell, which may be a
/// parent of the target cell provided.
pub fn get<V>(&mut self, cell: Cell) -> Result<Option<(Cell, V)>>
where
V: DeserializeOwned,
{
/// Returns a reader pre-seeked to the value for cell, if present.
pub fn seek_to_cell(&mut self, cell: Cell) -> Result<Option<(Cell, &mut R)>> {
let base_cell_pos = Self::base_cell_offset(cell);
self.seek_to(base_cell_pos)?;
self.seek_to_pos(base_cell_pos)?;
let node_dptr = dptr::read(&mut self.0)?;
if node_dptr == DPTR_NULL {
return Ok(None);
}
let digits = Digits::new(cell);
if let Some((cell, pos)) = self._get(0, node_dptr, cell, digits)? {
debug_assert_eq!(pos, self.0.stream_position()?);
Ok(Some((cell, bincode::deserialize_from(&mut self.0)?)))
if let Some((cell, _)) = self._get(0, node_dptr, cell, digits)? {
Ok(Some((cell, &mut self.0)))
} else {
Ok(None)
}
Expand All @@ -75,7 +66,7 @@ impl<R: Read + Seek> DiskTree<R> {
/// Returns `true` if the tree fully contains `cell`.
pub fn contains(&mut self, cell: Cell) -> Result<bool> {
let base_cell_pos = Self::base_cell_offset(cell);
self.seek_to(base_cell_pos)?;
self.seek_to_pos(base_cell_pos)?;
let node_dptr = dptr::read(&mut self.0)?;
if node_dptr == DPTR_NULL {
return Ok(false);
Expand All @@ -94,7 +85,7 @@ impl<R: Read + Seek> DiskTree<R> {
cell: Cell,
mut digits: Digits,
) -> Result<Option<(Cell, u64)>> {
self.seek_to(node_dptr)?;
self.seek_to_pos(node_dptr)?;
let node_tag = self.0.read_u8()?;
assert!(node_tag == 0 || node_tag > 0b1000_0000);
match (digits.next(), node_tag) {
Expand All @@ -119,7 +110,7 @@ impl<R: Read + Seek> DiskTree<R> {
}
}

fn seek_to(&mut self, pos: u64) -> Result {
fn seek_to_pos(&mut self, pos: u64) -> Result {
self.0.seek(SeekFrom::Start(pos))?;
Ok(())
}
Expand Down
30 changes: 19 additions & 11 deletions src/disktree/writer.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,34 @@
use crate::{
compaction::Compactor,
disktree::dptr::{self, DPTR_NULL},
error::Result,
error::{Error, Result},
node::Node,
HexTreeMap,
};
use byteorder::WriteBytesExt;
use serde::Serialize;
use std::io::{Seek, SeekFrom, Write};

impl<V: Serialize, C: Compactor<V>> HexTreeMap<V, C> {
impl<V, C: Compactor<V>> HexTreeMap<V, C> {
/// Write self to disk.
pub fn to_disktree<W>(&self, wtr: W) -> Result
pub fn to_disktree<W, F, E>(&self, wtr: W, f: F) -> Result
where
W: Write + Seek,
F: Fn(&mut W, &V) -> std::result::Result<(), E>,
E: std::error::Error + Sync + Send + 'static,
{
DiskTreeWriter(wtr).write(self)
DiskTreeWriter(wtr).write(self, f)
}
}

pub(crate) struct DiskTreeWriter<W>(W);

impl<W: Write + Seek> DiskTreeWriter<W> {
pub fn write<V, C>(&mut self, hextree: &HexTreeMap<V, C>) -> Result
pub fn write<V, C, F, E>(&mut self, hextree: &HexTreeMap<V, C>, f: F) -> Result
where
V: Serialize,
F: Fn(&mut W, &V) -> std::result::Result<(), E>,
E: std::error::Error + Sync + Send + 'static,
{
let mut f = f;
// Write version field
const VERSION: u8 = 0;
self.0.write_u8(0xFE - VERSION)?;
Expand All @@ -45,7 +48,7 @@ impl<W: Write + Seek> DiskTreeWriter<W> {
}

for (fixee_dptr, node) in fixups {
let node_dptr = self.write_node(node)?;
let node_dptr = self.write_node(node, &mut f)?;
self.0.seek(SeekFrom::Start(fixee_dptr))?;
dptr::write(&mut self.0, node_dptr)?;
}
Expand All @@ -55,13 +58,18 @@ impl<W: Write + Seek> DiskTreeWriter<W> {

/// Leaf: | 0_u8 | bincode bytes |
/// Parent: | 1_u8 | Dptr | Dptr | Dptr | Dptr | Dptr | Dptr | Dptr |
fn write_node<V: Serialize>(&mut self, node: &Node<V>) -> Result<u64> {
fn write_node<V, F, E>(&mut self, node: &Node<V>, f: &mut F) -> Result<u64>
where
F: Fn(&mut W, &V) -> std::result::Result<(), E>,
E: std::error::Error + Sync + Send + 'static,
{
let node_pos = self.0.seek(SeekFrom::End(0))?;
let mut node_fixups: Vec<(u64, &Node<V>)> = Vec::new();
match node {
Node::Leaf(val) => {
self.0.write_u8(0)?;
bincode::serialize_into(&mut self.0, val)?;
// bincode::serialize_into(&mut self.0, val)?;
f(&mut self.0, val).map_err(|e| Error::Writer(Box::new(e)))?
}
Node::Parent(children) => {
let tag_pos = self.0.stream_position()?;
Expand Down Expand Up @@ -92,7 +100,7 @@ impl<W: Write + Seek> DiskTreeWriter<W> {
};

for (fixee_dptr, node) in node_fixups {
let node_dptr = self.write_node(node)?;
let node_dptr = self.write_node(node, f)?;
self.0.seek(SeekFrom::Start(fixee_dptr))?;
dptr::write(&mut self.0, node_dptr)?;
}
Expand Down
17 changes: 5 additions & 12 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ pub enum Error {
#[cfg(feature = "disktree")]
Prefixed(u32),

/// Error \[de\]serializing value.
/// User-provided serializer failed.
#[cfg(feature = "disktree")]
Bincode(bincode::Error),
Writer(Box<dyn std::error::Error + Send + Sync>),
}

#[cfg(feature = "disktree")]
Expand All @@ -36,13 +36,6 @@ impl std::convert::From<std::io::Error> for Error {
}
}

#[cfg(feature = "disktree")]
impl std::convert::From<bincode::Error> for Error {
fn from(other: bincode::Error) -> Self {
Error::Bincode(other)
}
}

impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Expand All @@ -61,7 +54,7 @@ impl std::error::Error for Error {
Error::Prefixed(_) => None,

#[cfg(feature = "disktree")]
Error::Bincode(_) => None,
Error::Writer(inner) => inner.source(),
}
}
}
Expand Down Expand Up @@ -90,8 +83,8 @@ impl std::fmt::Display for Error {
}

#[cfg(feature = "disktree")]
Error::Bincode(err) => {
write!(f, "failure to [de]serialize value, got {err}")
Error::Writer(writer_error) => {
write!(f, "provided writer returned an error, got {writer_error}")
}
}
}
Expand Down

0 comments on commit 3033d7f

Please sign in to comment.