prns_runtime/runtime/packet_phy_retention/
heap.rs1use core::num::NonZeroUsize;
2
3use alloc::vec::Vec;
4use prns_core::lemire_index::HeapLemireIndex;
5
6use crate::interfaces::{RssiDbm, SignalQualityTenthsPercent, SnrQuarterDb};
7use crate::routing::dedup::PacketHash;
8
9use super::{PacketMetricStorage, PacketPhyRetention};
10
11pub const RNS_1_4_2_PACKET_PHY_CAPACITY: usize = 512;
12
13pub struct HeapPacketMetricStorage<Metric, const CAPACITY: usize> {
14 packet_hashes: Vec<PacketHash>,
15 metrics: Vec<Metric>,
16 index: HeapLemireIndex,
17}
18
19impl<Metric, const CAPACITY: usize> Default for HeapPacketMetricStorage<Metric, CAPACITY> {
20 fn default() -> Self {
21 const {
22 assert!(
23 CAPACITY > 0,
24 "packet PHY retention capacity must be non-zero"
25 );
26 assert!(
27 CAPACITY < u32::MAX as usize,
28 "heap packet PHY retention exceeds its index slot range"
29 );
30 }
31 Self {
32 packet_hashes: Vec::with_capacity(CAPACITY),
33 metrics: Vec::with_capacity(CAPACITY),
34 index: HeapLemireIndex::default(),
35 }
36 }
37}
38
39impl<Metric: Copy, const CAPACITY: usize> PacketMetricStorage
40 for HeapPacketMetricStorage<Metric, CAPACITY>
41{
42 type Metric = Metric;
43
44 fn capacity(&self) -> NonZeroUsize {
45 match NonZeroUsize::new(CAPACITY) {
46 Some(capacity) => capacity,
47 None => unreachable!("packet PHY retention capacity is non-zero"),
48 }
49 }
50
51 fn len(&self) -> usize {
52 self.packet_hashes.len()
53 }
54
55 fn append(&mut self, packet_hash: PacketHash, metric: Metric) {
56 self.packet_hashes.push(packet_hash);
57 self.metrics.push(metric);
58 self.index
59 .insert(self.packet_hashes.len() - 1, &self.packet_hashes);
60 }
61
62 fn replace(&mut self, slot: usize, packet_hash: PacketHash, metric: Metric) {
63 self.index.remove_slot(slot, &self.packet_hashes);
64 self.packet_hashes[slot] = packet_hash;
65 self.metrics[slot] = metric;
66 self.index.insert(slot, &self.packet_hashes);
67 }
68
69 fn get(&self, packet_hash: PacketHash) -> Option<Metric> {
70 self.index
71 .get(&packet_hash, &self.packet_hashes)
72 .map(|slot| self.metrics[slot])
73 }
74}
75
76pub type HeapPacketPhyRetention = PacketPhyRetention<
77 HeapPacketMetricStorage<RssiDbm, RNS_1_4_2_PACKET_PHY_CAPACITY>,
78 HeapPacketMetricStorage<SnrQuarterDb, RNS_1_4_2_PACKET_PHY_CAPACITY>,
79 HeapPacketMetricStorage<SignalQualityTenthsPercent, RNS_1_4_2_PACKET_PHY_CAPACITY>,
80>;