Improve allocations for SszEncoder

This commit is contained in:
Paul Hauner 2019-05-06 09:58:31 +10:00
parent 480c5ff160
commit 56fe63f78d
No known key found for this signature in database
GPG Key ID: D362883A9218FCC6
4 changed files with 22 additions and 19 deletions

View File

@ -17,13 +17,13 @@ impl Encodable for Foo {
+ <Vec<u16> as Encodable>::ssz_fixed_len() + <Vec<u16> as Encodable>::ssz_fixed_len()
+ <u16 as Encodable>::ssz_fixed_len(); + <u16 as Encodable>::ssz_fixed_len();
let mut encoder = SszEncoder::container(offset); let mut encoder = SszEncoder::container(buf, offset);
encoder.append(&self.a); encoder.append(&self.a);
encoder.append(&self.b); encoder.append(&self.b);
encoder.append(&self.c); encoder.append(&self.c);
encoder.drain_onto(buf); encoder.finalize();
} }
} }

View File

@ -25,48 +25,51 @@ pub trait Encodable {
} }
} }
pub struct SszEncoder { pub struct SszEncoder<'a> {
offset: usize, offset: usize,
fixed_bytes: Vec<u8>, buf: &'a mut Vec<u8>,
variable_bytes: Vec<u8>, variable_bytes: Vec<u8>,
} }
impl SszEncoder { impl<'a> SszEncoder<'a> {
pub fn list(num_fixed_bytes: usize) -> Self { pub fn list(buf: &'a mut Vec<u8>, num_fixed_bytes: usize) -> Self {
Self::container(num_fixed_bytes) Self::container(buf, num_fixed_bytes)
} }
pub fn container(num_fixed_bytes: usize) -> Self { pub fn container(buf: &'a mut Vec<u8>, num_fixed_bytes: usize) -> Self {
buf.reserve(num_fixed_bytes);
Self { Self {
offset: num_fixed_bytes, offset: num_fixed_bytes,
fixed_bytes: Vec::with_capacity(num_fixed_bytes), buf,
variable_bytes: vec![], variable_bytes: vec![],
} }
} }
pub fn append<T: Encodable>(&mut self, item: &T) { pub fn append<T: Encodable>(&mut self, item: &T) {
if T::is_ssz_fixed_len() { if T::is_ssz_fixed_len() {
item.ssz_append(&mut self.fixed_bytes); item.ssz_append(&mut self.buf);
} else { } else {
self.fixed_bytes self.buf
.append(&mut encode_length(self.offset + self.variable_bytes.len())); .append(&mut encode_length(self.offset + self.variable_bytes.len()));
item.ssz_append(&mut self.variable_bytes); item.ssz_append(&mut self.variable_bytes);
} }
} }
pub fn drain_onto(mut self, buf: &mut Vec<u8>) { pub fn finalize(&mut self) -> &mut Vec<u8> {
buf.append(&mut self.fixed_bytes); self.buf.append(&mut self.variable_bytes);
buf.append(&mut self.variable_bytes);
&mut self.buf
} }
} }
/*
pub struct VariableLengths { pub struct VariableLengths {
pub fixed_bytes_position: usize, pub fixed_bytes_position: usize,
pub variable_bytes_length: usize, pub variable_bytes_length: usize,
} }
/*
/// Provides a buffer for appending SSZ values. /// Provides a buffer for appending SSZ values.
#[derive(Default)] #[derive(Default)]
pub struct SszStream { pub struct SszStream {

View File

@ -38,13 +38,13 @@ impl<T: Encodable> Encodable for Vec<T> {
item.ssz_append(buf); item.ssz_append(buf);
} }
} else { } else {
let mut encoder = SszEncoder::list(self.len() * BYTES_PER_LENGTH_OFFSET); let mut encoder = SszEncoder::list(buf, self.len() * BYTES_PER_LENGTH_OFFSET);
for item in self { for item in self {
encoder.append(item); encoder.append(item);
} }
encoder.drain_onto(buf); encoder.finalize();
} }
} }
} }

View File

@ -109,13 +109,13 @@ pub fn ssz_encode_derive(input: TokenStream) -> TokenStream {
)* )*
0; 0;
let mut encoder = ssz::SszEncoder::container(offset); let mut encoder = ssz::SszEncoder::container(buf, offset);
#( #(
encoder.append(&self.#field_idents); encoder.append(&self.#field_idents);
)* )*
encoder.drain_onto(buf); encoder.finalize();
} }
} }
}; };