oxidd_manager_index/node/mod.rs
1use std::sync::atomic::Ordering;
2
3pub mod fixed_arity;
4
5/// Base traits to be satisfied by inner nodes for oxidd-manager. This does not
6/// include the [`InnerNode`][oxidd_core::InnerNode] trait.
7///
8/// # Safety
9///
10/// - The reference counter must be initialized to 2.
11/// - [`Self::retain()`] increments the counter by 1
12/// - [`Self::release()`] decrements the counter by 1 with (at least)
13/// [`Release`][std::sync::atomic::Ordering::Release] order.
14/// - [`Self::load_rc()`] loads the reference count with the specified load
15/// order.
16/// - An implementation must not modify the counter unless instructed externally
17/// via the `retain()` or `release()` methods.
18pub unsafe trait NodeBase: Eq + std::hash::Hash {
19 /// Atomically increment the reference counter (with
20 /// [`Relaxed`][std::sync::atomic::Ordering::Relaxed] order)
21 ///
22 /// This method is responsible for preventing an overflow of the reference
23 /// counter.
24 fn retain(&self);
25
26 /// Atomically decrement the reference counter (with
27 /// [`Release`][std::sync::atomic::Ordering::Release] order)
28 ///
29 /// Returns the previous reference count.
30 ///
31 /// A call to this function only modifies the counter value and never drops
32 /// `self`.
33 ///
34 /// # Safety
35 ///
36 /// The caller must give up ownership of one reference to `self`.
37 unsafe fn release(&self) -> usize;
38
39 /// Atomically load the current reference count with the given `order`
40 fn load_rc(&self, order: Ordering) -> usize;
41
42 /// Whether this node type contains additional data that needs to be dropped
43 /// to avoid memory leaks.
44 ///
45 /// If the node only consists of [`Edge`][crate::manager::Edge]s and types
46 /// that implement [`Copy`], an implementation may return `false`. This may
47 /// speed up dropping a diagram a lot.
48 #[inline(always)]
49 fn needs_drop() -> bool {
50 true
51 }
52}