IOStatWrapper

Struct IOStatWrapper 

Source
pub struct IOStatWrapper<T, C> { /* private fields */ }
Expand description

A wrapper around an IO object that tracks operations and statistics.

Implementations§

Source§

impl<T, C> IOStatWrapper<T, C>

Source

pub fn new(obj: T, start_seek_pos: u64) -> IOStatWrapper<T, C>

Create a new IOStatWrapper with a manually given seek position. Detecting the seek position automatically is not possible without specialization.

Examples found in repository?
examples/bufread_reduced_read_count.rs (line 8)
6fn main() {
7    let file_obj = File::open("Cargo.toml").unwrap();
8    let mut instrumented_raw_file = IOStatWrapper::<_, Vec<IopInfoPair>>::new(file_obj, 0);
9    let buffered_io = BufReader::new(&mut instrumented_raw_file);
10    let mut instrumented_buf_file = IOStatWrapper::<_, Vec<IopInfoPair>>::new(buffered_io, 0);
11
12    // Do something so that the loop doesn't get optimized out
13    let mut xor_result: u8 = 0x00;
14    for byte in (&mut instrumented_buf_file).bytes() {
15        xor_result ^= byte.unwrap();
16    }
17    println!("XOR of all bytes in Cargo.toml is {:#x}", xor_result);
18
19    // Demonstrate how BufReader reduces the number of read calls
20    println!("Buffered read was called successfully {} times",
21        instrumented_buf_file.read_call_counter().success_ctr());
22    println!("Inner read was called successfully {} times",
23        instrumented_raw_file.read_call_counter().success_ctr());
24}
More examples
Hide additional examples
examples/bufread_assert_stream_position.rs (line 8)
6fn main() {
7    let file_obj = File::open("Cargo.toml").unwrap();
8    let mut instrumented_raw_file = IOStatWrapper::<_, Vec<IopInfoPair>>::new(file_obj, 0);
9    let buffered_io = BufReader::new(&mut instrumented_raw_file);
10    let mut instrumented_buf_file = IOStatWrapper::<_, Vec<IopInfoPair>>::new(buffered_io, 0);
11
12    // Do something so that the loop doesn't get optimized out
13    let mut xor_result: u8 = 0x00;
14    let mut read_buf: [u8; 1] = [0x00; 1];
15    loop {
16        let bytes_read = instrumented_buf_file.read(&mut read_buf).unwrap();
17        if bytes_read == 0 {
18            break;
19        }
20        xor_result ^= read_buf[0];
21        assert_eq!(instrumented_buf_file.seek_pos(),
22            instrumented_buf_file.stream_position().unwrap());
23    }
24    println!("XOR of all bytes in Cargo.toml is {:#x}", xor_result);
25
26    // Demonstrate how BufReader reduces the number of read calls
27    println!("Buffered read was called successfully {} times",
28        instrumented_buf_file.read_call_counter().success_ctr());
29    println!("Buffered seek was called successfully {} times",
30        instrumented_buf_file.seek_call_counter().success_ctr());
31    println!("Inner read was called successfully {} times",
32        instrumented_raw_file.read_call_counter().success_ctr());
33    println!("Inner seek was called successfully {} times",
34        instrumented_raw_file.seek_call_counter().success_ctr());
35}
examples/bufread_assert_seek_zero.rs (line 8)
6fn main() {
7    let file_obj = File::open("Cargo.toml").unwrap();
8    let mut instrumented_raw_file = IOStatWrapper::<_, Vec<IopInfoPair>>::new(file_obj, 0);
9    let buffered_io = BufReader::new(&mut instrumented_raw_file);
10    let mut instrumented_buf_file = IOStatWrapper::<_, Vec<IopInfoPair>>::new(buffered_io, 0);
11
12    // Do something so that the loop doesn't get optimized out
13    let mut xor_result: u8 = 0x00;
14    let mut read_buf: [u8; 1] = [0x00; 1];
15    loop {
16        let bytes_read = instrumented_buf_file.read(&mut read_buf).unwrap();
17        if bytes_read == 0 {
18            break;
19        }
20        xor_result ^= read_buf[0];
21        assert_eq!(instrumented_buf_file.seek_pos(),
22            instrumented_buf_file.seek(SeekFrom::Current(0)).unwrap());
23    }
24    println!("XOR of all bytes in Cargo.toml is {:#x}", xor_result);
25
26    // Demonstrate how BufReader reduces the number of read calls
27    println!("Buffered read was called successfully {} times",
28        instrumented_buf_file.read_call_counter().success_ctr());
29    println!("Buffered seek was called successfully {} times",
30        instrumented_buf_file.seek_call_counter().success_ctr());
31    println!("Inner read was called successfully {} times",
32        instrumented_raw_file.read_call_counter().success_ctr());
33    println!("Inner seek was called successfully {} times",
34        instrumented_raw_file.seek_call_counter().success_ctr());
35}
Source

pub fn into_inner(self) -> T

Extract the original I/O object.

Source

pub fn iop_log(&self) -> &C

Get the I/O operation log containing operations and their results.

Source§

impl<T: Read, C> IOStatWrapper<T, C>

Source

pub fn read_call_counter(&self) -> &SuccessFailureCounter<u64>

Returns the number of times Read::read() was invoked.

Examples found in repository?
examples/bufread_reduced_read_count.rs (line 21)
6fn main() {
7    let file_obj = File::open("Cargo.toml").unwrap();
8    let mut instrumented_raw_file = IOStatWrapper::<_, Vec<IopInfoPair>>::new(file_obj, 0);
9    let buffered_io = BufReader::new(&mut instrumented_raw_file);
10    let mut instrumented_buf_file = IOStatWrapper::<_, Vec<IopInfoPair>>::new(buffered_io, 0);
11
12    // Do something so that the loop doesn't get optimized out
13    let mut xor_result: u8 = 0x00;
14    for byte in (&mut instrumented_buf_file).bytes() {
15        xor_result ^= byte.unwrap();
16    }
17    println!("XOR of all bytes in Cargo.toml is {:#x}", xor_result);
18
19    // Demonstrate how BufReader reduces the number of read calls
20    println!("Buffered read was called successfully {} times",
21        instrumented_buf_file.read_call_counter().success_ctr());
22    println!("Inner read was called successfully {} times",
23        instrumented_raw_file.read_call_counter().success_ctr());
24}
More examples
Hide additional examples
examples/bufread_assert_stream_position.rs (line 28)
6fn main() {
7    let file_obj = File::open("Cargo.toml").unwrap();
8    let mut instrumented_raw_file = IOStatWrapper::<_, Vec<IopInfoPair>>::new(file_obj, 0);
9    let buffered_io = BufReader::new(&mut instrumented_raw_file);
10    let mut instrumented_buf_file = IOStatWrapper::<_, Vec<IopInfoPair>>::new(buffered_io, 0);
11
12    // Do something so that the loop doesn't get optimized out
13    let mut xor_result: u8 = 0x00;
14    let mut read_buf: [u8; 1] = [0x00; 1];
15    loop {
16        let bytes_read = instrumented_buf_file.read(&mut read_buf).unwrap();
17        if bytes_read == 0 {
18            break;
19        }
20        xor_result ^= read_buf[0];
21        assert_eq!(instrumented_buf_file.seek_pos(),
22            instrumented_buf_file.stream_position().unwrap());
23    }
24    println!("XOR of all bytes in Cargo.toml is {:#x}", xor_result);
25
26    // Demonstrate how BufReader reduces the number of read calls
27    println!("Buffered read was called successfully {} times",
28        instrumented_buf_file.read_call_counter().success_ctr());
29    println!("Buffered seek was called successfully {} times",
30        instrumented_buf_file.seek_call_counter().success_ctr());
31    println!("Inner read was called successfully {} times",
32        instrumented_raw_file.read_call_counter().success_ctr());
33    println!("Inner seek was called successfully {} times",
34        instrumented_raw_file.seek_call_counter().success_ctr());
35}
examples/bufread_assert_seek_zero.rs (line 28)
6fn main() {
7    let file_obj = File::open("Cargo.toml").unwrap();
8    let mut instrumented_raw_file = IOStatWrapper::<_, Vec<IopInfoPair>>::new(file_obj, 0);
9    let buffered_io = BufReader::new(&mut instrumented_raw_file);
10    let mut instrumented_buf_file = IOStatWrapper::<_, Vec<IopInfoPair>>::new(buffered_io, 0);
11
12    // Do something so that the loop doesn't get optimized out
13    let mut xor_result: u8 = 0x00;
14    let mut read_buf: [u8; 1] = [0x00; 1];
15    loop {
16        let bytes_read = instrumented_buf_file.read(&mut read_buf).unwrap();
17        if bytes_read == 0 {
18            break;
19        }
20        xor_result ^= read_buf[0];
21        assert_eq!(instrumented_buf_file.seek_pos(),
22            instrumented_buf_file.seek(SeekFrom::Current(0)).unwrap());
23    }
24    println!("XOR of all bytes in Cargo.toml is {:#x}", xor_result);
25
26    // Demonstrate how BufReader reduces the number of read calls
27    println!("Buffered read was called successfully {} times",
28        instrumented_buf_file.read_call_counter().success_ctr());
29    println!("Buffered seek was called successfully {} times",
30        instrumented_buf_file.seek_call_counter().success_ctr());
31    println!("Inner read was called successfully {} times",
32        instrumented_raw_file.read_call_counter().success_ctr());
33    println!("Inner seek was called successfully {} times",
34        instrumented_raw_file.seek_call_counter().success_ctr());
35}
Source

pub fn read_byte_counter(&self) -> usize

Returns the total number of bytes read.

Source§

impl<T: Seek, C> IOStatWrapper<T, C>

Source

pub fn seek_call_counter(&self) -> &SuccessFailureCounter<u64>

Returns the number of times Seek::seek() was invoked.

Examples found in repository?
examples/bufread_assert_stream_position.rs (line 30)
6fn main() {
7    let file_obj = File::open("Cargo.toml").unwrap();
8    let mut instrumented_raw_file = IOStatWrapper::<_, Vec<IopInfoPair>>::new(file_obj, 0);
9    let buffered_io = BufReader::new(&mut instrumented_raw_file);
10    let mut instrumented_buf_file = IOStatWrapper::<_, Vec<IopInfoPair>>::new(buffered_io, 0);
11
12    // Do something so that the loop doesn't get optimized out
13    let mut xor_result: u8 = 0x00;
14    let mut read_buf: [u8; 1] = [0x00; 1];
15    loop {
16        let bytes_read = instrumented_buf_file.read(&mut read_buf).unwrap();
17        if bytes_read == 0 {
18            break;
19        }
20        xor_result ^= read_buf[0];
21        assert_eq!(instrumented_buf_file.seek_pos(),
22            instrumented_buf_file.stream_position().unwrap());
23    }
24    println!("XOR of all bytes in Cargo.toml is {:#x}", xor_result);
25
26    // Demonstrate how BufReader reduces the number of read calls
27    println!("Buffered read was called successfully {} times",
28        instrumented_buf_file.read_call_counter().success_ctr());
29    println!("Buffered seek was called successfully {} times",
30        instrumented_buf_file.seek_call_counter().success_ctr());
31    println!("Inner read was called successfully {} times",
32        instrumented_raw_file.read_call_counter().success_ctr());
33    println!("Inner seek was called successfully {} times",
34        instrumented_raw_file.seek_call_counter().success_ctr());
35}
More examples
Hide additional examples
examples/bufread_assert_seek_zero.rs (line 30)
6fn main() {
7    let file_obj = File::open("Cargo.toml").unwrap();
8    let mut instrumented_raw_file = IOStatWrapper::<_, Vec<IopInfoPair>>::new(file_obj, 0);
9    let buffered_io = BufReader::new(&mut instrumented_raw_file);
10    let mut instrumented_buf_file = IOStatWrapper::<_, Vec<IopInfoPair>>::new(buffered_io, 0);
11
12    // Do something so that the loop doesn't get optimized out
13    let mut xor_result: u8 = 0x00;
14    let mut read_buf: [u8; 1] = [0x00; 1];
15    loop {
16        let bytes_read = instrumented_buf_file.read(&mut read_buf).unwrap();
17        if bytes_read == 0 {
18            break;
19        }
20        xor_result ^= read_buf[0];
21        assert_eq!(instrumented_buf_file.seek_pos(),
22            instrumented_buf_file.seek(SeekFrom::Current(0)).unwrap());
23    }
24    println!("XOR of all bytes in Cargo.toml is {:#x}", xor_result);
25
26    // Demonstrate how BufReader reduces the number of read calls
27    println!("Buffered read was called successfully {} times",
28        instrumented_buf_file.read_call_counter().success_ctr());
29    println!("Buffered seek was called successfully {} times",
30        instrumented_buf_file.seek_call_counter().success_ctr());
31    println!("Inner read was called successfully {} times",
32        instrumented_raw_file.read_call_counter().success_ctr());
33    println!("Inner seek was called successfully {} times",
34        instrumented_raw_file.seek_call_counter().success_ctr());
35}
Source

pub fn seek_pos(&self) -> u64

Get the current seek position without doing an actual seek operation.

This is accomplished by storing a separate position integer. When debug assertions are on we assert after every seek operation that the cursor is where we expect it to be.

Examples found in repository?
examples/bufread_assert_stream_position.rs (line 21)
6fn main() {
7    let file_obj = File::open("Cargo.toml").unwrap();
8    let mut instrumented_raw_file = IOStatWrapper::<_, Vec<IopInfoPair>>::new(file_obj, 0);
9    let buffered_io = BufReader::new(&mut instrumented_raw_file);
10    let mut instrumented_buf_file = IOStatWrapper::<_, Vec<IopInfoPair>>::new(buffered_io, 0);
11
12    // Do something so that the loop doesn't get optimized out
13    let mut xor_result: u8 = 0x00;
14    let mut read_buf: [u8; 1] = [0x00; 1];
15    loop {
16        let bytes_read = instrumented_buf_file.read(&mut read_buf).unwrap();
17        if bytes_read == 0 {
18            break;
19        }
20        xor_result ^= read_buf[0];
21        assert_eq!(instrumented_buf_file.seek_pos(),
22            instrumented_buf_file.stream_position().unwrap());
23    }
24    println!("XOR of all bytes in Cargo.toml is {:#x}", xor_result);
25
26    // Demonstrate how BufReader reduces the number of read calls
27    println!("Buffered read was called successfully {} times",
28        instrumented_buf_file.read_call_counter().success_ctr());
29    println!("Buffered seek was called successfully {} times",
30        instrumented_buf_file.seek_call_counter().success_ctr());
31    println!("Inner read was called successfully {} times",
32        instrumented_raw_file.read_call_counter().success_ctr());
33    println!("Inner seek was called successfully {} times",
34        instrumented_raw_file.seek_call_counter().success_ctr());
35}
More examples
Hide additional examples
examples/bufread_assert_seek_zero.rs (line 21)
6fn main() {
7    let file_obj = File::open("Cargo.toml").unwrap();
8    let mut instrumented_raw_file = IOStatWrapper::<_, Vec<IopInfoPair>>::new(file_obj, 0);
9    let buffered_io = BufReader::new(&mut instrumented_raw_file);
10    let mut instrumented_buf_file = IOStatWrapper::<_, Vec<IopInfoPair>>::new(buffered_io, 0);
11
12    // Do something so that the loop doesn't get optimized out
13    let mut xor_result: u8 = 0x00;
14    let mut read_buf: [u8; 1] = [0x00; 1];
15    loop {
16        let bytes_read = instrumented_buf_file.read(&mut read_buf).unwrap();
17        if bytes_read == 0 {
18            break;
19        }
20        xor_result ^= read_buf[0];
21        assert_eq!(instrumented_buf_file.seek_pos(),
22            instrumented_buf_file.seek(SeekFrom::Current(0)).unwrap());
23    }
24    println!("XOR of all bytes in Cargo.toml is {:#x}", xor_result);
25
26    // Demonstrate how BufReader reduces the number of read calls
27    println!("Buffered read was called successfully {} times",
28        instrumented_buf_file.read_call_counter().success_ctr());
29    println!("Buffered seek was called successfully {} times",
30        instrumented_buf_file.seek_call_counter().success_ctr());
31    println!("Inner read was called successfully {} times",
32        instrumented_raw_file.read_call_counter().success_ctr());
33    println!("Inner seek was called successfully {} times",
34        instrumented_raw_file.seek_call_counter().success_ctr());
35}
Source§

impl<T: Write, C> IOStatWrapper<T, C>

Source

pub fn write_call_counter(&self) -> &SuccessFailureCounter<u64>

Returns the number of times Write::write() was invoked.

Source

pub fn write_flush_counter(&self) -> &SuccessFailureCounter<u64>

Returns the number of times Write::flush() was invoked.

Source

pub fn write_byte_counter(&self) -> usize

Trait Implementations§

Source§

impl<T: Debug, C: Debug> Debug for IOStatWrapper<T, C>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Read, C: Extend<IopInfoPair>> Read for IOStatWrapper<T, C>

We wrap most methods of Read, including provided ones, and pass calls through to the inner I/O object. The I/O operation log and statistics are only explicitly updated in the Read::read() function, as it is expected that the other methods are implemented with it. Notably, we do not passthrough Read::bytes(), Read::chain(), and Read::take() as the structs they return have private implementation details that we need to see to have correct type generics. However, for this reason, we do not expect other Read implementations to have their own implementations either, so this shouldn’t be an issue.

Source§

fn read(&mut self, buf: &mut [u8]) -> IOResult<usize>

Passthrough for the inner_io read call that increments a call counter and appends a IopResults::Read object to the log.

Source§

fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> IOResult<usize>

Like read, except that it reads into a slice of buffers. Read more
Source§

fn read_to_end(&mut self, buf: &mut Vec<u8>) -> IOResult<usize>

Reads all bytes until EOF in this source, placing them into buf. Read more
Source§

fn read_to_string(&mut self, buf: &mut String) -> IOResult<usize>

Reads all bytes until EOF in this source, appending them to buf. Read more
Source§

fn read_exact(&mut self, buf: &mut [u8]) -> IOResult<()>

Reads the exact number of bytes required to fill buf. Read more
Source§

fn by_ref(&mut self) -> &mut Self
where Self: Sized,

Creates a “by reference” adaptor for this instance of Read. Read more
Source§

fn is_read_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector)
Determines if this Reader has an efficient read_vectored implementation. Read more
Source§

fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<(), Error>

🔬This is a nightly-only experimental API. (read_buf)
Pull some bytes from this source into the specified buffer. Read more
Source§

fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<(), Error>

🔬This is a nightly-only experimental API. (read_buf)
Reads the exact number of bytes required to fill cursor. Read more
1.0.0 · Source§

fn bytes(self) -> Bytes<Self>
where Self: Sized,

Transforms this Read instance to an Iterator over its bytes. Read more
1.0.0 · Source§

fn chain<R>(self, next: R) -> Chain<Self, R>
where R: Read, Self: Sized,

Creates an adapter which will chain this stream with another. Read more
1.0.0 · Source§

fn take(self, limit: u64) -> Take<Self>
where Self: Sized,

Creates an adapter which will read at most limit bytes from it. Read more
Source§

impl<T: Seek, C: Extend<IopInfoPair>> Seek for IOStatWrapper<T, C>

We wrap all methods of Seek, including provided ones, and pass calls through to the inner I/O object. The I/O operation log and statistics are only explicitly updated in the Seek::seek() function, as it is expected that the other methods are implemented with it.

Source§

fn seek(&mut self, pos: SeekFrom) -> IOResult<u64>

Passthrough for the inner_io seek call that increments a call counter and appends a IopResults::Seek object to the log.

Source§

fn rewind(&mut self) -> IOResult<()>

Rewind to the beginning of a stream. Read more
Source§

fn stream_position(&mut self) -> IOResult<u64>

Returns the current seek position from the start of the stream. Read more
Source§

fn stream_len(&mut self) -> Result<u64, Error>

🔬This is a nightly-only experimental API. (seek_stream_len)
Returns the length of this stream (in bytes). Read more
1.80.0 · Source§

fn seek_relative(&mut self, offset: i64) -> Result<(), Error>

Seeks relative to the current position. Read more
Source§

impl<T: Write, C: Extend<IopInfoPair>> Write for IOStatWrapper<T, C>

We wrap all methods of Write, including provided ones, and pass calls through to the inner I/O object. The I/O operation log and statistics are explicitly updated in the Write::write() and Write::flush() functions, as it is expected that the other methods are implemented with them.

Source§

fn write(&mut self, buf: &[u8]) -> IOResult<usize>

Passthrough for the inner_io write call that increments a call counter and appends a IopResults::Write object to the log.

Source§

fn flush(&mut self) -> IOResult<()>

Passthrough for the inner_io write call that increments a call counter and appends a IopResults::Flush object to the log.

Source§

fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> IOResult<usize>

Like write, except that it writes from a slice of buffers. Read more
Source§

fn write_all(&mut self, buf: &[u8]) -> IOResult<()>

Attempts to write an entire buffer into this writer. Read more
Source§

fn write_fmt(&mut self, fmt: Arguments<'_>) -> IOResult<()>

Writes a formatted string into this writer, returning any error encountered. Read more
Source§

fn by_ref(&mut self) -> &mut Self
where Self: Sized,

Creates a “by reference” adapter for this instance of Write. Read more
Source§

fn is_write_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector)
Determines if this Writer has an efficient write_vectored implementation. Read more
Source§

fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>

🔬This is a nightly-only experimental API. (write_all_vectored)
Attempts to write multiple buffers into this writer. Read more

Auto Trait Implementations§

§

impl<T, C> Freeze for IOStatWrapper<T, C>
where T: Freeze, C: Freeze,

§

impl<T, C> RefUnwindSafe for IOStatWrapper<T, C>

§

impl<T, C> Send for IOStatWrapper<T, C>
where T: Send, C: Send,

§

impl<T, C> Sync for IOStatWrapper<T, C>
where T: Sync, C: Sync,

§

impl<T, C> Unpin for IOStatWrapper<T, C>
where T: Unpin, C: Unpin,

§

impl<T, C> UnwindSafe for IOStatWrapper<T, C>
where T: UnwindSafe, C: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.