Skip to content

A high-performance, lock-free ring buffer for single-producer, single-consumer scenarios.

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

ain1084/direct_ring_buffer

Repository files navigation

Direct Ring Buffer

Crates.io Documentation Build Status Crates.io License

This crate provides a high-performance, lock-free ring buffer for single-producer, single-consumer scenarios. The main components of this crate are the Producer and Consumer structures, which allow for efficient elements writing and reading, respectively.

Overview

A ring buffer is a fixed-size buffer that works as a circular queue. This implementation uses a lock-free approach, making it suitable for real-time applications where minimal latency is crucial. The buffer supports generic types with the Copy trait. The Copy trait is mainly used to prevent the use of types implementing Drop, as the buffer is allocated uninitialized.

Features

  • Single-Producer, Single-Consumer: Designed for scenarios with a single writer and a single reader.
  • Lock-Free: Utilizes atomic operations for synchronization, avoiding the need for mutexes or other locking mechanisms.
  • Slice-Based I/O: Supports reading and writing multiple elements at a time using slices, enhancing performance for bulk operations.
  • Closure-Based Access: Provides direct access to the buffer through closures, allowing for flexible and efficient elements processing.
  • Single Element Read/Write: Supports not only bulk operations but also single element read and write operations.

Example

use direct_ring_buffer::{create_ring_buffer, Producer, Consumer};

let (mut producer, mut consumer) = create_ring_buffer::<u8>(5);

// Writing data to the buffer
producer.write_slices(|data, _offset| {
    data[..3].copy_from_slice(&[1, 2, 3]);
    3
}, None);
assert!(producer.write_element(4));
assert!(producer.write_element(5));
assert_eq!(producer.available(), 0);

// Reading data from the buffer
consumer.read_slices(|data, _offset| {
    assert_eq!(data, &[1, 2, 3, 4, 5]);
    4
}, None);
assert_eq!(consumer.read_element(), Some(5));
assert_eq!(consumer.read_element(), None);
assert_eq!(consumer.available(), 0);
  1. Writing Elements (Step 1): The producer writes the elements [1, 2, 3] into the buffer using write_slices.
  2. Writing Elements (Step 2): Next, the producer writes the element [4] into the buffer using write_element.
  3. Writing Elements (Step 3): Then, the producer writes the element [5] into the buffer using write_element, filling the buffer.
  4. Buffer Check: After these write operations, it checks that the buffer is full.
  5. Reading Elements (Step 1): The consumer reads the first four elements [1, 2, 3, 4] from the buffer using read_slices.
  6. Reading Elements (Step 2): Then, the consumer reads the remaining element [5] using read_element.
  7. Final Buffer Check: Finally, it checks that the buffer is empty.

Safety and Performance

This implementation ensures that elements are accessed safely through unsafe blocks with proper checks. The use of atomic operations ensures minimal overhead for synchronization, making it suitable for high-performance applications.

Optimized for Bulk Operations

Designed to handle multiple elements at once, reducing overhead for batch processing. Single-element operations may incur significant overhead.

License

Licensed under either of

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

A high-performance, lock-free ring buffer for single-producer, single-consumer scenarios.

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Packages

No packages published

Languages