Skip to main content

honeycomb_core/cmap/dim3/links/
mod.rs

1mod one;
2mod three;
3mod two;
4
5use fast_stm::atomically_with_err;
6
7use crate::cmap::{CMap3, DartIdType, LinkError};
8use crate::geometry::CoordsFloat;
9use crate::stm::{Transaction, TransactionClosureResult};
10
11/// # **Link operations**
12impl<T: CoordsFloat> CMap3<T> {
13    /// `I`-link operator.
14    ///
15    /// # Description
16    ///
17    /// This operation corresponds to coherently linking two darts via their *β* images. Unlike
18    /// sewing, this does not alter associated attributes. For a thorough explanation of this
19    /// operation, its hypothesis & consequences, refer to the [user guide][UG].
20    ///
21    /// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/user-guide/definitions/sew.html
22    ///
23    /// # Arguments
24    ///
25    /// - `const I: u8` -- Link dimension.
26    /// - `t: &mut Transaction` -- Transaction associated to the operation.
27    /// - `lhs_dart_id: DartIdType` -- First dart ID.
28    /// - `rhs_dart_id: DartIdType` -- Second dart ID.
29    ///
30    /// # Errors
31    ///
32    /// This method should be called in a transactional context. The `Result` is then used to
33    /// validate the transaction; Errors should not be processed manually, only processed via the
34    /// `?` operator. The policy in case of failure can be defined when creating the transaction,
35    /// using `Transaction::with_control`.
36    ///
37    /// It may return an error if the transaction fails or if the link fails; See [`LinkError`] for
38    /// more detail about the latter.
39    ///
40    /// # Panics
41    ///
42    /// The method may panic if:
43    /// - `I >= 4` or `I == 0`,
44    /// - the two darts are not `I`-linkable.
45    pub fn link_tx<const I: u8>(
46        &self,
47        t: &mut Transaction,
48        lhs_dart_id: DartIdType,
49        rhs_dart_id: DartIdType,
50    ) -> TransactionClosureResult<(), LinkError> {
51        // these assertions + match on a const are optimized away
52        assert!(I < 4);
53        assert_ne!(I, 0);
54        match I {
55            1 => self.one_link_tx(t, lhs_dart_id, rhs_dart_id),
56            2 => self.two_link_tx(t, lhs_dart_id, rhs_dart_id),
57            3 => self.three_link_tx(t, lhs_dart_id, rhs_dart_id),
58            _ => unreachable!(),
59        }
60    }
61
62    #[allow(clippy::missing_errors_doc)]
63    /// `I`-unlink operator.
64    ///
65    /// # Description
66    ///
67    /// This operation corresponds to unlinking two darts by resetting their *β* images. Unlike
68    /// unsewing, this does not alter associated attributes. For a thorough explanation of this
69    /// operation, its hypothesis & consequences, refer to the [user guide][UG].
70    ///
71    /// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/user-guide/definitions/sew.html
72    ///
73    /// # Arguments
74    ///
75    /// - `const I: u8` -- Unlink dimension.
76    /// - `t: &mut Transaction` -- Transaction associated to the operation.
77    /// - `lhs_dart_id: DartIdType` -- First dart ID.
78    ///
79    /// The second dart ID is fetched using `I` and `lhs_dart_id`.
80    ///
81    /// # Return / Errors
82    ///
83    /// This method returns the old value of *β<sub>I</sub>(ld)*.
84    ///
85    /// This method should be called in a transactional context. The `Result` is then used to
86    /// validate the transaction; Errors should not be processed manually, only processed via the
87    /// `?` operator. The policy in case of failure can be defined when creating the transaction,
88    /// using `Transaction::with_control`.
89    ///
90    /// It may return an error if the transaction fails or if the link fails; See [`LinkError`] for
91    /// more detail about the latter.
92    ///
93    /// # Panics
94    ///
95    /// The method may panic if:
96    /// - `I >= 4` or `I == 0`,
97    /// - `lhs_dart_id` is already `I`-free.
98    pub fn unlink_tx<const I: u8>(
99        &self,
100        t: &mut Transaction,
101        lhs_dart_id: DartIdType,
102    ) -> TransactionClosureResult<DartIdType, LinkError> {
103        // these assertions + match on a const are optimized away
104        assert!(I < 4);
105        assert_ne!(I, 0);
106        match I {
107            1 => self.one_unlink_tx(t, lhs_dart_id),
108            2 => self.two_unlink_tx(t, lhs_dart_id),
109            3 => self.three_unlink_tx(t, lhs_dart_id),
110            _ => unreachable!(),
111        }
112    }
113
114    /// `I`-link operator.
115    ///
116    /// This variant is equivalent to [`link`][Self::link], but internally uses a transaction that
117    /// will be retried until validated.
118    ///
119    /// # Errors
120    ///
121    /// It may return an error if the transaction fails or if the link fails; See [`LinkError`] for
122    /// more detail about the latter.
123    ///
124    /// # Panics
125    ///
126    /// The method may panic if:
127    /// - `I >= 4` or `I == 0`,
128    /// - `lhs_dart_id` is already `I`-free.
129    pub fn link<const I: u8>(
130        &self,
131        lhs_dart_id: DartIdType,
132        rhs_dart_id: DartIdType,
133    ) -> Result<(), LinkError> {
134        // these assertions + match on a const are optimized away
135        assert!(I < 4);
136        assert_ne!(I, 0);
137        match I {
138            1 => atomically_with_err(|t| self.one_link_tx(t, lhs_dart_id, rhs_dart_id)),
139            2 => atomically_with_err(|t| self.two_link_tx(t, lhs_dart_id, rhs_dart_id)),
140            3 => atomically_with_err(|t| self.three_link_tx(t, lhs_dart_id, rhs_dart_id)),
141            _ => unreachable!(),
142        }
143    }
144
145    #[allow(clippy::missing_errors_doc)]
146    /// `I`-unlink operator.
147    ///
148    /// This variant is equivalent to [`unlink`][Self::unlink], but internally uses a transaction
149    /// that will be retried until validated.
150    ///
151    /// # Return / Errors
152    ///
153    /// This method returns the old value of *β<sub>I</sub>(ld)*.
154    ///
155    /// It may return an error if the transaction fails or if the link fails; See [`LinkError`] for
156    /// more detail about the latter.
157    ///
158    /// # Panics
159    ///
160    /// The method may panic if:
161    /// - `I >= 4` or `I == 0`,
162    /// - `lhs_dart_id` is already `I`-free.
163    pub fn unlink<const I: u8>(&self, lhs_dart_id: DartIdType) -> Result<DartIdType, LinkError> {
164        // these assertions + match on a const are optimized away
165        assert!(I < 4);
166        assert_ne!(I, 0);
167        match I {
168            1 => atomically_with_err(|t| self.one_unlink_tx(t, lhs_dart_id)),
169            2 => atomically_with_err(|t| self.two_unlink_tx(t, lhs_dart_id)),
170            3 => atomically_with_err(|t| self.three_unlink_tx(t, lhs_dart_id)),
171            _ => unreachable!(),
172        }
173    }
174}