orx_selfref_col/memory/
policy.rs

1use crate::{CoreCol, Node, NodePtr, Variant};
2use orx_pinned_vec::PinnedVec;
3
4/// Policy which determines how the memory of closed nodes will be reclaimed and made useful.
5///
6/// Two main implementors are:
7/// * [`MemoryReclaimOnThreshold::<D>`] reclaims unused holes whenever the utilization of the memory falls below a constant threshold determined by `D`.
8///   This could be considered as the flexible and general approach.
9/// * [`MemoryReclaimNever`] which never reclaims the holes due to popped or removed; i.e., closed, nodes.
10///   This approach has the advantage that a `NodeIndex` is never invalidated due to memory reorganization.
11///   Note that it still allows to reclaim closed nodes manually.
12///   Therefore, it fits very well to situations where
13///   * removals from the list are not substantial, or
14///   * having valid indices is crucial.
15///
16/// [`MemoryReclaimOnThreshold::<D>`]: crate::MemoryReclaimOnThreshold
17/// [`MemoryReclaimNever`]: crate::MemoryReclaimNever
18pub trait MemoryPolicy<V: Variant>: Clone + Default {
19    /// Reclaims closed nodes.
20    ///
21    /// Assume that **A** below stands for active nodes and **x** designates a closed or popped node.
22    /// If the underlying storage has the following layout at a certain stage:
23    /// * `[ x, x, A, x, A, A, A, x, A, x ]`
24    ///
25    /// the reclaimer first reorganizes the nodes so that we have:
26    /// * `[ A, A, A, A, A, x, x, x, x, x ]`
27    ///
28    /// and next trims the storage to reclaim memory
29    /// * `[ A, A, A, A, A ]`
30    ///
31    /// Note that the order of the **A**s might change which is not relevant since this is self-referential-collection;
32    /// i.e., the order is defined by the links among nodes.
33    ///
34    /// # Possible Strategies
35    ///
36    /// Memory reclaim policies define this operation:
37    /// * [`MemoryReclaimNever`]: The manual policy which never automatically runs this operation,
38    ///   gives the control completely to the user.
39    ///   This fits best the use cases where we want to ensure the validity of stored node references or indices
40    ///   as long as we do not change them.
41    ///   * the user can never call `reclaim_closed_nodes` to ensure that the indices are always valid; or
42    ///   * reclaims closed nodes whenever it is possible to refresh indices or prior indices are no longer required.
43    /// * [`MemoryReclaimOnThreshold`]: Automatically reorganizes self whenever the utilization of memory falls
44    ///   below a predefined threshold. This is the setting fitting most of the use cases.
45    ///
46    /// [`MemoryReclaimNever`]: crate::MemoryReclaimNever
47    /// [`MemoryReclaimOnThreshold`]: crate::MemoryReclaimOnThreshold
48    fn reclaim_closed_nodes<P>(col: &mut CoreCol<V, P>, closed_node_ptr: &NodePtr<V>) -> bool
49    where
50        P: PinnedVec<Node<V>>;
51}