sorted_insert/arc_mutex/mod.rs
1mod collections;
2
3use core::cmp::Ordering;
4use std::sync::{Arc, Mutex};
5
6#[doc(hidden)]
7pub trait SortedInsertArcMutexBasic<T> {
8 #[doc(hidden)]
9 fn insert_element(&mut self, index: usize, element: Arc<Mutex<T>>);
10}
11
12pub trait SortedInsertArcMutexBy<T>: SortedInsertArcMutexBasic<T> {
13 /// Insert elements to this sorted collection by a specific comparator and return the inserted index. Use linear search to find the index where a matching element could be inserted.
14 ///
15 /// ## Safety
16 ///
17 /// This function will panic if the element is locked.
18 #[inline]
19 fn sorted_insert_by<F: FnMut(&Arc<Mutex<T>>, &T) -> bool>(
20 &mut self,
21 element: Arc<Mutex<T>>,
22 mut f: F,
23 ) -> usize {
24 let element_guard = element.lock().unwrap();
25
26 let index = self.get_sorted_insert_index_by(|e| f(e, &*element_guard));
27
28 drop(element_guard);
29
30 self.insert_element(index, element);
31
32 index
33 }
34
35 #[doc(hidden)]
36 fn get_sorted_insert_index_by<F: FnMut(&Arc<Mutex<T>>) -> bool>(&self, f: F) -> usize;
37}
38
39pub trait SortedInsertArcMutexByKey<T>: SortedInsertArcMutexBy<T> {
40 /// Insert elements to this sorted collection in ascending order by a specific key and return the inserted index. Use linear search to find the index where a matching element could be inserted.
41 ///
42 /// ## Safety
43 ///
44 /// This function will panic if the element is locked.
45 #[inline]
46 fn sorted_insert_asc_by_key<A: Ord, F: FnMut(&T) -> &A>(
47 &mut self,
48 element: Arc<Mutex<T>>,
49 mut f: F,
50 ) -> usize {
51 self.sorted_insert_by(element.clone(), |e, element_t| {
52 // if the element is the same as the one being inserted, we can skip the comparison, in order to avoid deadlocks
53 if Arc::ptr_eq(e, &element) {
54 true
55 } else {
56 let e_guard = e.lock().unwrap();
57
58 f(&*e_guard) <= f(element_t)
59 }
60 })
61 }
62
63 /// Insert elements to this sorted collection in descending order by a specific key and return the inserted index. Use linear search to find the index where a matching element could be inserted.
64 ///
65 /// ## Safety
66 ///
67 /// This function will panic if the element is locked.
68 #[inline]
69 fn sorted_insert_desc_by_key<A: Ord, F: FnMut(&T) -> &A>(
70 &mut self,
71 element: Arc<Mutex<T>>,
72 mut f: F,
73 ) -> usize {
74 self.sorted_insert_by(element.clone(), |e, element_t| {
75 // if the element is the same as the one being inserted, we can skip the comparison, in order to avoid deadlocks
76 if Arc::ptr_eq(e, &element) {
77 true
78 } else {
79 let e_guard = e.lock().unwrap();
80
81 f(&*e_guard) >= f(element_t)
82 }
83 })
84 }
85}
86
87pub trait SortedInsertArcMutex<T: Ord>: SortedInsertArcMutexByKey<T> {
88 /// Insert elements to this sorted collection in ascending order and return the inserted index. Use linear search to find the index where a matching element could be inserted.
89 ///
90 /// ## Safety
91 ///
92 /// This function will panic if the element is locked.
93 #[inline]
94 fn sorted_insert_asc(&mut self, element: Arc<Mutex<T>>) -> usize {
95 self.sorted_insert_asc_by_key(element, |element| element)
96 }
97
98 /// Insert elements to this sorted collection in descending order and return the inserted index. Use linear search to find the index where a matching element could be inserted.
99 ///
100 /// ## Safety
101 ///
102 /// This function will panic if the element is locked.
103 #[inline]
104 fn sorted_insert_desc(&mut self, element: Arc<Mutex<T>>) -> usize {
105 self.sorted_insert_desc_by_key(element, |element| element)
106 }
107}
108
109pub trait SortedInsertBinaryArcMutexBy<T>: SortedInsertArcMutexBy<T> {
110 /// Insert elements to this sorted collection by a specific comparator and return the inserted index. Use binary search to find the index where a matching element could be inserted.
111 ///
112 /// ## Safety
113 ///
114 /// This function will panic if the element is locked.
115 fn sorted_insert_binary_by<F: FnMut(&Arc<Mutex<T>>, &T) -> Ordering>(
116 &mut self,
117 element: Arc<Mutex<T>>,
118 mut f: F,
119 ) -> usize {
120 let element_guard = element.lock().unwrap();
121
122 let index = self.get_sorted_insert_index_binary_by(|e| f(e, &*element_guard));
123
124 drop(element_guard);
125
126 self.insert_element(index, element);
127
128 index
129 }
130
131 #[doc(hidden)]
132 fn get_sorted_insert_index_binary_by<F: FnMut(&Arc<Mutex<T>>) -> Ordering>(
133 &mut self,
134 f: F,
135 ) -> usize;
136}
137
138pub trait SortedInsertBinaryArcMutexByKey<T>: SortedInsertBinaryArcMutexBy<T> {
139 /// Insert elements to this sorted collection in ascending order by a specific key and return the inserted index. Use binary search to find the index where a matching element could be inserted.
140 ///
141 /// ## Safety
142 ///
143 /// This function will panic if the element is locked.
144 #[inline]
145 fn sorted_insert_binary_asc_by_key<A: Ord, F: FnMut(&T) -> &A>(
146 &mut self,
147 element: Arc<Mutex<T>>,
148 mut f: F,
149 ) -> usize {
150 self.sorted_insert_binary_by(element.clone(), |e, element_t| {
151 // if the element is the same as the one being inserted, we can skip the comparison, in order to avoid deadlocks
152 if Arc::ptr_eq(e, &element) {
153 Ordering::Equal
154 } else {
155 let e_guard = e.lock().unwrap();
156
157 f(&*e_guard).cmp(f(element_t))
158 }
159 })
160 }
161
162 /// Insert elements to this sorted collection in descending order by a specific key and return the inserted index. Use binary search to find the index where a matching element could be inserted.
163 ///
164 /// ## Safety
165 ///
166 /// This function will panic if the element is locked.
167 #[inline]
168 fn sorted_insert_binary_desc_by_key<A: Ord, F: FnMut(&T) -> &A>(
169 &mut self,
170 element: Arc<Mutex<T>>,
171 mut f: F,
172 ) -> usize {
173 self.sorted_insert_binary_by(element.clone(), |e, element_t| {
174 // if the element is the same as the one being inserted, we can skip the comparison, in order to avoid deadlocks
175 if Arc::ptr_eq(e, &element) {
176 Ordering::Equal
177 } else {
178 let e_guard = e.lock().unwrap();
179
180 f(element_t).cmp(f(&*e_guard))
181 }
182 })
183 }
184}
185
186pub trait SortedInsertBinaryArcMutex<T: Ord>: SortedInsertBinaryArcMutexByKey<T> {
187 /// Insert elements to this sorted collection in ascending order and return the inserted index. Use binary search to find the index where a matching element could be inserted.
188 ///
189 /// ## Safety
190 ///
191 /// This function will panic if the element is locked.
192 #[inline]
193 fn sorted_insert_asc_binary(&mut self, element: Arc<Mutex<T>>) -> usize {
194 self.sorted_insert_binary_asc_by_key(element, |element| element)
195 }
196
197 /// Insert elements to this sorted collection in descending order and return the inserted index. Use binary search to find the index where a matching element could be inserted.
198 ///
199 /// ## Safety
200 ///
201 /// This function will panic if the element is locked.
202 #[inline]
203 fn sorted_insert_desc_binary(&mut self, element: Arc<Mutex<T>>) -> usize {
204 self.sorted_insert_binary_desc_by_key(element, |element| element)
205 }
206}