@@ -5,7 +5,6 @@ use std::fmt::Debug;
5
5
use std:: fs:: { File , OpenOptions } ;
6
6
7
7
use anyhow:: { anyhow, bail, Context , Result } ;
8
- use bytes:: BufMut ;
9
8
use nix:: unistd:: { sysconf, SysconfVar } ;
10
9
11
10
use serde:: { Deserialize , Serialize } ;
@@ -54,24 +53,28 @@ pub(crate) trait ExtentInner: Send + Sync + Debug {
54
53
requests : & [ crucible_protocol:: ReadRequest ] ,
55
54
iov_max : usize ,
56
55
out : & mut BytesMut ,
57
- ) -> Result < ( ) , CrucibleError > {
58
- // Call the existing read implementation, then do serialization by hand
59
- // here. Note that we serialize the individual ReadResponse values, but
60
- // not the leading size, because that's already placed into the buffer.
61
- let data = self . read ( job_id, requests, iov_max) ?;
62
- let mut w = out. writer ( ) ;
63
- for d in data {
64
- bincode:: serialize_into ( & mut w, & d) . unwrap ( ) ;
65
- }
66
- Ok ( ( ) )
67
- }
56
+ ) -> Result < ( ) , CrucibleError > ;
68
57
58
+ /// Read the given requests into a `Vec<ReadResponse>`
59
+ ///
60
+ /// The default implementation defers to `read_raw`, then deserializes the
61
+ /// resulting buffer.
62
+ ///
63
+ /// This function is only built during unit tests, because it's less
64
+ /// efficient than `read_raw`.
65
+ #[ cfg( test) ]
69
66
fn read (
70
67
& mut self ,
71
68
job_id : JobId ,
72
69
requests : & [ crucible_protocol:: ReadRequest ] ,
73
70
iov_max : usize ,
74
- ) -> Result < Vec < crucible_protocol:: ReadResponse > , CrucibleError > ;
71
+ ) -> Result < Vec < crucible_protocol:: ReadResponse > , CrucibleError > {
72
+ use bytes:: BufMut ;
73
+ let mut b = BytesMut :: new ( ) ;
74
+ b. put_u64_le ( requests. len ( ) as u64 ) ;
75
+ self . read_raw ( job_id, requests, iov_max, & mut b) ?;
76
+ Ok ( bincode:: deserialize ( & b) . unwrap ( ) )
77
+ }
75
78
76
79
fn write (
77
80
& mut self ,
0 commit comments