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.
17pub(crate) fn with_slice<R>(
18    bytes: &SharedBytes,
19    read: impl FnOnce(&[u8]) -> R,
20) -> crate::TelemetryResult<R> {
21    #[cfg(feature = "compact-packet-store")]
22    {
23        bytes.with_slice(read)
24    }
25    #[cfg(not(feature = "compact-packet-store"))]
26    {
27        Ok(read(bytes))
28    }
29}
30
31#[cfg(all(test, feature = "compact-packet-store", feature = "std"))]
32mod scoped_inspection_tests {
33    use super::*;
34    #[test]
35    fn queue_inspection_releases_its_pin_and_preserves_existing_consumer_pins() {
36        let store = crate::packet_store::PacketStore::new(64, 4, usize::MAX).unwrap();
37        let bytes = SharedBytes::Managed(crate::packet_store::ParkedPayload::new(
38            store.store(&[7; 32]).unwrap(),
39        ));
40        assert_eq!(store.stats().pinned_bytes, 0);
41        for _ in 0..32 {
42            assert_eq!(
43                with_slice(&bytes, |view| {
44                    assert_eq!(store.stats().pinned_bytes, 32);
45                    view[0]
46                })
47                .unwrap(),
48                7
49            );
50            assert_eq!(store.stats().pinned_bytes, 0);
51        }
52        let consumer = bytes.as_ref();
53        with_slice(&bytes, |view| assert_eq!(view, consumer)).unwrap();
54        assert_eq!(store.stats().pinned_bytes, 32);
55        assert_eq!(consumer, &[7; 32]);
56    }
57}