smartbuf
A high-performance buffered reader with background thread pre-fetching and full seek support.
SmartBuf wraps any Read + Seek implementation and provides:
- Off-thread pre-fetch buffering for improved read performance
- Full seek support with optimization for seeks within buffered data
- Configurable buffer sizes and queue lengths for fine-tuning performance
Features
- Background thread pre-fetching: Data is read ahead of time in a background thread, reducing blocking on I/O operations
- Intelligent seek optimization: Seeks within the current buffer are handled instantly without touching the underlying reader
- Configurable performance: Adjust buffer size and queue length based on your use case
- Standard trait implementation: Implements
std::io::Readandstd::io::Seekfor drop-in compatibility
Installation
Add this to your Cargo.toml:
[]
= "0.1.0"
Quick Example
use SmartBuf;
use ;
let data = b"Hello, world! This is a test.";
let cursor = new;
let mut reader = new;
// Read some data
let mut buf = vec!;
reader.read.unwrap;
assert_eq!;
// Seek back to the beginning
reader.seek.unwrap;
// Read again
let mut buf = vec!;
reader.read.unwrap;
assert_eq!;
// Seek forward
reader.seek.unwrap;
let mut buf = vec!;
reader.read.unwrap;
assert_eq!;
Usage
Basic Usage
use SmartBuf;
use ;
use File;
let file = open?;
let mut reader = new;
// Read data
let mut buffer = vec!;
let bytes_read = reader.read?;
// Seek to a specific position
reader.seek?;
// Continue reading from the new position
reader.read?;
Custom Buffer Configuration
For fine-tuned performance, you can specify the buffer size and queue length:
use SmartBuf;
use Cursor;
let data = vec!; // 1MB of data
let cursor = new;
// Create with custom buffer size (16KB) and queue length (4)
let mut reader = with_capacity;
// Larger buffers and more queue slots can improve throughput
// at the cost of increased memory usage
Seeking Operations
SmartBuf supports all standard seek operations:
use SmartBuf;
use ;
let data: = .collect;
let cursor = new;
let mut reader = with_capacity;
// Seek to absolute position
reader.seek.unwrap;
// Seek relative to current position (forward)
reader.seek.unwrap;
// Seek relative to current position (backward)
reader.seek.unwrap;
// Seek from end of file
reader.seek.unwrap;
Reading Entire Files
use SmartBuf;
use Read;
let cursor = new;
let mut reader = new;
let mut contents = Vecnew;
reader.read_to_end.unwrap;
API Documentation
SmartBuf::new(reader: R) -> SmartBuf<R>
Creates a new SmartBuf with default settings:
- Buffer size: 8KB
- Queue length: 2
SmartBuf::with_capacity(bufsize: usize, queuelen: usize, reader: R) -> SmartBuf<R>
Creates a new SmartBuf with custom configuration:
bufsize: Size of each buffer chunk in bytesqueuelen: Number of buffers to keep in the pre-fetch queue (must be ≥ 1)
SmartBuf::position(&self) -> u64
Returns the current absolute position in the stream.
SmartBuf::buffer_size(&self) -> usize
Returns the configured buffer size.
Performance Considerations
- Buffer size: Larger buffers reduce the number of system calls but increase memory usage. A good default is 8KB–64KB.
- Queue length: More buffers in the queue allow for better pre-fetching, especially when reading sequentially. Values of 2–4 are usually sufficient.
- Seek optimization: Seeks within the currently buffered data are handled instantly. Seeks outside the buffer require synchronization with the background thread.
Examples
Reading with Seeking
use SmartBuf;
use ;
let data: = .collect;
let cursor = new;
let mut reader = with_capacity;
// Read first 50 bytes
let mut buf = vec!;
reader.read.unwrap;
assert_eq!;
// Seek to middle
reader.seek.unwrap;
let mut buf = vec!;
reader.read.unwrap;
assert_eq!;
// Seek back
reader.seek.unwrap;
let mut buf = vec!;
reader.read.unwrap;
assert_eq!;
Large File Processing
use SmartBuf;
use ;
use File;
let file = open?;
let mut reader = with_capacity;
// Process file in chunks
let mut buffer = vec!; // 1MB chunks
loop
Requirements
- Rust 1.38.0 or later
- Dependencies:
crossbeam-channelandcrossbeam-utilsfor thread-safe communication
License
This project is licensed under the MIT License - see the LICENSE file for details.