Skip to main content

sedsnet/
shared_bytes.rs

1//! Shared wire bytes. The optional arena keeps full-slice views pinned until
2//! exclusive queue parking. Default builds retain the original Arc representation.
3#[cfg(not(feature = "compact-packet-store"))]
4pub type SharedBytes = alloc::sync::Arc<[u8]>;
5#[cfg(feature = "compact-packet-store")]
6pub type SharedBytes = crate::small_payload::SmallPayload<0>;
7
8/// Convert between owned and arena-aware bytes using the destination type.
9/// Keeping this generic supports both directions and the default Arc alias
10/// without feature-dependent identity-conversion lints at each call site.
11#[inline]
12pub(crate) fn convert<T: Into<U>, U>(bytes: T) -> U {
13    bytes.into()
14}
15
16/// Queue inspection must not retain a full-slice pin after classification.
17#[cfg(any(feature = "std", feature = "fair-admission"))]
18pub(crate) fn with_slice<R>(
19    bytes: &SharedBytes,
20    read: impl FnOnce(&[u8]) -> R,
21) -> crate::TelemetryResult<R> {
22    #[cfg(feature = "compact-packet-store")]
23    {
24        bytes.with_slice(read)
25    }
26    #[cfg(not(feature = "compact-packet-store"))]
27    {
28        Ok(read(bytes))
29    }
30}
31
32#[cfg(all(test, feature = "compact-packet-store", feature = "std"))]
33mod scoped_inspection_tests {
34    use super::*;
35    #[test]
36    fn queue_inspection_releases_its_pin_and_preserves_existing_consumer_pins() {
37        let store = crate::packet_store::PacketStore::new(64, 4, usize::MAX).unwrap();
38        let bytes = SharedBytes::Managed(crate::packet_store::ParkedPayload::new(
39            store.store(&[7; 32]).unwrap(),
40        ));
41        assert_eq!(store.stats().pinned_bytes, 0);
42        for _ in 0..32 {
43            assert_eq!(
44                with_slice(&bytes, |view| {
45                    assert_eq!(store.stats().pinned_bytes, 32);
46                    view[0]
47                })
48                .unwrap(),
49                7
50            );
51            assert_eq!(store.stats().pinned_bytes, 0);
52        }
53        let consumer = bytes.as_ref();
54        with_slice(&bytes, |view| assert_eq!(view, consumer)).unwrap();
55        assert_eq!(store.stats().pinned_bytes, 32);
56        assert_eq!(consumer, &[7; 32]);
57    }
58}