Speed up Vec<u8> [d]e[n]code operations by dropping the generic
This commit is contained in:
parent
ee827e4aa3
commit
fa1ec2028d
|
@ -45,6 +45,10 @@ use secp256k1;
|
||||||
use util::base58;
|
use util::base58;
|
||||||
use util::psbt;
|
use util::psbt;
|
||||||
|
|
||||||
|
use blockdata::transaction::{TxOut, Transaction, TxIn};
|
||||||
|
use network::message_blockdata::Inventory;
|
||||||
|
use network::address::Address;
|
||||||
|
|
||||||
/// Encoding error
|
/// Encoding error
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
@ -551,21 +555,23 @@ impl<S: Encoder> Encodable<S> for [u16; 8] {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vectors
|
// Vectors
|
||||||
impl<S: Encoder, T: Encodable<S>> Encodable<S> for Vec<T> {
|
macro_rules! impl_vec {
|
||||||
|
($type: ty) => {
|
||||||
|
impl<S: Encoder> Encodable<S> for Vec<$type> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), self::Error> {
|
fn consensus_encode(&self, s: &mut S) -> Result<(), self::Error> {
|
||||||
VarInt(self.len() as u64).consensus_encode(s)?;
|
VarInt(self.len() as u64).consensus_encode(s)?;
|
||||||
for c in self.iter() { c.consensus_encode(s)?; }
|
for c in self.iter() { c.consensus_encode(s)?; }
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Vec<T> {
|
impl<D: Decoder> Decodable<D> for Vec<$type> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode(d: &mut D) -> Result<Vec<T>, self::Error> {
|
fn consensus_decode(d: &mut D) -> Result<Vec<$type>, self::Error> {
|
||||||
let len = VarInt::consensus_decode(d)?.0;
|
let len = VarInt::consensus_decode(d)?.0;
|
||||||
let byte_size = (len as usize)
|
let byte_size = (len as usize)
|
||||||
.checked_mul(mem::size_of::<T>())
|
.checked_mul(mem::size_of::<$type>())
|
||||||
.ok_or(self::Error::ParseFailed("Invalid length"))?;
|
.ok_or(self::Error::ParseFailed("Invalid length"))?;
|
||||||
if byte_size > MAX_VEC_SIZE {
|
if byte_size > MAX_VEC_SIZE {
|
||||||
return Err(self::Error::OversizedVectorAllocation { requested: byte_size, max: MAX_VEC_SIZE })
|
return Err(self::Error::OversizedVectorAllocation { requested: byte_size, max: MAX_VEC_SIZE })
|
||||||
|
@ -574,6 +580,39 @@ impl<D: Decoder, T: Decodable<D>> Decodable<D> for Vec<T> {
|
||||||
for _ in 0..len { ret.push(Decodable::consensus_decode(d)?); }
|
for _ in 0..len { ret.push(Decodable::consensus_decode(d)?); }
|
||||||
Ok(ret)
|
Ok(ret)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl_vec!(sha256d::Hash);
|
||||||
|
impl_vec!(Transaction);
|
||||||
|
impl_vec!(TxOut);
|
||||||
|
impl_vec!(TxIn);
|
||||||
|
impl_vec!(Inventory);
|
||||||
|
impl_vec!(Vec<u8>);
|
||||||
|
impl_vec!((u32, Address));
|
||||||
|
impl_vec!(u64);
|
||||||
|
|
||||||
|
impl<S: Encoder> Encodable<S> for Vec<u8> {
|
||||||
|
#[inline]
|
||||||
|
fn consensus_encode(&self, s: &mut S) -> Result<(), self::Error> {
|
||||||
|
VarInt(self.len() as u64).consensus_encode(s)?;
|
||||||
|
s.emit_slice(&self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: Decoder> Decodable<D> for Vec<u8> {
|
||||||
|
#[inline]
|
||||||
|
fn consensus_decode(d: &mut D) -> Result<Vec<u8>, self::Error> {
|
||||||
|
let len = VarInt::consensus_decode(d)?.0;
|
||||||
|
let len = len as usize;
|
||||||
|
if len > MAX_VEC_SIZE {
|
||||||
|
return Err(self::Error::OversizedVectorAllocation { requested: len, max: MAX_VEC_SIZE })
|
||||||
|
}
|
||||||
|
let mut ret = Vec::with_capacity(len);
|
||||||
|
ret.resize(len, 0);
|
||||||
|
d.read_slice(&mut ret)?;
|
||||||
|
Ok(ret)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Encoder> Encodable<S> for Box<[u8]> {
|
impl<S: Encoder> Encodable<S> for Box<[u8]> {
|
||||||
|
|
Loading…
Reference in New Issue