From a32a0487d5fe93bfb717578b52d901f8876d5113 Mon Sep 17 00:00:00 2001 From: Takeru Ohta Date: Sun, 28 May 2023 09:47:17 +0900 Subject: [PATCH] Remove "binary-format" feature in favor of "serde" feature --- Cargo.toml | 15 -- examples/decode.rs | 13 -- examples/encode.rs | 19 --- src/codec.rs | 370 --------------------------------------------- src/lib.rs | 8 - src/node.rs | 7 +- 6 files changed, 2 insertions(+), 430 deletions(-) delete mode 100644 examples/decode.rs delete mode 100644 examples/encode.rs delete mode 100644 src/codec.rs diff --git a/Cargo.toml b/Cargo.toml index 8d86b19..0afdd76 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,13 +14,8 @@ edition = "2021" [badges] coveralls = { repository = "sile/patricia_tree" } -[features] -binary-format = ["bytecodec", "trackable"] - [dependencies] bitflags = "1" -bytecodec = { version = "0.4", optional = true } -trackable = { version = "1", optional = true } serde = { version = "1", optional = true } [dev-dependencies] @@ -32,16 +27,6 @@ serde_json = { version = "1" } [package.metadata.docs.rs] all-features = true -[[example]] -name = "decode" -path = "examples/decode.rs" -required-features = ["binary-format"] - -[[example]] -name = "encode" -path = "examples/encode.rs" -required-features = ["binary-format"] - [[example]] name = "insert_lines" path = "examples/insert_lines.rs" diff --git a/examples/decode.rs b/examples/decode.rs deleted file mode 100644 index 917c9c0..0000000 --- a/examples/decode.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! `cargo run --example decode --features binary-format < INPUT_FILE > OUTPUT_FILE` -use bytecodec::io::IoDecodeExt; -use bytecodec::null::NullDecoder; -use patricia_tree::{node::NodeDecoder, PatriciaSet}; - -fn main() { - let mut decoder = NodeDecoder::new(NullDecoder); - let node = decoder.decode_exact(std::io::stdin()).unwrap(); - let set = PatriciaSet::from(node); - for s in set.iter() { - println!("{}", std::str::from_utf8(&s).unwrap()); - } -} diff --git a/examples/encode.rs b/examples/encode.rs deleted file mode 100644 index 4e70765..0000000 --- a/examples/encode.rs +++ /dev/null @@ -1,19 +0,0 @@ -//! `cargo run --example encode --features binary-format < INPUT_FILE > OUTPUT_FILE` -use bytecodec::io::IoEncodeExt; -use bytecodec::null::NullEncoder; -use bytecodec::Encode; -use patricia_tree::{node::NodeEncoder, PatriciaSet}; -use std::io::BufRead; - -fn main() { - let mut set = PatriciaSet::new(); - let stdin = std::io::stdin(); - for line in stdin.lock().lines() { - let line = line.unwrap(); - set.insert(line); - } - - let mut encoder = NodeEncoder::new(NullEncoder); - encoder.start_encoding(set.into()).unwrap(); - encoder.encode_all(std::io::stdout()).unwrap(); -} diff --git a/src/codec.rs b/src/codec.rs deleted file mode 100644 index 2d18f56..0000000 --- a/src/codec.rs +++ /dev/null @@ -1,370 +0,0 @@ -use crate::node::{Flags, Node}; -use bytecodec::combinator::Omittable; -use bytecodec::fixnum::{U16beDecoder, U16beEncoder, U8Decoder, U8Encoder}; -use bytecodec::tuple::{TupleDecoder, TupleEncoder}; -use bytecodec::{ByteCount, Decode, DecodeExt, Encode, Eos, ErrorKind, Result}; -use std::cmp; - -/// `[cfg(feature = "binary-format")]` Binary decoder for `Node`. -/// -/// # Binary format -/// -/// ```text -/// const FLAG_HAS_VALUE: u8 = 0b0000_0010; -/// const FLAG_HAS_CHILD: u8 = 0b0000_1000; -/// const FLAG_HAS_SIBLING: u8 = 0b0010_0000; -/// -/// struct BinNode { -/// flags: u8, -/// label_len: u8, -/// level: u16 // Big Endian -/// label: [u8; label_len], -/// value: Option, -/// child: Option, -/// sibling: Option -/// } -/// ``` -#[derive(Debug, Default)] -pub struct NodeDecoder { - stack: Vec<(u16, Node)>, - node: Option<(u16, Node)>, - label_offset: usize, - header_decoder: HeaderDecoder, - value_decoder: Omittable, - decoded: Option>, -} -impl NodeDecoder { - /// Makes a new `NodeDecoder` instance. - pub fn new(value_decoder: V) -> Self { - NodeDecoder { - stack: Vec::new(), - node: None, - label_offset: 0, - header_decoder: HeaderDecoder::default(), - value_decoder: value_decoder.omit(false), - decoded: None, - } - } -} -impl Decode for NodeDecoder { - type Item = Node; - - fn decode(&mut self, buf: &[u8], eos: Eos) -> Result { - if self.is_idle() { - return Ok(0); - } - - let mut offset = 0; - loop { - if self.node.is_none() { - bytecodec_try_decode!(self.header_decoder, offset, buf, eos); - let header = track!(self.header_decoder.finish_decoding())?; - let node = Node::new_for_decoding(header.flags, header.label_len); - self.value_decoder - .do_omit(!node.flags().contains(Flags::VALUE_ALLOCATED)); - self.node = Some((header.level, node)); - } - { - let node = &mut self.node.as_mut().expect("Never fails").1; - if self.label_offset < node.label().len() { - let size = cmp::min(buf.len() - offset, node.label().len() - self.label_offset); - node.label_mut()[self.label_offset..][..size] - .copy_from_slice(&buf[offset..][..size]); - offset += size; - self.label_offset += size; - if self.label_offset < node.label().len() { - break; - } - } - } - - bytecodec_try_decode!(self.value_decoder, offset, buf, eos); - let value = track!(self.value_decoder.finish_decoding())?; - let (level, mut node) = self.node.take().expect("Never fails"); - if let Some(value) = value { - node.set_value(value); - } - self.label_offset = 0; - - self.stack.push((level, node)); - while let Some(node) = self.stack.pop() { - let flags = node.1.flags(); - let has_next = (flags.contains(Flags::CHILD_ALLOCATED) - && !flags.contains(Flags::CHILD_INITIALIZED)) - || (flags.contains(Flags::SIBLING_ALLOCATED) - && !flags.contains(Flags::SIBLING_INITIALIZED)); - if has_next { - self.stack.push(node); - break; - } - if let Some(pred) = self.stack.last_mut() { - if node.0 == pred.0 { - pred.1.set_sibling(node.1); - } else { - track_assert_eq!(pred.0 + 1, node.0, ErrorKind::InvalidInput); - pred.1.set_child(node.1); - } - } else { - track_assert_eq!(node.0, 0, ErrorKind::InvalidInput); - self.decoded = Some(node.1); - return Ok(offset); - } - } - } - Ok(offset) - } - - fn finish_decoding(&mut self) -> Result { - let item = track_assert_some!(self.decoded.take(), ErrorKind::IncompleteDecoding); - Ok(item) - } - - fn requiring_bytes(&self) -> ByteCount { - if self.is_idle() { - ByteCount::Finite(0) - } else { - ByteCount::Unknown - } - } - - fn is_idle(&self) -> bool { - self.decoded.is_some() - } -} - -/// `[cfg(feature = "binary-format")]` Binary encoder for `Node`. -/// -/// # Binary format -/// -/// ```text -/// const FLAG_HAS_VALUE: u8 = 0b0000_0010; -/// const FLAG_HAS_CHILD: u8 = 0b0000_1000; -/// const FLAG_HAS_SIBLING: u8 = 0b0010_0000; -/// -/// struct BinNode { -/// flags: u8, -/// label_len: u8, -/// level: u16 // Big Endian -/// label: [u8; label_len], -/// value: Option, -/// child: Option, -/// sibling: Option -/// } -/// ``` -#[derive(Debug, Default)] -pub struct NodeEncoder { - stack: Vec<(u16, Node)>, - header_encoder: HeaderEncoder, - label_offset: usize, - value_encoder: V, - in_progress: bool, -} -impl NodeEncoder { - /// Makes a new `NodeEncoder` instance. - pub fn new(value_encoder: V) -> Self { - NodeEncoder { - stack: Vec::new(), - header_encoder: HeaderEncoder::default(), - label_offset: 0, - value_encoder, - in_progress: false, - } - } -} -impl Encode for NodeEncoder { - type Item = Node; - - fn encode(&mut self, buf: &mut [u8], eos: Eos) -> Result { - let mut offset = 0; - while !self.stack.is_empty() { - if !self.in_progress { - self.in_progress = true; - let &mut (level, ref mut node) = self.stack.last_mut().expect("Never fails"); - let header = Header::new(level, node); - track!(self.header_encoder.start_encoding(header))?; - self.label_offset = 0; - if let Some(v) = node.take_value() { - track!(self.value_encoder.start_encoding(v))?; - } - } - - if !self.header_encoder.is_idle() { - offset += track!(self.header_encoder.encode(&mut buf[offset..], eos))?; - if !self.header_encoder.is_idle() { - return Ok(offset); - }; - } - { - let node = &self.stack.last().expect("Never fails").1; - if self.label_offset < node.label().len() { - let size = cmp::min(buf.len() - offset, node.label().len() - self.label_offset); - buf[offset..][..size] - .copy_from_slice(&node.label()[self.label_offset..][..size]); - offset += size; - self.label_offset += size; - if self.label_offset < node.label().len() { - return Ok(offset); - } - } - } - if !self.value_encoder.is_idle() { - offset += track!(self.value_encoder.encode(&mut buf[offset..], eos))?; - if !self.value_encoder.is_idle() { - return Ok(offset); - } - } - - let (level, mut node) = self.stack.pop().expect("Never fails"); - if let Some(n) = node.take_sibling() { - self.stack.push((level, n)); - } - if let Some(n) = node.take_child() { - track_assert_ne!(level, 0xFFFF, ErrorKind::Other); - self.stack.push((level + 1, n)); - } - self.in_progress = false; - self.label_offset = 0; - } - Ok(offset) - } - - fn start_encoding(&mut self, item: Self::Item) -> Result<()> { - track_assert!(self.is_idle(), ErrorKind::EncoderFull); - self.stack.push((0, item)); - Ok(()) - } - - fn is_idle(&self) -> bool { - self.stack.is_empty() - } - - fn requiring_bytes(&self) -> ByteCount { - ByteCount::Unknown - } -} - -#[derive(Debug, Default)] -struct HeaderDecoder { - inner: TupleDecoder<(U8Decoder, U8Decoder, U16beDecoder)>, -} -impl Decode for HeaderDecoder { - type Item = Header; - - fn decode(&mut self, buf: &[u8], eos: Eos) -> Result { - track!(self.inner.decode(buf, eos)) - } - - fn finish_decoding(&mut self) -> Result { - let item = track!(self.inner.finish_decoding())?; - Ok(Header { - flags: Flags::from_bits_truncate(item.0), - label_len: item.1, - level: item.2, - }) - } - - fn requiring_bytes(&self) -> ByteCount { - self.inner.requiring_bytes() - } - - fn is_idle(&self) -> bool { - self.inner.is_idle() - } -} - -#[derive(Debug, Default)] -struct HeaderEncoder { - inner: TupleEncoder<(U8Encoder, U8Encoder, U16beEncoder)>, -} -impl Encode for HeaderEncoder { - type Item = Header; - - fn encode(&mut self, buf: &mut [u8], eos: Eos) -> Result { - track!(self.inner.encode(buf, eos)) - } - - fn start_encoding(&mut self, item: Self::Item) -> Result<()> { - let t = (item.flags.bits(), item.label_len, item.level); - track!(self.inner.start_encoding(t)) - } - - fn is_idle(&self) -> bool { - self.inner.is_idle() - } - - fn requiring_bytes(&self) -> ByteCount { - self.inner.requiring_bytes() - } -} - -#[derive(Debug)] -struct Header { - flags: Flags, - label_len: u8, - level: u16, -} -impl Header { - fn new(level: u16, node: &Node) -> Self { - Header { - flags: node.flags(), - label_len: node.label().len() as u8, - level, - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::node::Node; - use crate::PatriciaMap; - use bytecodec::fixnum::{U32beDecoder, U32beEncoder, U8Decoder, U8Encoder}; - use bytecodec::io::IoEncodeExt; - use bytecodec::{Decode, EncodeExt, Eos}; - - #[test] - fn encoder_and_decoder_works() { - let mut input = vec![(Vec::from("foo"), 1), ("bar".into(), 2), ("baz".into(), 3)]; - input.sort(); - - let map: PatriciaMap<_> = input.iter().cloned().collect(); - let root = Node::from(map); - - let mut buf = Vec::new(); - let mut encoder = track_try_unwrap!(NodeEncoder::::with_item(root)); - track_try_unwrap!(encoder.encode_all(&mut buf)); - - let mut decoder = NodeDecoder::new(U8Decoder::new()); - let size = track_try_unwrap!(decoder.decode(&buf, Eos::new(true))); - assert_eq!(size, buf.len()); - - let item = track_try_unwrap!(decoder.finish_decoding()); - let map = PatriciaMap::from(item); - assert_eq!(map.len(), 3); - assert_eq!(map.into_iter().collect::>(), input); - } - - #[test] - fn large_encoder_and_decoder_works() { - let mut input = (0..10000) - .map(|i| (i.to_string().into_bytes(), i)) - .collect::>(); - input.sort(); - - let map: PatriciaMap<_> = input.iter().cloned().collect(); - let root = Node::from(map); - - let mut buf = Vec::new(); - let mut encoder = track_try_unwrap!(NodeEncoder::::with_item(root)); - track_try_unwrap!(encoder.encode_all(&mut buf)); - - let mut decoder = NodeDecoder::new(U32beDecoder::new()); - let size = track_try_unwrap!(decoder.decode(&buf, Eos::new(true))); - assert_eq!(size, buf.len()); - - let item = track_try_unwrap!(decoder.finish_decoding()); - let map = PatriciaMap::from(item); - assert_eq!(map.len(), 10000); - assert_eq!(map.into_iter().collect::>(), input); - } -} diff --git a/src/lib.rs b/src/lib.rs index c09b66c..f813089 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,14 +27,8 @@ #[macro_use] extern crate bitflags; -#[cfg(feature = "binary-format")] -#[macro_use] -extern crate bytecodec; #[cfg(test)] extern crate rand; -#[cfg(feature = "binary-format")] -#[macro_use] -extern crate trackable; pub use map::PatriciaMap; pub use set::PatriciaSet; @@ -43,8 +37,6 @@ pub mod map; pub mod node; pub mod set; -#[cfg(feature = "binary-format")] -mod codec; #[cfg(feature = "serde")] mod serialization; mod tree; diff --git a/src/node.rs b/src/node.rs index 5b3ea6a..84bf683 100644 --- a/src/node.rs +++ b/src/node.rs @@ -28,9 +28,6 @@ bitflags! { } } -#[cfg(feature = "binary-format")] -pub use crate::codec::{NodeDecoder, NodeEncoder}; - const FLAGS_OFFSET: isize = 0; const LABEL_LEN_OFFSET: isize = 1; const LABEL_OFFSET: isize = 2; @@ -162,7 +159,7 @@ impl Node { } } - #[cfg(any(feature = "binary-format", feature = "serde"))] + #[cfg(any(feature = "serde"))] pub(crate) fn new_for_decoding(flags: Flags, label_len: u8) -> Self { let mut init_flags = Flags::empty(); let mut layout = Self::initial_layout(label_len as usize); @@ -200,7 +197,7 @@ impl Node { } } - #[cfg(any(feature = "binary-format", feature = "serde"))] + #[cfg(any(feature = "serde"))] pub(crate) fn label_mut(&mut self) -> &mut [u8] { unsafe { let label_len = *self.ptr.offset(LABEL_LEN_OFFSET) as usize;