Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions tree-buf-macros/src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,9 @@ fn fill_decode_skeleton<A: ToTokens>(

fn impl_enum_decode(ast: &DeriveInput, data_enum: &DataEnum) -> TokenStream {
let ident = &ast.ident;
let mut array_fields = Vec::new();
array_fields.push(quote! {
let mut array_fields = vec![quote! {
tree_buf_discriminant: <u64 as ::tree_buf::Decodable>::DecoderArray
});
}];

let mut new_matches = Vec::new();
let mut new_inits = Vec::new();
Expand Down
5 changes: 2 additions & 3 deletions tree-buf-macros/src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,11 @@ fn impl_enum_encode(ast: &DeriveInput, data_enum: &DataEnum) -> TokenStream {
// For each variant, possibly it's own encoder struct if it's a tuple or struct sort of DataEnum
// A discriminant

let mut array_fields = Vec::new();
array_fields.push(quote! {
let mut array_fields = vec![quote! {
// TODO: (Performance) have the size scale to the number of variants
tree_buf_discriminant: <u64 as ::tree_buf::Encodable>::EncoderArray,
tree_buf_next_discriminant: u64
});
}];

let mut array_matches = Vec::new();
let mut root_matches = Vec::new();
Expand Down
6 changes: 2 additions & 4 deletions tree-buf-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,16 @@ extern crate syn;
#[macro_use]
extern crate quote;

mod utils;
mod decode;
mod encode;
mod utils;

use {
decode::impl_decode_macro,
encode::impl_encode_macro,
syn::{parse_macro_input, DeriveInput},
};



#[proc_macro_derive(Encode)]
pub fn encode_macro_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
Expand All @@ -27,4 +25,4 @@ pub fn decode_macro_derive(input: proc_macro::TokenStream) -> proc_macro::TokenS
let ast = parse_macro_input!(input as DeriveInput);
let output = impl_decode_macro(&ast);
proc_macro::TokenStream::from(output)
}
}
1 change: 0 additions & 1 deletion tree-buf/benches/float_list.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use tree_buf::prelude::*;

/*

Expand Down
2 changes: 1 addition & 1 deletion tree-buf/src/experimental/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! or resulting file may change unexpectedly with any version. Even so, it is worth
//! poking around.

pub mod options;
#[doc(hidden)]
pub mod scratch;
pub mod stats;
pub mod options;
13 changes: 3 additions & 10 deletions tree-buf/src/experimental/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,9 @@

use crate::prelude::*;

pub use crate::internal::options::{
DisableParallel,
EnableParallel,
LosslessFloat,
LossyFloatTolerance,
EncodeOptions, DecodeOptions
};

pub use crate::{encode_options, decode_options};
pub use crate::internal::options::{DecodeOptions, DisableParallel, EnableParallel, EncodeOptions, LosslessFloat, LossyFloatTolerance};

pub use crate::{decode_options, encode_options};

#[cfg(feature = "encode")]
pub fn encode_with_options<T: Encodable>(value: &T, options: &impl EncodeOptions) -> Vec<u8> {
Expand All @@ -38,4 +31,4 @@ pub fn decode_with_options<T: Decodable>(bytes: &[u8], options: &impl DecodeOpti
profile_fn!(T, decode_with_options);
let sticks = decode_root(bytes)?;
T::decode(sticks, options)
}
}
3 changes: 2 additions & 1 deletion tree-buf/src/experimental/scratch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ impl Scratch {

/// A re-usable object which may increase performance when encoding over and over again
/// in a loop. Avoids allocations
#[must_use]
pub fn scratch<T: Encodable>() -> Scratch {
Scratch { buffers: Default::default() }
Scratch { buffers: Rc::default() }
}

pub fn encode_into_with_scratch<T: Encodable>(_value: &T, _scratch: &mut Scratch, _into: &mut Vec<u8>) {
Expand Down
72 changes: 35 additions & 37 deletions tree-buf/src/experimental/stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,14 @@ struct Path {
}

impl Path {
fn c(s: &String, x: &impl fmt::Display) -> String {
fn c(s: &str, x: &impl fmt::Display) -> String {
let x = format!("{}", x);
if s.is_empty() {
x
} else if x.is_empty() {
s.to_string()
} else {
if x.is_empty() {
s.clone()
} else {
format!("{}.{}", s, x)
}
format!("{}.{}", s, x)
}
}

Expand Down Expand Up @@ -59,13 +57,13 @@ impl fmt::Display for SizeBreakdown {
by_type.sort_by_key(|i| usize::MAX - i.1.size);

writeln!(f, "Largest by path:")?;
for (path, agg) in by_path.iter() {
for (path, agg) in &by_path {
writeln!(f, "\t{}\n\t {}\n\t {}", agg.size, path, agg.types)?;
}

writeln!(f)?;
writeln!(f, "Largest by type:")?;
for (t, agg) in by_type.iter() {
for (t, agg) in &by_type {
writeln!(f, "\t {}x {} @ {}", agg.count, agg.size, t)?;
}

Expand Down Expand Up @@ -98,22 +96,22 @@ impl SizeBreakdown {
}
}

fn visit_array(path: Path, branch: &DynArrayBranch, breakdown: &mut SizeBreakdown) {
fn visit_array(path: &Path, branch: &DynArrayBranch, breakdown: &mut SizeBreakdown) {
match branch {
DynArrayBranch::ArrayFixed { values, len } => visit_array(path.a(&format!("[{}]", len), &"Array Fixed"), values, breakdown),
DynArrayBranch::ArrayFixed { values, len } => visit_array(&path.a(&format!("[{}]", len), &"Array Fixed"), values, breakdown),
DynArrayBranch::Array { len, values } => {
visit_array(path.a(&"len", &"Array"), len, breakdown);
visit_array(path.a(&"values", &"Array"), values, breakdown);
visit_array(&path.a(&"len", &"Array"), len, breakdown);
visit_array(&path.a(&"values", &"Array"), values, breakdown);
}
DynArrayBranch::Enum { discriminants, variants } => {
visit_array(path.a(&"discriminants", &"Enum"), discriminants, breakdown);
visit_array(&path.a(&"discriminants", &"Enum"), discriminants, breakdown);
for variant in variants.iter() {
visit_array(path.a(&variant.ident, &"Enum"), &variant.data, breakdown);
visit_array(&path.a(&variant.ident, &"Enum"), &variant.data, breakdown);
}
}
DynArrayBranch::Boolean(enc) => match enc {
ArrayBool::Packed(b) => breakdown.add(&path, "Packed Boolean", b),
ArrayBool::RLE(_first, runs) => visit_array(path.a(&"runs", &"Bool RLE"), runs, breakdown),
ArrayBool::RLE(_first, runs) => visit_array(&path.a(&"runs", &"Bool RLE"), runs, breakdown),
},
DynArrayBranch::Float(f) => match f {
ArrayFloat::DoubleGorilla(b) => breakdown.add(&path, "Gorilla", b),
Expand All @@ -129,60 +127,60 @@ fn visit_array(path: Path, branch: &DynArrayBranch, breakdown: &mut SizeBreakdow
ArrayIntegerEncoding::DeltaZig => breakdown.add(&path, "DeltaZig", bytes),
},
DynArrayBranch::Map { len, keys, values } => {
visit_array(path.a(&"len", &"Map"), len, breakdown);
visit_array(path.a(&"keys", &"Map"), keys, breakdown);
visit_array(path.a(&"values", &"Map"), values, breakdown);
visit_array(&path.a(&"len", &"Map"), len, breakdown);
visit_array(&path.a(&"keys", &"Map"), keys, breakdown);
visit_array(&path.a(&"values", &"Map"), values, breakdown);
}
DynArrayBranch::Object { fields } => {
for (name, field) in fields {
visit_array(path.a(name, &"Object"), field, breakdown);
visit_array(&path.a(name, &"Object"), field, breakdown);
}
}
DynArrayBranch::RLE { runs, values } => {
visit_array(path.a(&"runs", &"RLE"), runs, breakdown);
visit_array(path.a(&"values", &"RLE"), values, breakdown);
visit_array(&path.a(&"runs", &"RLE"), runs, breakdown);
visit_array(&path.a(&"values", &"RLE"), values, breakdown);
}
DynArrayBranch::Dictionary { indices, values } => {
visit_array(path.a(&"indices", &"Dictionary"), indices, breakdown);
visit_array(path.a(&"values", &"Dictionary"), values, breakdown);
visit_array(&path.a(&"indices", &"Dictionary"), indices, breakdown);
visit_array(&path.a(&"values", &"Dictionary"), values, breakdown);
}
DynArrayBranch::String(b) => breakdown.add(&path, "UTF-8", b),
DynArrayBranch::Tuple { fields } => {
for (i, field) in fields.iter().enumerate() {
visit_array(path.a(&i, &"Tuple"), field, breakdown);
visit_array(&path.a(&i, &"Tuple"), field, breakdown);
}
}
DynArrayBranch::Nullable { opt, values } => {
visit_array(path.a(&"opt", &"Nullable"), opt, breakdown);
visit_array(path.a(&"values", &"Nullable"), values, breakdown);
visit_array(&path.a(&"opt", &"Nullable"), opt, breakdown);
visit_array(&path.a(&"values", &"Nullable"), values, breakdown);
}
DynArrayBranch::Void | DynArrayBranch::Map0 | DynArrayBranch::Array0 => {}
}
}

fn visit(path: Path, branch: &DynRootBranch<'_>, breakdown: &mut SizeBreakdown) {
fn visit(path: &Path, branch: &DynRootBranch<'_>, breakdown: &mut SizeBreakdown) {
match branch {
DynRootBranch::Object { fields } => {
for (name, value) in fields.iter() {
visit(path.a(name, &"Object"), value, breakdown);
visit(&path.a(name, &"Object"), value, breakdown);
}
}
DynRootBranch::Enum { discriminant, value } => visit(path.a(discriminant, &"Enum"), value, breakdown),
DynRootBranch::Enum { discriminant, value } => visit(&path.a(discriminant, &"Enum"), value, breakdown),
DynRootBranch::Map { len: _, keys, values } => {
visit_array(path.a(&"keys", &"Map"), keys, breakdown);
visit_array(path.a(&"values", &"Values"), values, breakdown);
visit_array(&path.a(&"keys", &"Map"), keys, breakdown);
visit_array(&path.a(&"values", &"Values"), values, breakdown);
}
DynRootBranch::Tuple { fields } => {
for (i, field) in fields.iter().enumerate() {
visit(path.a(&i, &"Tuple"), field, breakdown);
visit(&path.a(&i, &"Tuple"), field, breakdown);
}
}
DynRootBranch::Map1 { key, value } => {
visit(path.a(&"key", &"Map1"), key, breakdown);
visit(path.a(&"value", &"Map1"), value, breakdown);
visit(&path.a(&"key", &"Map1"), key, breakdown);
visit(&path.a(&"value", &"Map1"), value, breakdown);
}
DynRootBranch::Array { len, values } => visit_array(path.a(&format!("[{}]", len), &"Array"), values, breakdown),
DynRootBranch::Array1(item) => visit(path.a(&"1", &"Array1"), item, breakdown),
DynRootBranch::Array { len, values } => visit_array(&path.a(&format!("[{}]", len), &"Array"), values, breakdown),
DynRootBranch::Array1(item) => visit(&path.a(&"1", &"Array1"), item, breakdown),
DynRootBranch::Boolean(_)
| DynRootBranch::Array0
| DynRootBranch::Map0
Expand Down Expand Up @@ -269,7 +267,7 @@ pub fn size_breakdown(data: &[u8]) -> DecodeResult<String> {
by_type: HashMap::new(),
total: data.len(),
};
visit(Path::default(), &root, &mut breakdown);
visit(&Path::default(), &root, &mut breakdown);

Ok(format!("{}", breakdown))
}
43 changes: 22 additions & 21 deletions tree-buf/src/internal/branch/array_branch.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::internal::encodings::varint::*;
use crate::internal::encodings::varint::{decode_prefix_varint, decode_suffix_varint};
use crate::prelude::*;
use std::collections::HashMap;
use std::convert::{TryFrom, TryInto};
Expand Down Expand Up @@ -105,10 +105,13 @@ pub enum DynArrayBranch<'a> {
pub fn decode_next_array<'a>(bytes: &'a [u8], offset: &'_ mut usize, lens: &'_ mut usize) -> DecodeResult<DynArrayBranch<'a>> {
let id = ArrayTypeId::decode_next(bytes, offset)?;

use ArrayTypeId::*;
use ArrayTypeId::{
ArrayFixed, ArrayVar, DeltaZig, Dictionary, DoubleGorilla, Enum, IntPrefixVar, IntSimple16, Map, Nullable, Obj0, Obj1, Obj2, Obj3, Obj4, Obj5, Obj6, Obj7, Obj8, ObjN,
PackedBool, RLEBoolFalse, RLEBoolTrue, Tuple2, Tuple3, Tuple4, Tuple5, Tuple6, Tuple7, Tuple8, TupleN, Utf8, Void, Zfp32, Zfp64, F32, F64, RLE, U8,
};

fn decode_ints<'a>(bytes: &'a [u8], offset: &'_ mut usize, lens: &'_ mut usize, encoding: ArrayIntegerEncoding) -> DecodeResult<DynArrayBranch<'a>> {
let bytes = decode_bytes_from_len(bytes, offset, lens)?.into();
let bytes = decode_bytes_from_len(bytes, offset, lens)?;
Ok(DynArrayBranch::Integer(ArrayInteger { bytes, encoding }))
}

Expand Down Expand Up @@ -155,14 +158,13 @@ pub fn decode_next_array<'a>(bytes: &'a [u8], offset: &'_ mut usize, lens: &'_ m
TupleN => decode_tuple(decode_prefix_varint(bytes, offset)? as usize + 9, bytes, offset, lens)?,
ArrayVar => {
let len = decode_next_array(bytes, offset, lens)?;
match len {
DynArrayBranch::Void => DynArrayBranch::Array0,
_ => {
let len = Box::new(len);
let values = decode_next_array(bytes, offset, lens)?;
let values = Box::new(values);
DynArrayBranch::Array { len, values }
}
if let DynArrayBranch::Void = len {
DynArrayBranch::Array0
} else {
let len = Box::new(len);
let values = decode_next_array(bytes, offset, lens)?;
let values = Box::new(values);
DynArrayBranch::Array { len, values }
}
}
ArrayFixed => {
Expand All @@ -173,16 +175,15 @@ pub fn decode_next_array<'a>(bytes: &'a [u8], offset: &'_ mut usize, lens: &'_ m
}
Map => {
let len = decode_next_array(bytes, offset, lens)?;
match len {
DynArrayBranch::Void => DynArrayBranch::Map0,
_ => {
let len = Box::new(len);
let keys = decode_next_array(bytes, offset, lens)?;
let keys = Box::new(keys);
let values = decode_next_array(bytes, offset, lens)?;
let values = Box::new(values);
DynArrayBranch::Map { len, keys, values }
}
if let DynArrayBranch::Void = len {
DynArrayBranch::Map0
} else {
let len = Box::new(len);
let keys = decode_next_array(bytes, offset, lens)?;
let keys = Box::new(keys);
let values = decode_next_array(bytes, offset, lens)?;
let values = Box::new(values);
DynArrayBranch::Map { len, keys, values }
}
}

Expand Down
4 changes: 2 additions & 2 deletions tree-buf/src/internal/branch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ pub trait TypeId: Copy + Into<u8> + PartialEq + std::fmt::Debug {
#[cfg(feature = "decode")]
pub fn decode_root(bytes: &[u8]) -> DecodeResult<DynRootBranch<'_>> {
profile_fn!(decode_root);
if bytes.len() == 0 {
if bytes.is_empty() {
return Ok(DynRootBranch::Void);
}
let mut lens = bytes.len() - 1;
Expand All @@ -131,7 +131,7 @@ mod tests {
use super::*;
use std::convert::{TryFrom, TryInto};
fn convert_all<T: TryFrom<u8> + Into<u8>>() {
for i in 0..=255u8 {
for i in 0..=255_u8 {
let v: Result<T, _> = i.try_into();
if let Ok(v) = v {
debug_assert_eq!(i, v.into());
Expand Down
Loading