-
Notifications
You must be signed in to change notification settings - Fork 134
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1232 from rrybarczyk/utils-buffer-sv2-docs
Utils buffer sv2 docs
- Loading branch information
Showing
9 changed files
with
1,079 additions
and
178 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// # Simple `BufferPool` Usage | ||
// | ||
// This example showcases how to: | ||
// 1. Creating a `BufferPool`. | ||
// 2. Obtaining a writable buffer. | ||
// 3. Writing data into the buffer. | ||
// 4. Retrieving the data as a referenced slice. | ||
// 5. Retrieving the data as an owned slice. | ||
// | ||
// # Run | ||
// | ||
// ``` | ||
// cargo run --example basic_buffer_pool | ||
// ``` | ||
|
||
use buffer_sv2::{Buffer, BufferPool}; | ||
|
||
fn main() { | ||
// Create a new BufferPool with a capacity of 32 bytes | ||
let mut buffer_pool = BufferPool::new(32); | ||
|
||
// Get a writable buffer from the pool | ||
let data_to_write = b"Ciao, mundo!"; // 12 bytes | ||
let writable = buffer_pool.get_writable(data_to_write.len()); | ||
|
||
// Write data (12 bytes) into the buffer. | ||
writable.copy_from_slice(data_to_write); | ||
assert_eq!(buffer_pool.len(), 12); | ||
|
||
// Retrieve the data as a referenced slice | ||
let _data_slice = buffer_pool.get_data_by_ref(12); | ||
assert_eq!(buffer_pool.len(), 12); | ||
|
||
// Retrieve the data as an owned slice | ||
let data_slice = buffer_pool.get_data_owned(); | ||
assert_eq!(buffer_pool.len(), 0); | ||
|
||
let expect = [67, 105, 97, 111, 44, 32, 109, 117, 110, 100, 111, 33]; // "Ciao, mundo!" ASCII | ||
assert_eq!(data_slice.as_ref(), expect); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// # Handling Buffer Pool Exhaustion and Heap Allocation | ||
// | ||
// This example demonstrates how a buffer pool is filled. The back slots of the buffer pool are | ||
// exhausted first, followed by the front of the buffer pool. Once both the back and front are | ||
// exhausted, data is allocated on the heap at a performance decrease. | ||
// | ||
// 1. Fills up the back slots of the buffer pool until they’re exhausted. | ||
// 2. Releases one slot to allow the buffer pool to switch to front mode. | ||
// 3. Fully fills the front slots of the buffer pool. | ||
// 4. Switches to alloc mode for direct heap allocation when both the buffer pool's back and front | ||
// slots are at capacity. | ||
// | ||
// Below is a visual representation of how the buffer pool evolves as the example progresses: | ||
// | ||
// -------- BACK MODE | ||
// a------- BACK MODE (add "a" via loop) | ||
// aa------ BACK MODE (add "a" via loop) | ||
// aaa----- BACK MODE (add "a" via loop) | ||
// aaaa---- BACK MODE (add "a" via loop) | ||
// -aaa---- BACK MODE (pop front) | ||
// -aaab--- BACK MODE (add "b") | ||
// -aaabc-- BACK MODE (add "c" via loop) | ||
// -aaabcc- BACK MODE (add "c" via loop) | ||
// -aaabccc BACK MODE (add "c" via loop) | ||
// caaabccc BACK MODE (add "c" via loop, which gets added via front mode) | ||
// caaabccc ALLOC MODE (add "d", allocated in a new space in the heap) | ||
// | ||
// # Run | ||
// | ||
// ``` | ||
// cargo run --example buffer_pool_exhaustion | ||
// ``` | ||
|
||
use buffer_sv2::{Buffer, BufferPool}; | ||
use std::collections::VecDeque; | ||
|
||
fn main() { | ||
// 8 byte capacity | ||
let mut buffer_pool = BufferPool::new(8); | ||
let mut slices = VecDeque::new(); | ||
|
||
// Write data to fill back slots | ||
for _ in 0..4 { | ||
let data_bytes = b"a"; // 1 byte | ||
let writable = buffer_pool.get_writable(data_bytes.len()); // Mutable slice to internal | ||
// buffer | ||
writable.copy_from_slice(data_bytes); | ||
let data_slice = buffer_pool.get_data_owned(); // Take ownership of allocated segment | ||
slices.push_back(data_slice); | ||
} | ||
assert!(buffer_pool.is_back_mode()); | ||
|
||
// Release one slice and add another in the back (one slice in back mode must be free to switch | ||
// to front mode) | ||
slices.pop_front(); // Free the slice's associated segment in the buffer pool | ||
let data_bytes = b"b"; // 1 byte | ||
let writable = buffer_pool.get_writable(data_bytes.len()); | ||
writable.copy_from_slice(data_bytes); | ||
let data_slice = buffer_pool.get_data_owned(); | ||
slices.push_back(data_slice); | ||
assert!(buffer_pool.is_back_mode()); // Still in back mode | ||
|
||
// Write data to switch to front mode | ||
for _ in 0..4 { | ||
let data_bytes = b"c"; // 1 byte | ||
let writable = buffer_pool.get_writable(data_bytes.len()); | ||
writable.copy_from_slice(data_bytes); | ||
let data_slice = buffer_pool.get_data_owned(); | ||
slices.push_back(data_slice); | ||
} | ||
assert!(buffer_pool.is_front_mode()); // Confirm front mode | ||
|
||
// Add another slice, causing a switch to alloc mode | ||
let data_bytes = b"d"; // 1 byte | ||
let writable = buffer_pool.get_writable(data_bytes.len()); | ||
writable.copy_from_slice(data_bytes); | ||
let data_slice = buffer_pool.get_data_owned(); | ||
slices.push_back(data_slice); | ||
assert!(buffer_pool.is_alloc_mode()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// # Handling Variable-Sized Messages | ||
// | ||
// This example demonstrates how to the `BufferPool` handles messages of varying sizes. | ||
// | ||
// # Run | ||
// | ||
// ``` | ||
// cargo run --example variable_sized_messages | ||
// ``` | ||
|
||
use buffer_sv2::{Buffer, BufferPool}; | ||
use std::collections::VecDeque; | ||
|
||
fn main() { | ||
// Initialize a BufferPool with a capacity of 32 bytes | ||
let mut buffer_pool = BufferPool::new(32); | ||
let mut slices = VecDeque::new(); | ||
|
||
// Function to write data to the buffer pool and store the slice | ||
let write_data = |pool: &mut BufferPool<_>, data: &[u8], slices: &mut VecDeque<_>| { | ||
let writable = pool.get_writable(data.len()); | ||
writable.copy_from_slice(data); | ||
let data_slice = pool.get_data_owned(); | ||
slices.push_back(data_slice); | ||
println!("{:?}", &pool); | ||
println!(""); | ||
}; | ||
|
||
// Write a small message to the first slot | ||
let small_message = b"Hello"; | ||
write_data(&mut buffer_pool, small_message, &mut slices); | ||
assert!(buffer_pool.is_back_mode()); | ||
assert_eq!(slices.back().unwrap().as_ref(), small_message); | ||
|
||
// Write a medium-sized message to the second slot | ||
let medium_message = b"Rust programming"; | ||
write_data(&mut buffer_pool, medium_message, &mut slices); | ||
assert!(buffer_pool.is_back_mode()); | ||
assert_eq!(slices.back().unwrap().as_ref(), medium_message); | ||
|
||
// Write a large message that exceeds the remaining pool capacity | ||
let large_message = b"This message is larger than the remaining buffer pool capacity."; | ||
write_data(&mut buffer_pool, large_message, &mut slices); | ||
assert!(buffer_pool.is_alloc_mode()); | ||
assert_eq!(slices.back().unwrap().as_ref(), large_message); | ||
|
||
while let Some(slice) = slices.pop_front() { | ||
drop(slice); | ||
} | ||
|
||
// Write another small message | ||
let another_small_message = b"Hi"; | ||
write_data(&mut buffer_pool, another_small_message, &mut slices); | ||
assert_eq!(slices.back().unwrap().as_ref(), another_small_message); | ||
|
||
// Verify that the buffer pool has returned to back mode for the last write | ||
assert!(buffer_pool.is_back_mode()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.