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}