Expand description
Double Mapped Circular Buffer
- Thread-safe.
- Supports multiple readers.
- Generic over the item type.
- Provides access to all items (not n-1).
- Supports Linux, macOS, Windows, and Android.
- Sync, async, and non-blocking implementations.
- Generic variant that allows specifying custom Notifiers to ease integration.
- Underlying data structure (i.e., DoubleMappedBuffer) is exported to allow custom implementations.
§Quick Start
let mut w = sync::Circular::new::<u32>().unwrap();
let mut r = w.add_reader();
// delay producing by 1 sec
let now = std::time::Instant::now();
let delay = std::time::Duration::from_millis(1000);
// producer thread
std::thread::spawn(move || {
std::thread::sleep(delay);
let w_buff = w.slice();
for v in w_buff.iter_mut() {
*v = 23;
}
let l = w_buff.len();
w.produce(l);
});
// blocks until data becomes available
let r_buff = r.slice().unwrap();
assert!(now.elapsed() > delay);
for v in r_buff {
assert_eq!(*v, 23);
}
let l = r_buff.len();
r.consume(l);§Commonalities
There are some commonalities between the implementations:
- The
Circularstruct is a factory to create theWriter. - If there are no
Readers, theWriterwill not block but continuously overwrite the buffer. - The
Writerhas anadd_reader()method to addReaders. - When the
Writeris dropped, theReadercan read the remaining items. Afterwards, theslice()will returnNone.
§Details
This circular buffer implementation maps the underlying buffer twice, back-to-back into the virtual address space of the process. This arrangement allows the circular buffer to present the available data sequentially, (i.e., as a slice) without having to worry about wrapping.
On Unix-based systems, the mapping is setup with a temporary file. This file is created in the folder, determined through std::env::temp_dir, which considers environment variables. This can be used, if the standard paths are not present of not writable on the platform.
§Features
The async, nonblocking, and sync feature flags, allow to disable the
corresponding implementations. By default, all are enabled. In addition, the
generic flag allows to disable the generic implementation, leaving only
the DoubleMappedBuffer.
Modules§
- asynchronous
- Async Circular Buffer that can
awaituntil buffer space becomes available. - double_
mapped_ buffer - Underlying data structure that maps a buffer twice into virtual memory.
- generic
- Circular Buffer with generic Notifier to implement custom wait/block behavior.
- nonblocking
- Non-blocking Circular Buffer that can only check if data is available right now.
- sync
- Blocking Circular Buffer that blocks until data becomes available.