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