Stack-based allocation for serialization.
This commit is contained in:
parent
1320986642
commit
90a3ada499
|
@ -52,8 +52,9 @@ use tiny_keccak::keccak256;
|
||||||
|
|
||||||
// 3 according to yellowpaper
|
// 3 according to yellowpaper
|
||||||
const BLOOM_BITS: u32 = 3;
|
const BLOOM_BITS: u32 = 3;
|
||||||
|
const BLOOM_SIZE: usize = 256;
|
||||||
|
|
||||||
construct_hash!(Bloom, 256);
|
construct_hash!(Bloom, BLOOM_SIZE);
|
||||||
|
|
||||||
/// Returns log2.
|
/// Returns log2.
|
||||||
fn log2(x: usize) -> u32 {
|
fn log2(x: usize) -> u32 {
|
||||||
|
@ -175,20 +176,20 @@ impl Bloom {
|
||||||
|
|
||||||
pub fn accrue_bloom<'a, B>(&mut self, bloom: B) where BloomRef<'a>: From<B> {
|
pub fn accrue_bloom<'a, B>(&mut self, bloom: B) where BloomRef<'a>: From<B> {
|
||||||
let bloom_ref: BloomRef = bloom.into();
|
let bloom_ref: BloomRef = bloom.into();
|
||||||
assert_eq!(self.0.len(), 256);
|
assert_eq!(self.0.len(), BLOOM_SIZE);
|
||||||
assert_eq!(bloom_ref.0.len(), 256);
|
assert_eq!(bloom_ref.0.len(), BLOOM_SIZE);
|
||||||
for i in 0..256 {
|
for i in 0..BLOOM_SIZE {
|
||||||
self.0[i] |= bloom_ref.0[i];
|
self.0[i] |= bloom_ref.0[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn data(&self) -> &[u8; 256] {
|
pub fn data(&self) -> &[u8; BLOOM_SIZE] {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct BloomRef<'a>(&'a [u8; 256]);
|
pub struct BloomRef<'a>(&'a [u8; BLOOM_SIZE]);
|
||||||
|
|
||||||
impl<'a> BloomRef<'a> {
|
impl<'a> BloomRef<'a> {
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
|
@ -202,9 +203,9 @@ impl<'a> BloomRef<'a> {
|
||||||
|
|
||||||
pub fn contains_bloom<'b, B>(&self, bloom: B) -> bool where BloomRef<'b>: From<B> {
|
pub fn contains_bloom<'b, B>(&self, bloom: B) -> bool where BloomRef<'b>: From<B> {
|
||||||
let bloom_ref: BloomRef = bloom.into();
|
let bloom_ref: BloomRef = bloom.into();
|
||||||
assert_eq!(self.0.len(), 256);
|
assert_eq!(self.0.len(), BLOOM_SIZE);
|
||||||
assert_eq!(bloom_ref.0.len(), 256);
|
assert_eq!(bloom_ref.0.len(), BLOOM_SIZE);
|
||||||
for i in 0..256 {
|
for i in 0..BLOOM_SIZE {
|
||||||
let a = self.0[i];
|
let a = self.0[i];
|
||||||
let b = bloom_ref.0[i];
|
let b = bloom_ref.0[i];
|
||||||
if (a & b) != b {
|
if (a & b) != b {
|
||||||
|
@ -214,13 +215,13 @@ impl<'a> BloomRef<'a> {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn data(&self) -> &'a [u8; 256] {
|
pub fn data(&self) -> &'a [u8; BLOOM_SIZE] {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a [u8; 256]> for BloomRef<'a> {
|
impl<'a> From<&'a [u8; BLOOM_SIZE]> for BloomRef<'a> {
|
||||||
fn from(data: &'a [u8; 256]) -> Self {
|
fn from(data: &'a [u8; BLOOM_SIZE]) -> Self {
|
||||||
BloomRef(data)
|
BloomRef(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,14 +235,15 @@ impl<'a> From<&'a Bloom> for BloomRef<'a> {
|
||||||
#[cfg(feature="serialize")]
|
#[cfg(feature="serialize")]
|
||||||
impl Serialize for Bloom {
|
impl Serialize for Bloom {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
|
||||||
ethereum_types_serialize::serialize(&self.0, serializer)
|
let mut slice = [0u8; 2 + 2 * BLOOM_SIZE];
|
||||||
|
ethereum_types_serialize::serialize(&mut slice, &self.0, serializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature="serialize")]
|
#[cfg(feature="serialize")]
|
||||||
impl<'de> Deserialize<'de> for Bloom {
|
impl<'de> Deserialize<'de> for Bloom {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
|
||||||
let mut bytes = [0; 256];
|
let mut bytes = [0; BLOOM_SIZE];
|
||||||
ethereum_types_serialize::deserialize_check_len(deserializer, ethereum_types_serialize::ExpectedLen::Exact(&mut bytes))?;
|
ethereum_types_serialize::deserialize_check_len(deserializer, ethereum_types_serialize::ExpectedLen::Exact(&mut bytes))?;
|
||||||
Ok(Bloom(bytes))
|
Ok(Bloom(bytes))
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,8 @@ macro_rules! impl_serde {
|
||||||
#[cfg(feature="serialize")]
|
#[cfg(feature="serialize")]
|
||||||
impl Serialize for $name {
|
impl Serialize for $name {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
|
||||||
ethereum_types_serialize::serialize(&self.0, serializer)
|
let mut slice = [0u8; 2 + 2 * $len];
|
||||||
|
ethereum_types_serialize::serialize(&mut slice, &self.0, serializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -334,9 +334,10 @@ macro_rules! impl_serde {
|
||||||
#[cfg(feature="serialize")]
|
#[cfg(feature="serialize")]
|
||||||
impl Serialize for $name {
|
impl Serialize for $name {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
|
||||||
|
let mut slice = [0u8; 2 + 2 * $len * 8];
|
||||||
let mut bytes = [0u8; $len * 8];
|
let mut bytes = [0u8; $len * 8];
|
||||||
self.to_big_endian(&mut bytes);
|
self.to_big_endian(&mut bytes);
|
||||||
ethereum_types_serialize::serialize_uint(&bytes, serializer)
|
ethereum_types_serialize::serialize_uint(&mut slice, &bytes, serializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,38 +5,43 @@ use serde::{de, Serializer, Deserializer};
|
||||||
|
|
||||||
static CHARS: &'static[u8] = b"0123456789abcdef";
|
static CHARS: &'static[u8] = b"0123456789abcdef";
|
||||||
|
|
||||||
fn to_hex(bytes: &[u8], skip_leading_zero: bool) -> String {
|
fn to_hex<'a>(v: &'a mut [u8], bytes: &[u8], skip_leading_zero: bool) -> &'a str {
|
||||||
let mut v = Vec::with_capacity(2 + bytes.len() * 2);
|
assert!(v.len() > 1 + bytes.len() * 2);
|
||||||
v.push('0' as u8);
|
|
||||||
v.push('x' as u8);
|
|
||||||
|
|
||||||
|
v[0] = '0' as u8;
|
||||||
|
v[1] = 'x' as u8;
|
||||||
|
|
||||||
|
let mut idx = 2;
|
||||||
let first_nibble = bytes[0] >> 4;
|
let first_nibble = bytes[0] >> 4;
|
||||||
if first_nibble != 0 || !skip_leading_zero {
|
if first_nibble != 0 || !skip_leading_zero {
|
||||||
v.push(CHARS[first_nibble as usize]);
|
v[idx] = CHARS[first_nibble as usize];
|
||||||
|
idx += 1;
|
||||||
}
|
}
|
||||||
v.push(CHARS[(bytes[0] & 0xf) as usize]);
|
v[idx] = CHARS[(bytes[0] & 0xf) as usize];
|
||||||
|
idx += 1;
|
||||||
|
|
||||||
for &byte in bytes.iter().skip(1) {
|
for &byte in bytes.iter().skip(1) {
|
||||||
v.push(CHARS[(byte >> 4) as usize]);
|
v[idx] = CHARS[(byte >> 4) as usize];
|
||||||
v.push(CHARS[(byte & 0xf) as usize]);
|
v[idx + 1] = CHARS[(byte & 0xf) as usize];
|
||||||
|
idx += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
::std::str::from_utf8(&v[0..idx]).expect("All characters are coming from CHARS")
|
||||||
String::from_utf8_unchecked(v)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serializes a slice of bytes.
|
/// Serializes a slice of bytes.
|
||||||
pub fn serialize<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> where
|
pub fn serialize<S>(slice: &mut [u8], bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
serializer.serialize_str(&to_hex(bytes, false))
|
let mut v = Vec::with_capacity(2 + bytes.len() * 2);
|
||||||
|
v.resize(2 + bytes.len() * 2, 0);
|
||||||
|
serializer.serialize_str(to_hex(slice, bytes, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serialize a slice of bytes as uint.
|
/// Serialize a slice of bytes as uint.
|
||||||
///
|
///
|
||||||
/// The representation will have all leading zeros trimmed.
|
/// The representation will have all leading zeros trimmed.
|
||||||
pub fn serialize_uint<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> where
|
pub fn serialize_uint<S>(slice: &mut [u8], bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
let non_zero = bytes.iter().take_while(|b| **b == 0).count();
|
let non_zero = bytes.iter().take_while(|b| **b == 0).count();
|
||||||
|
@ -45,8 +50,7 @@ pub fn serialize_uint<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
|
||||||
return serializer.serialize_str("0x0");
|
return serializer.serialize_str("0x0");
|
||||||
}
|
}
|
||||||
|
|
||||||
let string = to_hex(bytes, true);
|
serializer.serialize_str(to_hex(slice, bytes, true))
|
||||||
serializer.serialize_str(&*string)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Expected length of bytes vector.
|
/// Expected length of bytes vector.
|
||||||
|
|
Loading…
Reference in New Issue