Skip to main content

zerodds_flatdata/
backend.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 ZeroDDS Contributors
3//! `SlotBackend`-Trait — abstrahiert das Slot-Storage-Backend.
4//!
5//! ADR-0003: drei produktive Backends — in-memory (Default fuer
6//! Tests + Single-Process), POSIX shm/mmap (Cross-Process Same-Host
7//! per `posix-mmap`-Feature), Iceoryx2 (optionale Bridge per
8//! `iceoryx2-bridge`-Feature). Alle drei implementieren denselben
9//! Trait, sodass `FlatWriter`/`FlatReader` generisch ueber dem
10//! Backend sind.
11
12use alloc::vec::Vec;
13
14use crate::allocator::{SlotError, SlotHandle};
15use crate::slot::{ReaderMask, SlotHeader};
16
17/// Backend-Trait fuer SHM-Slot-Allocator.
18///
19/// Implementer:
20/// - [`crate::InMemorySlotAllocator`] — In-Memory-Backend, Default
21///   fuer Single-Process-Tests und als Referenz-Implementation.
22/// - `PosixSlotAllocator` — POSIX-`shm_open` + `mmap`,
23///   Cross-Process-Same-Host (Feature `posix-mmap`).
24/// - `Iceoryx2SlotAdapter` — Iceoryx2-Bridge (optional Feature
25///   `iceoryx2-bridge`).
26pub trait SlotBackend: Send + Sync {
27    /// Reserviert einen freien Slot. Caller schreibt danach via
28    /// `commit_slot` und veroeffentlicht damit das Sample.
29    ///
30    /// # Errors
31    /// `NoFreeSlot` wenn alle Slots geloant oder unfertig.
32    fn reserve_slot(&self, active_readers_mask: ReaderMask) -> Result<SlotHandle, SlotError>;
33
34    /// Schreibt sample-bytes in den Slot und setzt SlotHeader
35    /// `{ sn, sample_size, reader_mask=0 }`. Liefert die SN.
36    ///
37    /// # Errors
38    /// `OutOfBounds`, `SampleTooLarge`, oder Lock-Poison.
39    fn commit_slot(&self, handle: SlotHandle, bytes: &[u8]) -> Result<u32, SlotError>;
40
41    /// Verwirft einen Loan ohne Commit. Slot wird wieder frei.
42    ///
43    /// # Errors
44    /// `OutOfBounds` oder Lock-Poison.
45    fn discard_slot(&self, handle: SlotHandle) -> Result<(), SlotError>;
46
47    /// Liest Slot-Header + Daten-Bytes (kopiert).
48    ///
49    /// # Errors
50    /// `OutOfBounds` oder Lock-Poison.
51    fn read_slot(&self, handle: SlotHandle) -> Result<(SlotHeader, Vec<u8>), SlotError>;
52
53    /// Setzt das Bit `reader_index` im `reader_mask` des Slots
54    /// (Reader hat gelesen).
55    ///
56    /// # Errors
57    /// `OutOfBounds` oder Lock-Poison.
58    fn mark_read(&self, handle: SlotHandle, reader_index: u8) -> Result<(), SlotError>;
59
60    /// Setzt das `reader_index`-Bit retroaktiv auf allen Slots
61    /// (SPDP-Lease-Expiry).
62    ///
63    /// # Errors
64    /// Lock-Poison.
65    fn mark_reader_disconnected(&self, reader_index: u8) -> Result<(), SlotError>;
66
67    /// Anzahl konfigurierter Slots.
68    ///
69    /// # Errors
70    /// Lock-Poison.
71    fn slot_count(&self) -> Result<usize, SlotError>;
72
73    /// Gesamt-Slot-Groesse (Header + Daten + Padding); fuer Discovery.
74    fn slot_total_size(&self) -> usize;
75
76    /// Daten-Bereich pro Slot (ohne Header, ohne Padding).
77    fn slot_capacity(&self) -> usize;
78
79    /// Spec §6.1: TYPE_HASH des Topic-Type, falls dem Backend
80    /// bekannt. `None` = Backend trackt keinen Hash; Caller muss
81    /// auf andere Weise (z.B. Discovery) verifizieren. Default: None.
82    fn type_hash(&self) -> Option<[u8; 16]> {
83        None
84    }
85}