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}