@@ -43,7 +43,10 @@ pub struct Witness {
43
43
}
44
44
45
45
/// Support structure to allow efficient and convenient iteration over the Witness elements
46
- pub struct Iter < ' a > ( :: core:: slice:: Iter < ' a , u8 > ) ;
46
+ pub struct Iter < ' a > {
47
+ inner : core:: slice:: Iter < ' a , u8 > ,
48
+ remaining : usize ,
49
+ }
47
50
48
51
impl Decodable for Witness {
49
52
fn consensus_decode < D : Read > ( mut d : D ) -> Result < Self , Error > {
@@ -172,7 +175,7 @@ impl Witness {
172
175
173
176
/// Returns a struct implementing [`Iterator`]
174
177
pub fn iter ( & self ) -> Iter {
175
- Iter ( self . content . iter ( ) )
178
+ Iter { inner : self . content . iter ( ) , remaining : self . witness_elements }
176
179
}
177
180
178
181
/// Returns the number of elements this witness holds
@@ -253,18 +256,25 @@ impl<'a> Iterator for Iter<'a> {
253
256
type Item = & ' a [ u8 ] ;
254
257
255
258
fn next ( & mut self ) -> Option < Self :: Item > {
256
- let varint = VarInt :: consensus_decode ( self . 0 . as_slice ( ) ) . ok ( ) ?;
257
- self . 0 . nth ( varint. len ( ) - 1 ) ?; // VarInt::len returns at least 1
259
+ let varint = VarInt :: consensus_decode ( self . inner . as_slice ( ) ) . ok ( ) ?;
260
+ self . inner . nth ( varint. len ( ) - 1 ) ?; // VarInt::len returns at least 1
258
261
let len = varint. 0 as usize ;
259
- let slice = & self . 0 . as_slice ( ) [ ..len] ;
262
+ let slice = & self . inner . as_slice ( ) [ ..len] ;
260
263
if len > 0 {
261
264
// we don't need to advance if the element is empty
262
- self . 0 . nth ( len - 1 ) ?;
265
+ self . inner . nth ( len - 1 ) ?;
263
266
}
267
+ self . remaining -= 1 ;
264
268
Some ( slice)
265
269
}
270
+
271
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
272
+ ( self . remaining , Some ( self . remaining ) )
273
+ }
266
274
}
267
275
276
+ impl < ' a > ExactSizeIterator for Iter < ' a > { }
277
+
268
278
// Serde keep backward compatibility with old Vec<Vec<u8>> format
269
279
#[ cfg( feature = "serde" ) ]
270
280
impl serde:: Serialize for Witness {
@@ -323,6 +333,21 @@ mod test {
323
333
assert_eq ! ( witness. second_to_last( ) , Some ( & [ 0u8 ] [ ..] ) ) ;
324
334
}
325
335
336
+
337
+ #[ test]
338
+ fn test_iter_len ( ) {
339
+ let mut witness = Witness :: default ( ) ;
340
+ for i in 0 ..5 {
341
+ assert_eq ! ( witness. iter( ) . len( ) , i) ;
342
+ witness. push ( & vec ! [ 0u8 ] ) ;
343
+ }
344
+ let mut iter = witness. iter ( ) ;
345
+ for i in ( 0 ..=5 ) . rev ( ) {
346
+ assert_eq ! ( iter. len( ) , i) ;
347
+ iter. next ( ) ;
348
+ }
349
+ }
350
+
326
351
#[ test]
327
352
fn test_push_ecdsa_sig ( ) {
328
353
// The very first signature in block 734,958
@@ -408,3 +433,31 @@ mod test {
408
433
assert_eq ! ( new_witness_format, back) ;
409
434
}
410
435
}
436
+
437
+
438
+ #[ cfg( all( test, feature = "unstable" ) ) ]
439
+ mod benches {
440
+ use test:: { Bencher , black_box} ;
441
+ use super :: Witness ;
442
+
443
+ #[ bench]
444
+ pub fn bench_big_witness_to_vec ( bh : & mut Bencher ) {
445
+ let raw_witness = vec ! [ vec![ 1u8 ] ; 5 ] ;
446
+ let witness = Witness :: from_vec ( raw_witness) ;
447
+
448
+ bh. iter ( || {
449
+ black_box ( witness. to_vec ( ) ) ;
450
+ } ) ;
451
+ }
452
+
453
+ #[ bench]
454
+ pub fn bench_witness_to_vec ( bh : & mut Bencher ) {
455
+ let raw_witness = vec ! [ vec![ 1u8 ] ; 3 ] ;
456
+ let witness = Witness :: from_vec ( raw_witness) ;
457
+
458
+ bh. iter ( || {
459
+ black_box ( witness. to_vec ( ) ) ;
460
+ } ) ;
461
+ }
462
+
463
+ }
0 commit comments