Skip to main content

cranpose_core/
recycled_node.rs

1use crate::{Node, NodeError, NodeId};
2
3/// Which recycle path a pooled node came from.
4#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
5pub enum RecycleOrigin {
6    /// A node created fresh, or one kept from before the last pass.
7    #[default]
8    Cold,
9    /// A node kept warm from the last pass.
10    Warm,
11}
12
13/// A removed node kept in a pool with its old id, so that a later node of the same type can reuse
14/// it.
15pub struct RecycledNode {
16    stable_id: NodeId,
17    pub(crate) node: Box<dyn Node>,
18    origin: RecycleOrigin,
19}
20
21impl RecycledNode {
22    /// A removed node as a pool shell: the fresh box it rehouses into, or
23    /// the node itself cleared in place when it offers none. A rehoused
24    /// node is dropped as it is, so it is not cleared first.
25    pub(crate) fn new(stable_id: NodeId, mut node: Box<dyn Node>, origin: RecycleOrigin) -> Self {
26        let node = node.rehouse_for_recycle().unwrap_or_else(|| {
27            node.prepare_for_recycle();
28            node
29        });
30        Self {
31            stable_id,
32            node,
33            origin,
34        }
35    }
36
37    pub(crate) fn from_shell(
38        stable_id: NodeId,
39        node: Box<dyn Node>,
40        origin: RecycleOrigin,
41    ) -> Self {
42        Self {
43            stable_id,
44            node,
45            origin,
46        }
47    }
48
49    /// Returns the id the node had before it was recycled.
50    pub fn stable_id(&self) -> NodeId {
51        self.stable_id
52    }
53
54    pub(crate) fn origin(&self) -> RecycleOrigin {
55        self.origin
56    }
57
58    pub(crate) fn set_origin(&mut self, origin: RecycleOrigin) {
59        self.origin = origin;
60    }
61
62    /// Returns the pooled node, so that it can be reset before reuse.
63    pub fn node_mut(&mut self) -> &mut dyn Node {
64        self.node.as_mut()
65    }
66
67    /// Splits the shell into its stable id, its node and the recycle path it came from.
68    pub fn into_parts(self) -> (NodeId, Box<dyn Node>, RecycleOrigin) {
69        (self.stable_id, self.node, self.origin)
70    }
71}
72
73/// The result of putting a recycled node back into an applier.
74#[derive(Debug, Clone, PartialEq, Eq)]
75pub struct RecycledNodeInsertion {
76    /// The id the node has now.
77    pub id: NodeId,
78    /// Whether the node got its old stable id back.
79    pub stable_id_reused: bool,
80    /// The error that forced a new id, or `None` if the old id was reused.
81    pub fallback_error: Option<NodeError>,
82}
83
84impl RecycledNodeInsertion {
85    pub(crate) fn reused(stable_id: NodeId) -> Self {
86        Self {
87            id: stable_id,
88            stable_id_reused: true,
89            fallback_error: None,
90        }
91    }
92
93    pub(crate) fn fresh(id: NodeId, fallback_error: Option<NodeError>) -> Self {
94        Self {
95            id,
96            stable_id_reused: false,
97            fallback_error,
98        }
99    }
100}