From 6660b3d65feaff95c886ec09ffed5791e8a88e4b Mon Sep 17 00:00:00 2001 From: debris Date: Mon, 30 Nov 2015 16:14:03 +0100 Subject: [PATCH 1/4] replaced usages of append(&"") to append_empty_data() --- src/triehash.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/triehash.rs b/src/triehash.rs index bc8dedf76..e26cc255f 100644 --- a/src/triehash.rs +++ b/src/triehash.rs @@ -138,9 +138,9 @@ fn as_nibbles(bytes: &[u8]) -> Vec { fn hash256rlp(input: &[(Vec, Vec)], pre_len: usize, stream: &mut RlpStream) { let inlen = input.len(); - // in case of empty slice, just append null + // in case of empty slice, just append empty data if inlen == 0 { - stream.append(&""); + stream.append_empty_data(); return; } @@ -196,7 +196,7 @@ fn hash256rlp(input: &[(Vec, Vec)], pre_len: usize, stream: &mut RlpStre // if at least 1 successive element has the same nibble // append their suffixes match len { - 0 => { stream.append(&""); }, + 0 => { stream.append_empty_data(); }, _ => hash256aux(&input[begin..(begin + len)], pre_len + 1, stream) } begin += len; @@ -205,7 +205,7 @@ fn hash256rlp(input: &[(Vec, Vec)], pre_len: usize, stream: &mut RlpStre // if fist key len is equal prefix, append it's value match pre_len == key.len() { true => { stream.append(&value); }, - false => { stream.append(&""); } + false => { stream.append_empty_data(); } }; } From 84b872819ed68e044e25e763365e4d359388b97b Mon Sep 17 00:00:00 2001 From: debris Date: Mon, 30 Nov 2015 17:23:52 +0100 Subject: [PATCH 2/4] rlp lifetimes --- src/rlp.rs | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/src/rlp.rs b/src/rlp.rs index e8562828a..b74651799 100644 --- a/src/rlp.rs +++ b/src/rlp.rs @@ -132,7 +132,7 @@ pub enum Prototype { List(usize), } -impl<'a> Rlp<'a> { +impl<'a, 'view> Rlp<'a> where 'a: 'view { /// Create a new instance of `Rlp` pub fn new(bytes: &'a [u8]) -> Rlp<'a> { Rlp { @@ -162,12 +162,11 @@ impl<'a> Rlp<'a> { /// fn main () { /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']; /// let rlp = Rlp::new(&data); - /// let view = rlp.at(1); - /// let dog = view.data(); + /// let dog = rlp.at(1).data(); /// assert_eq!(dog, &[0x83, b'd', b'o', b'g']); /// } /// ``` - pub fn data(&self) -> &[u8] { + pub fn data(&'view self) -> &'a [u8] { self.rlp.data() } @@ -223,7 +222,7 @@ impl<'a> Rlp<'a> { /// assert_eq!(dog, "dog".to_string()); /// } /// ``` - pub fn at(&self, index: usize) -> Rlp<'a> { + pub fn at(&'view self, index: usize) -> Rlp<'a> { From::from(self.rlp.at(index).unwrap()) } @@ -325,7 +324,7 @@ impl<'a> Rlp<'a> { } } -impl<'a> UntrustedRlp<'a> { +impl<'a, 'view> UntrustedRlp<'a> where 'a: 'view { /// returns new instance of `UntrustedRlp` pub fn new(bytes: &'a [u8]) -> UntrustedRlp<'a> { UntrustedRlp { @@ -343,12 +342,11 @@ impl<'a> UntrustedRlp<'a> { /// fn main () { /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']; /// let rlp = UntrustedRlp::new(&data); - /// let view = rlp.at(1).unwrap(); - /// let dog = view.data(); + /// let dog = rlp.at(1).unwrap().data(); /// assert_eq!(dog, &[0x83, b'd', b'o', b'g']); /// } /// ``` - pub fn data(&self) -> &[u8] { + pub fn data(&'view self) -> &'a [u8] { self.bytes } @@ -410,7 +408,7 @@ impl<'a> UntrustedRlp<'a> { /// assert_eq!(dog, "dog".to_string()); /// } /// ``` - pub fn at(&self, index: usize) -> Result, DecoderError> { + pub fn at(&'view self, index: usize) -> Result, DecoderError> { if !self.is_list() { return Err(DecoderError::RlpExpectedToBeList); } @@ -1452,4 +1450,31 @@ mod tests { vec![0xc5, 0xc4, 0x83, b'c', b'a', b't'])]; run_decode_tests(tests); } + + #[test] + fn test_view() { + struct View<'a> { + bytes: &'a [u8] + } + + impl <'a, 'view> View<'a> where 'a: 'view { + fn new(bytes: &'a [u8]) -> View<'a> { + View { + bytes: bytes + } + } + + fn offset(&'view self, len: usize) -> View<'a> { + View::new(&self.bytes[len..]) + } + + fn data(&'view self) -> &'a [u8] { + self.bytes + } + } + + let data = vec![0, 1, 2, 3]; + let view = View::new(&data); + let _data_slice = view.offset(1).data(); + } } From 9736b39363920d941b2a0728a0482cbe4550d2cb Mon Sep 17 00:00:00 2001 From: debris Date: Mon, 30 Nov 2015 17:44:55 +0100 Subject: [PATCH 3/4] fixed benchmarks --- benches/rlp.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/benches/rlp.rs b/benches/rlp.rs index 50712bc57..1160e311f 100644 --- a/benches/rlp.rs +++ b/benches/rlp.rs @@ -20,7 +20,7 @@ fn bench_stream_u64_value(b: &mut Bencher) { // u64 let mut stream = RlpStream::new(); stream.append(&0x1023456789abcdefu64); - let _ = stream.out().unwrap(); + let _ = stream.out(); }); } @@ -42,7 +42,7 @@ fn bench_stream_u256_value(b: &mut Bencher) { stream.append(&U256::from_str("8090a0b0c0d0e0f009102030405060770000000000000001000000000\ 00012f0") .unwrap()); - let _ = stream.out().unwrap(); + let _ = stream.out(); }); } @@ -66,7 +66,7 @@ fn bench_stream_nested_empty_lists(b: &mut Bencher) { stream.append_list(0); stream.append_list(1).append_list(0); stream.append_list(2).append_list(0).append_list(1).append_list(0); - let _ = stream.out().unwrap(); + let _ = stream.out(); }); } @@ -76,11 +76,11 @@ fn bench_decode_nested_empty_lists(b: &mut Bencher) { // [ [], [[]], [ [], [[]] ] ] let data = vec![0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0]; let rlp = Rlp::new(&data); - let _v0: Vec = Decodable::decode(&rlp.at(0)); - let _v1: Vec> = Decodable::decode(&rlp.at(1)); + let _v0: Vec = Decodable::decode(&rlp.at(0)); + let _v1: Vec> = Decodable::decode(&rlp.at(1)); let nested_rlp = rlp.at(2); - let _v2a: Vec = Decodable::decode(&nested_rlp.at(0)); - let _v2b: Vec> = Decodable::decode(&nested_rlp.at(1)); + let _v2a: Vec = Decodable::decode(&nested_rlp.at(0)); + let _v2b: Vec> = Decodable::decode(&nested_rlp.at(1)); }); } @@ -91,6 +91,6 @@ fn bench_stream_1000_empty_lists(b: &mut Bencher) { for _ in 0..1000 { stream.append_list(0); } - let _ = stream.out().unwrap(); + let _ = stream.out(); }); } From 90196107284717ca99753660a4e7e20fff1e10fb Mon Sep 17 00:00:00 2001 From: debris Date: Mon, 30 Nov 2015 19:14:46 +0100 Subject: [PATCH 4/4] NibbleSlice mid do not share lifetime with a parent view, but with a collection --- src/nibbleslice.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/nibbleslice.rs b/src/nibbleslice.rs index 6ccf695c0..e7e62e193 100644 --- a/src/nibbleslice.rs +++ b/src/nibbleslice.rs @@ -31,7 +31,7 @@ pub struct NibbleSlice<'a> { offset: usize, } -impl<'a> NibbleSlice<'a> { +impl<'a, 'view> NibbleSlice<'a> where 'a: 'view { /// Create a new nibble slice with the given byte-slice. pub fn new(data: &[u8]) -> NibbleSlice { NibbleSlice::new_offset(data, 0) } @@ -60,7 +60,7 @@ impl<'a> NibbleSlice<'a> { } /// Return object which represents a view on to this slice (further) offset by `i` nibbles. - pub fn mid(&self, i: usize) -> Self { NibbleSlice{ data: self.data, offset: self.offset + i} } + pub fn mid(&'view self, i: usize) -> NibbleSlice<'a> { NibbleSlice{ data: self.data, offset: self.offset + i} } /// Do we start with the same nibbles as the whole of `them`? pub fn starts_with(&self, them: &Self) -> bool { self.common_prefix(them) == them.len() } @@ -192,4 +192,4 @@ mod tests { assert!(n >= m.mid(4)); assert!(n <= m.mid(4)); } -} \ No newline at end of file +}