cache item count in Rlp
This commit is contained in:
parent
900fc833f0
commit
f34b22c65b
@ -26,7 +26,7 @@ pub struct RlpStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Stream for RlpStream {
|
impl Stream for RlpStream {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
RlpStream {
|
RlpStream {
|
||||||
unfinished_lists: ElasticArray16::new(),
|
unfinished_lists: ElasticArray16::new(),
|
||||||
encoder: BasicEncoder::new(),
|
encoder: BasicEncoder::new(),
|
||||||
@ -57,7 +57,7 @@ impl Stream for RlpStream {
|
|||||||
self.encoder.bytes.push(0xc0u8);
|
self.encoder.bytes.push(0xc0u8);
|
||||||
self.note_appended(1);
|
self.note_appended(1);
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
let position = self.encoder.bytes.len();
|
let position = self.encoder.bytes.len();
|
||||||
self.unfinished_lists.push(ListInfo::new(position, len));
|
self.unfinished_lists.push(ListInfo::new(position, len));
|
||||||
},
|
},
|
||||||
@ -66,7 +66,7 @@ impl Stream for RlpStream {
|
|||||||
// return chainable self
|
// return chainable self
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_empty_data<'a>(&'a mut self) -> &'a mut RlpStream {
|
fn append_empty_data<'a>(&'a mut self) -> &'a mut RlpStream {
|
||||||
// self push raw item
|
// self push raw item
|
||||||
self.encoder.bytes.push(0x80);
|
self.encoder.bytes.push(0x80);
|
||||||
@ -80,7 +80,7 @@ impl Stream for RlpStream {
|
|||||||
|
|
||||||
fn append_raw<'a>(&'a mut self, bytes: &[u8], item_count: usize) -> &'a mut RlpStream {
|
fn append_raw<'a>(&'a mut self, bytes: &[u8], item_count: usize) -> &'a mut RlpStream {
|
||||||
// push raw items
|
// push raw items
|
||||||
self.encoder.bytes.append_slice(bytes);
|
self.encoder.bytes.append_slice(bytes);
|
||||||
|
|
||||||
// try to finish and prepend the length
|
// try to finish and prepend the length
|
||||||
self.note_appended(item_count);
|
self.note_appended(item_count);
|
||||||
|
@ -41,22 +41,24 @@ impl PayloadInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Data-oriented view onto rlp-slice.
|
/// Data-oriented view onto rlp-slice.
|
||||||
///
|
///
|
||||||
/// This is immutable structere. No operations change it.
|
/// This is immutable structere. No operations change it.
|
||||||
///
|
///
|
||||||
/// Should be used in places where, error handling is required,
|
/// Should be used in places where, error handling is required,
|
||||||
/// eg. on input
|
/// eg. on input
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UntrustedRlp<'a> {
|
pub struct UntrustedRlp<'a> {
|
||||||
bytes: &'a [u8],
|
bytes: &'a [u8],
|
||||||
cache: Cell<OffsetCache>,
|
offset_cache: Cell<OffsetCache>,
|
||||||
|
count_cache: Cell<Option<usize>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Clone for UntrustedRlp<'a> {
|
impl<'a> Clone for UntrustedRlp<'a> {
|
||||||
fn clone(&self) -> UntrustedRlp<'a> {
|
fn clone(&self) -> UntrustedRlp<'a> {
|
||||||
UntrustedRlp {
|
UntrustedRlp {
|
||||||
bytes: self.bytes,
|
bytes: self.bytes,
|
||||||
cache: Cell::new(OffsetCache::new(usize::max_value(), 0))
|
offset_cache: self.offset_cache.clone(),
|
||||||
|
count_cache: self.count_cache.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -72,10 +74,11 @@ impl<'a, 'view> View<'a, 'view> for UntrustedRlp<'a> where 'a: 'view {
|
|||||||
fn new(bytes: &'a [u8]) -> UntrustedRlp<'a> {
|
fn new(bytes: &'a [u8]) -> UntrustedRlp<'a> {
|
||||||
UntrustedRlp {
|
UntrustedRlp {
|
||||||
bytes: bytes,
|
bytes: bytes,
|
||||||
cache: Cell::new(OffsetCache::new(usize::max_value(), 0)),
|
offset_cache: Cell::new(OffsetCache::new(usize::max_value(), 0)),
|
||||||
|
count_cache: Cell::new(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn raw(&'view self) -> &'a [u8] {
|
fn raw(&'view self) -> &'a [u8] {
|
||||||
self.bytes
|
self.bytes
|
||||||
}
|
}
|
||||||
@ -102,7 +105,14 @@ impl<'a, 'view> View<'a, 'view> for UntrustedRlp<'a> where 'a: 'view {
|
|||||||
|
|
||||||
fn item_count(&self) -> usize {
|
fn item_count(&self) -> usize {
|
||||||
match self.is_list() {
|
match self.is_list() {
|
||||||
true => self.iter().count(),
|
true => match self.count_cache.get() {
|
||||||
|
Some(c) => c,
|
||||||
|
None => {
|
||||||
|
let c = self.iter().count();
|
||||||
|
self.count_cache.set(Some(c));
|
||||||
|
c
|
||||||
|
}
|
||||||
|
},
|
||||||
false => 0
|
false => 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,7 +132,7 @@ impl<'a, 'view> View<'a, 'view> for UntrustedRlp<'a> where 'a: 'view {
|
|||||||
|
|
||||||
// move to cached position if it's index is less or equal to
|
// move to cached position if it's index is less or equal to
|
||||||
// current search index, otherwise move to beginning of list
|
// current search index, otherwise move to beginning of list
|
||||||
let c = self.cache.get();
|
let c = self.offset_cache.get();
|
||||||
let (mut bytes, to_skip) = match c.index <= index {
|
let (mut bytes, to_skip) = match c.index <= index {
|
||||||
true => (try!(UntrustedRlp::consume(self.bytes, c.offset)), index - c.index),
|
true => (try!(UntrustedRlp::consume(self.bytes, c.offset)), index - c.index),
|
||||||
false => (try!(self.consume_list_prefix()), index),
|
false => (try!(self.consume_list_prefix()), index),
|
||||||
@ -132,7 +142,7 @@ impl<'a, 'view> View<'a, 'view> for UntrustedRlp<'a> where 'a: 'view {
|
|||||||
bytes = try!(UntrustedRlp::consume_items(bytes, to_skip));
|
bytes = try!(UntrustedRlp::consume_items(bytes, to_skip));
|
||||||
|
|
||||||
// update the cache
|
// update the cache
|
||||||
self.cache.set(OffsetCache::new(index, self.bytes.len() - bytes.len()));
|
self.offset_cache.set(OffsetCache::new(index, self.bytes.len() - bytes.len()));
|
||||||
|
|
||||||
// construct new rlp
|
// construct new rlp
|
||||||
let found = try!(BasicDecoder::payload_info(bytes));
|
let found = try!(BasicDecoder::payload_info(bytes));
|
||||||
@ -360,7 +370,7 @@ macro_rules! impl_array_decodable {
|
|||||||
if decoders.len() != $len {
|
if decoders.len() != $len {
|
||||||
return Err(DecoderError::RlpIncorrectListLen);
|
return Err(DecoderError::RlpIncorrectListLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 0..decoders.len() {
|
for i in 0..decoders.len() {
|
||||||
result[i] = try!(T::decode(&decoders[i]));
|
result[i] = try!(T::decode(&decoders[i]));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user