pub struct InMemorySlotAllocator { /* private fields */ }Expand description
In-memory slot allocator. Provides the same
SlotBackend interface as the
POSIX mmap backend (posix.rs), but lives on the process heap —
single-process pub/sub and test setups without an mmap dep.
Implementations§
Source§impl InMemorySlotAllocator
impl InMemorySlotAllocator
Sourcepub fn new(segment_id: u64, slot_count: usize, slot_capacity: usize) -> Self
pub fn new(segment_id: u64, slot_count: usize, slot_capacity: usize) -> Self
Creates a new allocator with slot_count slots, each with a
slot_capacity-byte data area.
Sourcepub fn notify_gen(&self) -> u64
pub fn notify_gen(&self) -> u64
Current notify generation. Capture it before checking a condition and
pass it to Self::wait_for_change to avoid a lost wakeup.
Sourcepub fn wait_for_change(&self, last: u64, timeout: Duration)
pub fn wait_for_change(&self, last: u64, timeout: Duration)
Blocks until the notify generation differs from last or timeout
elapses (event-driven, Spec §4.2 — no busy-poll). Pair with
Self::notify_gen for lost-wakeup-free waiting.
Sourcepub fn with_type_hash(self, hash: [u8; 16]) -> Self
pub fn with_type_hash(self, hash: [u8; 16]) -> Self
Spec §6.1: allocator with an associated type-hash. A reader
reading against this backend checks the hash against
T::TYPE_HASH and drops on mismatch.
Sourcepub fn reserve_slot(
&self,
active_readers_mask: ReaderMask,
) -> Result<SlotHandle, SlotError>
pub fn reserve_slot( &self, active_readers_mask: ReaderMask, ) -> Result<SlotHandle, SlotError>
Spec §4.1 reserve_slot. Finds a free slot (all active readers have read) or the first unused one.
§Errors
NoFreeSlot when all slots are loaned or unfinished.
Sourcepub fn commit_slot(
&self,
handle: SlotHandle,
bytes: &[u8],
) -> Result<u32, SlotError>
pub fn commit_slot( &self, handle: SlotHandle, bytes: &[u8], ) -> Result<u32, SlotError>
Spec §4.1 commit_slot. Writes the sample bytes into the slot and sets SlotHeader { sn, sample_size, reader_mask=0 }.
§Errors
OutOfBounds, SampleTooLarge, or lock poison.
Sourcepub fn slot_data_ptr(
&self,
handle: SlotHandle,
) -> Result<(*mut u8, usize), SlotError>
pub fn slot_data_ptr( &self, handle: SlotHandle, ) -> Result<(*mut u8, usize), SlotError>
In-place loan: writable pointer + capacity into a reserved slot’s data
area (see SlotBackend::slot_data_ptr).
§Errors
OutOfBounds if the slot is not a live loan, or lock poison.
Sourcepub fn commit_in_place(
&self,
handle: SlotHandle,
len: usize,
) -> Result<u32, SlotError>
pub fn commit_in_place( &self, handle: SlotHandle, len: usize, ) -> Result<u32, SlotError>
Finalizes an in-place loan (no copy) — sets the header + releases the
loan (see
SlotBackend::commit_in_place).
§Errors
SampleTooLarge, OutOfBounds, or lock poison.
Sourcepub fn slot_read_ptr(
&self,
handle: SlotHandle,
) -> Result<(*const u8, usize), SlotError>
pub fn slot_read_ptr( &self, handle: SlotHandle, ) -> Result<(*const u8, usize), SlotError>
Zero-copy read pointer + sample length into a committed slot (see
SlotBackend::slot_read_ptr).
§Errors
OutOfBounds or lock poison.
Sourcepub fn next_unread_slot(
&self,
reader_index: u8,
) -> Result<Option<SlotHandle>, SlotError>
pub fn next_unread_slot( &self, reader_index: u8, ) -> Result<Option<SlotHandle>, SlotError>
Next committed slot not yet read by reader_index (see
SlotBackend::next_unread_slot).
§Errors
Lock poison.
Sourcepub fn evict_stale(
&self,
max_age: Duration,
active_readers_mask: ReaderMask,
) -> Result<usize, SlotError>
pub fn evict_stale( &self, max_age: Duration, active_readers_mask: ReaderMask, ) -> Result<usize, SlotError>
Spec §5.1 timeout-eviction. Force-frees every committed, not-yet-fully-
read, not-currently-loaned slot whose sample was committed more than
max_age ago — by setting all active_readers_mask bits so the slot
counts as read and becomes reservable again. Guards against a single
hung/dead reader holding a slot hostage forever (the SPDP lease path
handles clean disconnects; this is the backstop for a stuck-but-alive
reader). Returns the number of slots evicted. The writer side calls this
periodically (e.g. from the DCPS tick).
§Errors
Lock poison.
Sourcepub fn discard_slot(&self, handle: SlotHandle) -> Result<(), SlotError>
pub fn discard_slot(&self, handle: SlotHandle) -> Result<(), SlotError>
Sourcepub fn read_slot(
&self,
handle: SlotHandle,
) -> Result<(SlotHeader, Vec<u8>), SlotError>
pub fn read_slot( &self, handle: SlotHandle, ) -> Result<(SlotHeader, Vec<u8>), SlotError>
Sourcepub fn mark_reader_disconnected(
&self,
reader_index: u8,
) -> Result<(), SlotError>
pub fn mark_reader_disconnected( &self, reader_index: u8, ) -> Result<(), SlotError>
Spec §5.2 reader disconnect, applied retroactively.
Called by the caller (SPDP lease-expiry hook) when a reader has died. Sets its bit on all slots, so that the slot allocator sees it as “has read” and frees up occupied slots again.
§Errors
Lock poison.
Sourcepub fn slot_capacity(&self) -> usize
pub fn slot_capacity(&self) -> usize
Slot capacity (data area; without header).
Sourcepub fn slot_count(&self) -> Result<usize, SlotError>
pub fn slot_count(&self) -> Result<usize, SlotError>
Number of configured slots.
Sourcepub fn slot_total_size(&self) -> usize
pub fn slot_total_size(&self) -> usize
Computes the total slot size (header + data, padded to a 64-byte cache line) — for SEDP discovery.
Trait Implementations§
Source§impl SlotBackend for InMemorySlotAllocator
Available on crate feature std only.
impl SlotBackend for InMemorySlotAllocator
std only.Source§fn reserve_slot(
&self,
active_readers_mask: ReaderMask,
) -> Result<SlotHandle, SlotError>
fn reserve_slot( &self, active_readers_mask: ReaderMask, ) -> Result<SlotHandle, SlotError>
commit_slot and thereby publishes the sample. Read moreSource§fn commit_slot(
&self,
handle: SlotHandle,
bytes: &[u8],
) -> Result<u32, SlotError>
fn commit_slot( &self, handle: SlotHandle, bytes: &[u8], ) -> Result<u32, SlotError>
{ sn, sample_size, reader_mask=0 }. Returns the SN. Read moreSource§fn discard_slot(&self, handle: SlotHandle) -> Result<(), SlotError>
fn discard_slot(&self, handle: SlotHandle) -> Result<(), SlotError>
Source§fn slot_data_ptr(
&self,
handle: SlotHandle,
) -> Result<(*mut u8, usize), SlotError>
fn slot_data_ptr( &self, handle: SlotHandle, ) -> Result<(*mut u8, usize), SlotError>
Self::commit_in_place. The pointer is valid until that
commit_in_place or a discard_slot for the same handle; the slot
must have been obtained from Self::reserve_slot and not yet
committed/discarded. Read moreSource§fn commit_in_place(
&self,
handle: SlotHandle,
len: usize,
) -> Result<u32, SlotError>
fn commit_in_place( &self, handle: SlotHandle, len: usize, ) -> Result<u32, SlotError>
len data bytes were already written in place
via Self::slot_data_ptr — sets SlotHeader { sn, sample_size=len, reader_mask=0 } and releases the loan, with no data copy. Returns
the SN. The byte-for-byte result is identical to commit_slot(handle, &buf[..len]), only without the staging copy. Read moreSource§fn slot_read_ptr(
&self,
handle: SlotHandle,
) -> Result<(*const u8, usize), SlotError>
fn slot_read_ptr( &self, handle: SlotHandle, ) -> Result<(*const u8, usize), SlotError>
Self::read_slot, which copies). The pointer is
valid until the slot is recycled (i.e. until every active reader has
mark_read it and the writer reserves it again); a same-host reader
reads it, then calls Self::mark_read. Default: InPlaceUnsupported. Read moreSource§fn next_unread_slot(
&self,
reader_index: u8,
) -> Result<Option<SlotHandle>, SlotError>
fn next_unread_slot( &self, reader_index: u8, ) -> Result<Option<SlotHandle>, SlotError>
sample_size > 0) that reader_index has not yet mark_read. Used
with Self::slot_read_ptr for an untyped zero-copy take, then
Self::mark_read to release it. Returns Ok(None) when nothing new
is pending. Default: Ok(None). Read moreSource§fn read_slot(
&self,
handle: SlotHandle,
) -> Result<(SlotHeader, Vec<u8>), SlotError>
fn read_slot( &self, handle: SlotHandle, ) -> Result<(SlotHeader, Vec<u8>), SlotError>
Source§fn mark_reader_disconnected(&self, reader_index: u8) -> Result<(), SlotError>
fn mark_reader_disconnected(&self, reader_index: u8) -> Result<(), SlotError>
reader_index bit retroactively on all slots
(SPDP lease-expiry). Read moreSource§fn slot_total_size(&self) -> usize
fn slot_total_size(&self) -> usize
Source§fn slot_capacity(&self) -> usize
fn slot_capacity(&self) -> usize
Source§fn type_hash(&self) -> Option<[u8; 16]>
fn type_hash(&self) -> Option<[u8; 16]>
None = the backend tracks no hash; the caller must
verify another way (e.g. via discovery). Default: None.Source§fn notify_generation(&self) -> u64
fn notify_generation(&self) -> u64
commit_slot (new sample → wake readers) and slot-free
(mark_read/discard_slot/… → wake writers). Capture this before
checking a condition and pass it to Self::wait_for_change for a
lost-wakeup-free wait. Default 0 for backends without notify support.Source§fn wait_for_change(&self, last: u64, timeout: Duration)
fn wait_for_change(&self, last: u64, timeout: Duration)
last or
timeout elapses (event-driven, NO busy-poll). Default: returns
immediately (a backend without notify support degrades to caller-driven
polling). InMemorySlotAllocator uses a Condvar; PosixSlotAllocator
uses a cross-process futex on a shared-memory word (Linux).