From 43aacd23fa43dac176446dd3d91115a05eb5b701 Mon Sep 17 00:00:00 2001 From: Mingwei Samuel Date: Thu, 9 Jan 2025 16:23:50 -0800 Subject: [PATCH] subgraph_loops wip --- dfir_rs/src/scheduled/graph.rs | 3 +- dfir_rs/src/util/slot_vec.rs | 66 +++++++++++++++++++++++++++++++--- 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/dfir_rs/src/scheduled/graph.rs b/dfir_rs/src/scheduled/graph.rs index 48427754313..12d8a789be2 100644 --- a/dfir_rs/src/scheduled/graph.rs +++ b/dfir_rs/src/scheduled/graph.rs @@ -23,13 +23,14 @@ use super::state::StateHandle; use super::subgraph::Subgraph; use super::{HandoffId, HandoffTag, SubgraphId, SubgraphTag}; use crate::scheduled::ticks::{TickDuration, TickInstant}; -use crate::util::slot_vec::SlotVec; +use crate::util::slot_vec::{SecondarySlotVec, SlotVec}; use crate::Never; /// A DFIR graph. Owns, schedules, and runs the compiled subgraphs. #[derive(Default)] pub struct Dfir<'a> { pub(super) subgraphs: SlotVec>, + pub(super) subgraph_loop: SecondarySlotVec, pub(super) context: Context, handoffs: SlotVec, diff --git a/dfir_rs/src/util/slot_vec.rs b/dfir_rs/src/util/slot_vec.rs index cca950e182b..b8d5ea1f526 100644 --- a/dfir_rs/src/util/slot_vec.rs +++ b/dfir_rs/src/util/slot_vec.rs @@ -55,7 +55,7 @@ pub struct SlotVec { _phantom: PhantomData, } impl SlotVec { - /// Creates a new SlotVec. + /// Creates a new `SlotVec`. pub fn new() -> Self { Self { slots: Vec::default(), @@ -63,14 +63,14 @@ impl SlotVec { } } - /// Inserts a value into the SlotVec and returns the key. + /// Inserts a value into the `SlotVec` and returns the key. pub fn insert(&mut self, value: Val) -> Key { let key = Key::from_raw(self.slots.len()); self.slots.push(value); key } - /// Use the provided function to generate a value given the key and insert it into the SlotVec. + /// Use the provided function to generate a value given the key and insert it into the `SlotVec`. pub fn insert_with_key(&mut self, func: F) -> Key where F: FnOnce(Key) -> Val, @@ -90,12 +90,12 @@ impl SlotVec { self.slots.get_mut(key.index) } - /// Returns the number of elements in the SlotVec. + /// Returns the number of elements in the `SlotVec`. pub fn len(&self) -> usize { self.slots.len() } - /// Returns true if the SlotVec is empty. + /// Returns true if the `SlotVec` is empty. pub fn is_empty(&self) -> bool { self.slots.is_empty() } @@ -117,3 +117,59 @@ impl Default for SlotVec { Self::new() } } + +/// A secondary map used to associated data with keys from elements in an existing [`SlotVec`]. +pub struct SecondarySlotVec { + slots: Vec>, + _phantom: PhantomData, +} +impl SecondarySlotVec { + /// Creates a new `SecondarySlotVec`. + pub fn new() -> Self { + Self { + slots: Vec::default(), + _phantom: PhantomData, + } + } + + /// Inserts a value into the `SecondarySlotVec` and returns the previous value associated with the key. + pub fn insert(&mut self, key: Key, value: Val) -> Option { + if key.index >= self.slots.len() { + self.slots.resize_with(key.index + 1, || None); + } + self.slots[key.index].replace(value) + } + + /// Removes a value associated with the key from the `SecondarySlotVec` and returns it. + pub fn remove(&mut self, key: Key) -> Option { + // TODO(mingwei): Shrink the vector? + self.slots[key.index].take() + } + + /// Returns a reference to the value associated with the key. + pub fn get(&self, key: Key) -> Option<&Val> { + self.slots.get(key.index).and_then(|v| v.as_ref()) + } + + /// Returns a mutable reference to the value associated with the key. + pub fn get_mut(&mut self, key: Key) -> Option<&mut Val> { + self.slots.get_mut(key.index).and_then(|v| v.as_mut()) + } +} +impl Default for SecondarySlotVec { + fn default() -> Self { + Self::new() + } +} +impl Index> for SecondarySlotVec { + type Output = Val; + + fn index(&self, key: Key) -> &Self::Output { + self.get(key).unwrap() + } +} +impl IndexMut> for SecondarySlotVec { + fn index_mut(&mut self, key: Key) -> &mut Self::Output { + self.get_mut(key).unwrap() + } +}