From 3690dcdf08aa8ee6b6f20eb46eac279763ccac94 Mon Sep 17 00:00:00 2001 From: Bastian Schubert Date: Wed, 10 Jul 2024 13:36:46 +0200 Subject: [PATCH] more minor improvements --- core/Cargo.toml | 1 + core/src/wire/nested.rs | 2 +- core/src/wire/scalars.rs | 29 +++++++++++++++++------------ core/src/wire/test.rs | 8 +++++--- core/src/wire/uuid.rs | 4 ++-- core/src/wire/varint.rs | 21 +++++++++++---------- core/src/wire/wire_type.rs | 26 +++++++++++++------------- derive/src/codegen.rs | 14 +++++++------- examples/shared/Cargo.toml | 7 ++----- 9 files changed, 59 insertions(+), 53 deletions(-) diff --git a/core/Cargo.toml b/core/Cargo.toml index a28fff7..13eb08f 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -15,6 +15,7 @@ uuid_bytes = ["dep:uuid"] [dependencies] bytes = { workspace = true } +smallvec = { workspace = true } thiserror = { workspace = true } tracing = { workspace = true } uuid = { workspace = true, optional = true } diff --git a/core/src/wire/nested.rs b/core/src/wire/nested.rs index bd1b51e..7cda13b 100644 --- a/core/src/wire/nested.rs +++ b/core/src/wire/nested.rs @@ -7,5 +7,5 @@ where T: IntoWire, { let size = message.size_hint(tag); - tag.required_space() + size.required_space() + size + tag.required_space() as usize + size.required_space() as usize + size } diff --git a/core/src/wire/scalars.rs b/core/src/wire/scalars.rs index 3a1e8e1..71a9267 100644 --- a/core/src/wire/scalars.rs +++ b/core/src/wire/scalars.rs @@ -25,7 +25,7 @@ impl IntoWire for f64 { } fn size_hint(&self, tag: u32) -> usize { - 8 + tag.required_space() + 8 + tag.required_space() as usize } } @@ -52,7 +52,7 @@ impl IntoWire for f32 { } fn size_hint(&self, tag: u32) -> usize { - 4 + tag.required_space() + 4 + tag.required_space() as usize } } @@ -81,7 +81,7 @@ impl IntoWire for u64 { } fn size_hint(&self, tag: u32) -> usize { - self.required_space() + tag.required_space() + self.required_space() as usize + tag.required_space() as usize } } @@ -110,7 +110,7 @@ impl IntoWire for i64 { } fn size_hint(&self, tag: u32) -> usize { - self.required_space() + tag.required_space() + self.required_space() as usize + tag.required_space() as usize } } @@ -139,7 +139,7 @@ impl IntoWire for u32 { } fn size_hint(&self, tag: u32) -> usize { - self.required_space() + tag.required_space() + self.required_space() as usize + tag.required_space() as usize } } @@ -168,7 +168,7 @@ impl IntoWire for i32 { } fn size_hint(&self, tag: u32) -> usize { - self.required_space() + tag.required_space() + self.required_space() as usize + tag.required_space() as usize } } @@ -193,7 +193,7 @@ impl IntoWire for String { fn size_hint(&self, tag: u32) -> usize { let len = self.len(); - len.required_space() + tag.required_space() + len + len.required_space() as usize + tag.required_space() as usize + len } } @@ -223,7 +223,7 @@ impl IntoWire for bool { } fn size_hint(&self, tag: u32) -> usize { - if *self { 1u32 } else { 0u32 }.required_space() + tag.required_space() + if *self { 1u32 } else { 0u32 }.required_space() as usize + tag.required_space() as usize } } @@ -232,13 +232,18 @@ where T: Message, { fn into_wire(self) -> WireType { - let mut buffer = bytes::BytesMut::with_capacity(self.size_hint()); - self.serialize(&mut buffer); - WireType::LengthEncoded(buffer.freeze()) + let size = self.size_hint(); + let mut buffer = smallvec::SmallVec::<[u8; 1024]>::new(); + buffer.resize(size, 0); + let mut buffer_ref = buffer.as_mut_slice(); + self.serialize(&mut buffer_ref); + let written = size - buffer_ref.len(); + WireType::LengthEncoded(bytes::Bytes::copy_from_slice(&buffer[0..written])) } fn size_hint(&self, tag: u32) -> usize { - tag.required_space() + self.size_hint() + // println!("size hint {} + {}", tag.required_space(), self.size_hint()); + tag.required_space() as usize + self.size_hint() } } diff --git a/core/src/wire/test.rs b/core/src/wire/test.rs index cfb0b25..960e016 100644 --- a/core/src/wire/test.rs +++ b/core/src/wire/test.rs @@ -587,16 +587,18 @@ mod test_messages { } fn size_hint(&self) -> usize { + let tag_size = 1.required_space() as usize; let map_size: usize = self .map .iter() .map(|(key, value)| { let message_size = key.size_hint(1) + value.size_hint(2); - message_size + message_size.required_space() + 1.required_space() + message_size + message_size.required_space() as usize + tag_size }) - .sum(); + .sum::() + + tag_size; - let nested_size = crate::wire::nested::size_hint(2, &self.nested); + let nested_size = 2.required_space() as usize + IntoWire::size_hint(&self.nested, 2); // crate::wire::nested::size_hint(2, &self.nested); map_size + nested_size } diff --git a/core/src/wire/uuid.rs b/core/src/wire/uuid.rs index 1e4e5dd..a2fefc5 100644 --- a/core/src/wire/uuid.rs +++ b/core/src/wire/uuid.rs @@ -69,8 +69,8 @@ mod uuid_bytes { fn size_hint(&self, tag: u32) -> usize { let (high, low) = self.as_u64_pair(); - let data_len = high.required_space() + low.required_space(); - tag.required_space() + data_len.required_space() + data_len + let data_len = high.required_space() as usize + low.required_space() as usize; + tag.required_space() as usize + data_len.required_space() as usize + data_len } } diff --git a/core/src/wire/varint.rs b/core/src/wire/varint.rs index 4530596..51fed57 100644 --- a/core/src/wire/varint.rs +++ b/core/src/wire/varint.rs @@ -11,7 +11,7 @@ const DROP_MSB: u8 = 0b0111_1111; /// How many bytes an integer uses when being encoded as a VarInt. #[inline] -fn required_encoded_space_unsigned(mut v: u64) -> usize { +fn required_encoded_space_unsigned(mut v: u64) -> u8 { if v == 0 { return 1; } @@ -26,7 +26,7 @@ fn required_encoded_space_unsigned(mut v: u64) -> usize { /// How many bytes an integer uses when being encoded as a VarInt. #[inline] -fn required_encoded_space_signed(v: i64) -> usize { +fn required_encoded_space_signed(v: i64) -> u8 { required_encoded_space_unsigned(zigzag_encode(v)) } @@ -37,7 +37,7 @@ fn required_encoded_space_signed(v: i64) -> usize { pub trait VarInt: Sized + Copy { /// Returns the number of bytes this number needs in its encoded form. Note: This varies /// depending on the actual number you want to encode. - fn required_space(self) -> usize; + fn required_space(self) -> u8; /// Decode a value from the slice. Returns the value and the number of bytes read from the /// slice (can be used to read several consecutive values from a big slice) /// return None if all bytes has MSB set. @@ -49,7 +49,7 @@ pub trait VarInt: Sized + Copy { /// Helper: Encode a value and return the encoded form as Vec. The Vec must be at least /// `required_space()` bytes long. fn encode_var_vec(self) -> Vec { - let mut v = vec![0; self.required_space()]; + let mut v = vec![0; self.required_space() as usize]; self.encode_var(&mut v); v } @@ -71,7 +71,7 @@ fn zigzag_decode(from: u64) -> i64 { macro_rules! impl_varint { ($t:ty, unsigned) => { impl VarInt for $t { - fn required_space(self) -> usize { + fn required_space(self) -> u8 { required_encoded_space_unsigned(self as u64) } @@ -87,7 +87,7 @@ macro_rules! impl_varint { }; ($t:ty, signed) => { impl VarInt for $t { - fn required_space(self) -> usize { + fn required_space(self) -> u8 { required_encoded_space_signed(self as i64) } @@ -117,12 +117,14 @@ impl_varint!(i8, signed); // first cast to these biggest types before being encoded. impl VarInt for u64 { - fn required_space(self) -> usize { + fn required_space(self) -> u8 { required_encoded_space_unsigned(self) } #[inline] fn decode_var(src: &[u8]) -> Option<(Self, usize)> { + const SIXTY_THREE: usize = 9 * 7; + let mut result: u64 = 0; let mut shift = 0; @@ -132,7 +134,7 @@ impl VarInt for u64 { result |= (msb_dropped as u64) << shift; shift += 7; - if b & MSB == 0 || shift > (9 * 7) { + if b & MSB == 0 || shift > SIXTY_THREE { success = b & MSB == 0; break; } @@ -162,7 +164,7 @@ impl VarInt for u64 { } impl VarInt for i64 { - fn required_space(self) -> usize { + fn required_space(self) -> u8 { required_encoded_space_signed(self) } @@ -177,7 +179,6 @@ impl VarInt for i64 { #[inline] fn encode_var(self, dst: &mut [u8]) -> u8 { - assert!(dst.len() >= self.required_space()); let mut n: u64 = zigzag_encode(self); let mut i = 0u8; diff --git a/core/src/wire/wire_type.rs b/core/src/wire/wire_type.rs index 739ac48..6729611 100644 --- a/core/src/wire/wire_type.rs +++ b/core/src/wire/wire_type.rs @@ -62,21 +62,21 @@ impl<'a> WireTypeView<'a> { pub fn size_hint(&self, tag: u32) -> usize { match self { - WireTypeView::VarInt(data) => tag.required_space() + data.len(), - WireTypeView::FixedI64(_) => tag.required_space() + 8, - WireTypeView::SGroup => tag.required_space(), - WireTypeView::EGroup => tag.required_space(), + WireTypeView::VarInt(data) => tag.required_space() as usize + data.len(), + WireTypeView::FixedI64(_) => tag.required_space() as usize + 8, + WireTypeView::SGroup => tag.required_space() as usize, + WireTypeView::EGroup => tag.required_space() as usize, WireTypeView::LengthEncoded(data) => { let data_len = data.len(); - tag.required_space() + data_len.required_space() + data_len + tag.required_space() as usize + data_len.required_space() as usize + data_len } - WireTypeView::FixedI32(_) => tag.required_space() + 4, + WireTypeView::FixedI32(_) => tag.required_space() as usize + 4, } } } /// [WireType] is used for writing messages -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone)] pub enum WireType { VarInt([u8; 10], u8), FixedI64([u8; 8]), @@ -137,15 +137,15 @@ impl WireType { pub fn size_hint(&self, tag: u32) -> usize { match self { - WireType::VarInt(_, size) => tag.required_space() + *size as usize, - WireType::FixedI64(_) => tag.required_space() + 8, - WireType::SGroup => tag.required_space(), - WireType::EGroup => tag.required_space(), + WireType::VarInt(_, size) => tag.required_space() as usize + *size as usize, + WireType::FixedI64(_) => tag.required_space() as usize + 8, + WireType::SGroup => tag.required_space() as usize, + WireType::EGroup => tag.required_space() as usize, WireType::LengthEncoded(data) => { let data_len = data.len(); - tag.required_space() + data_len.required_space() + data_len + tag.required_space() as usize + data_len.required_space() as usize + data_len } - WireType::FixedI32(_) => tag.required_space() + 4, + WireType::FixedI32(_) => tag.required_space() as usize + 4, } } diff --git a/derive/src/codegen.rs b/derive/src/codegen.rs index 43131dd..f5f9769 100644 --- a/derive/src/codegen.rs +++ b/derive/src/codegen.rs @@ -91,7 +91,7 @@ fn expand_message_message( }); size_hint_impl.extend(quote_spanned! { span=> - let #field_size_ident = #tag.required_space() + #root::IntoWire::size_hint(&self.#field_ident, #tag); + let #field_size_ident = #tag.required_space() as usize + #root::IntoWire::size_hint(&self.#field_ident, #tag); }); } Kind::OneOf => { @@ -158,13 +158,13 @@ fn expand_message_message( }); size_hint_impl.extend(quote_spanned! { span=> - let tag_space = #tag.required_space(); + let tag_space = #tag.required_space() as usize; let #field_size_ident: usize = self .#field_ident .iter() .map(|(key, value)| { let message_size = key.size_hint(1) + value.size_hint(2); - message_size + message_size.required_space() + tag_space + message_size + message_size.required_space() as usize + tag_space }) .sum(); }); @@ -301,12 +301,12 @@ fn expand_message_message( size_hint_impl.extend(quote_spanned! { span=> let #field_size_ident = if let Some(map) = self.#field_ident.as_ref() { - let tag_space = #tag.required_space(); + let tag_space = #tag.required_space() as usize; map .iter() .map(|(key, value)| { let message_size = key.size_hint(1) + value.size_hint(2); - message_size + message_size.required_space() + tag_space + message_size + message_size.required_space() as usize + tag_space }) .sum() } else { @@ -554,7 +554,7 @@ pub(crate) fn expand_enumeration( size_hint_impl.extend(quote_spanned! {span=> #ty::#var_ident => { let tag: u32 = #tag; - tag.required_space() + tag.required_space() as usize } }); @@ -576,7 +576,7 @@ pub(crate) fn expand_enumeration( fn size_hint(&self, tag: u32) -> usize { use #root::export::VarInt; - tag.required_space() + tag.required_space() as usize + match self { #size_hint_impl } diff --git a/examples/shared/Cargo.toml b/examples/shared/Cargo.toml index bc7cc0e..279cf16 100644 --- a/examples/shared/Cargo.toml +++ b/examples/shared/Cargo.toml @@ -6,12 +6,9 @@ version = "0.1.0" edition = "2021" [dependencies] -gin-tonic = { version = "0.4.8", features = ["uuid_bytes"] } +gin-tonic = { path = "../../gin", features = ["uuid_bytes"] } tonic = { version = "0.12.0", features = ["transport"] } uuid = { version = "1.10.0" } [build-dependencies] -gin-tonic = { version = "0.4.8", features = ["uuid_bytes"] } - -[patch.crates-io] -gin-tonic = { path = "../../gin" } +gin-tonic = { path = "../../gin", features = ["uuid_bytes"] }