From 2a2b16364ac5876de96bbffe4b9d7d8baa2c4004 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Sat, 4 Dec 2021 16:56:42 -0500 Subject: [PATCH 1/3] feat: add unstable sorting methods --- src/map.rs | 56 +++++++++++++++++++++++++++++++++++++++++++----- src/rayon/map.rs | 39 +++++++++++++++++++++++++++++++-- src/set.rs | 46 +++++++++++++++++++++++++++++++++------ 3 files changed, 128 insertions(+), 13 deletions(-) diff --git a/src/map.rs b/src/map.rs index aa8d06a0..6032c339 100644 --- a/src/map.rs +++ b/src/map.rs @@ -664,18 +664,18 @@ where /// Sort the map’s key-value pairs by the default ordering of the keys. /// - /// See `sort_by` for details. + /// See [`sort_by`](Self::sort_by) for details. pub fn sort_keys(&mut self) where K: Ord, { - self.with_entries(|entries| { - entries.sort_by(|a, b| Ord::cmp(&a.key, &b.key)); + self.with_entries(move |entries| { + entries.sort_by(move |a, b| K::cmp(&a.key, &b.key)); }); } /// Sort the map’s key-value pairs in place using the comparison - /// function `compare`. + /// function `cmp`. /// /// The comparison function receives two key and value pairs to compare (you /// can sort by keys or values or their combination as needed). @@ -691,7 +691,7 @@ where }); } - /// Sort the key-value pairs of the map and return a by value iterator of + /// Sort the key-value pairs of the map and return a by-value iterator of /// the key-value pairs with the result. /// /// The sort is stable. @@ -706,6 +706,52 @@ where } } + /// Sort the map's key-value pairs by the default ordering of the keys, but + /// may not preserve the order of equal elements. + /// + /// See [`sort_unstable_by`](Self::sort_unstable_by) for details. + pub fn sort_unstable_keys(&mut self) + where + K: Ord, + { + self.with_entries(move |entries| { + entries.sort_unstable_by(move |a, b| K::cmp(&a.key, &b.key)); + }); + } + + /// Sort the map's key-value pairs in place using the comparison function `cmp`, but + /// may not preserve the order of equal elements. + /// + /// The comparison function receives two key and value pairs to compare (you + /// can sort by keys or values or their combination as needed). + /// + /// Computes in **O(n log n + c)** time and **O(n)** space where *n* is + /// the length of the map and *c* is the capacity. The sort is unstable. + pub fn sort_unstable_by(&mut self, mut cmp: F) + where + F: FnMut(&K, &V, &K, &V) -> Ordering, + { + self.with_entries(move |entries| { + entries.sort_unstable_by(move |a, b| cmp(&a.key, &a.value, &b.key, &b.value)); + }); + } + + /// Sort the key-value pairs of the map and return a by-value iterator of + /// the key-value pairs with the result. + /// + /// The sort is unstable. + #[inline] + pub fn sorted_unstable_by(self, mut cmp: F) -> IntoIter + where + F: FnMut(&K, &V, &K, &V) -> Ordering, + { + let mut entries = self.into_entries(); + entries.sort_unstable_by(move |a, b| cmp(&a.key, &a.value, &b.key, &b.value)); + IntoIter { + iter: entries.into_iter(), + } + } + /// Reverses the order of the map’s key-value pairs in place. /// /// Computes in **O(n)** time and **O(1)** space. diff --git a/src/rayon/map.rs b/src/rayon/map.rs index ed2da3ef..abea8a13 100644 --- a/src/rayon/map.rs +++ b/src/rayon/map.rs @@ -303,7 +303,7 @@ where } /// Sort the map’s key-value pairs in place and in parallel, using the comparison - /// function `compare`. + /// function `cmp`. /// /// The comparison function receives two key and value pairs to compare (you /// can sort by keys or values or their combination as needed). @@ -316,7 +316,7 @@ where }); } - /// Sort the key-value pairs of the map in parallel and return a by value parallel + /// Sort the key-value pairs of the map in parallel and return a by-value parallel /// iterator of the key-value pairs with the result. pub fn par_sorted_by(self, cmp: F) -> IntoParIter where @@ -326,6 +326,41 @@ where entries.par_sort_by(move |a, b| cmp(&a.key, &a.value, &b.key, &b.value)); IntoParIter { entries } } + + /// Sort the map's key-value pairs in parallel, by the default ordering of the keys. + pub fn par_sort_unstable_keys(&mut self) + where + K: Ord, + { + self.with_entries(|entries| { + entries.par_sort_unstable_by(|a, b| K::cmp(&a.key, &b.key)); + }); + } + + /// Sort the map's key-value pairs in place and in parallel, using the comparison + /// function `cmp`. + /// + /// The comparison function receives two key and value pairs to compare (you + /// can sort by keys or values or their combination as needed). + pub fn par_sort_unstable_by(&mut self, cmp: F) + where + F: Fn(&K, &V, &K, &V) -> Ordering + Sync, + { + self.with_entries(|entries| { + entries.par_sort_unstable_by(move |a, b| cmp(&a.key, &a.value, &b.key, &b.value)); + }); + } + + /// Sort the key-value pairs of the map in parallel and return a by-value parallel + /// iterator of the key-value pairs with the result. + pub fn par_sorted_unstable_by(self, cmp: F) -> IntoParIter + where + F: Fn(&K, &V, &K, &V) -> Ordering + Sync, + { + let mut entries = self.into_entries(); + entries.par_sort_unstable_by(move |a, b| cmp(&a.key, &a.value, &b.key, &b.value)); + IntoParIter { entries } + } } /// A parallel mutable iterator over the values of a `IndexMap`. diff --git a/src/set.rs b/src/set.rs index 66c3da4d..72a386c5 100644 --- a/src/set.rs +++ b/src/set.rs @@ -553,7 +553,7 @@ where /// Sort the set’s values by their default ordering. /// - /// See `sort_by` for details. + /// See [`sort_by`](Self::sort_by) for details. pub fn sort(&mut self) where T: Ord, @@ -561,17 +561,17 @@ where self.map.sort_keys() } - /// Sort the set’s values in place using the comparison function `compare`. + /// Sort the set’s values in place using the comparison function `cmp`. /// /// Computes in **O(n log n)** time and **O(n)** space. The sort is stable. - pub fn sort_by(&mut self, mut compare: F) + pub fn sort_by(&mut self, mut cmp: F) where F: FnMut(&T, &T) -> Ordering, { - self.map.sort_by(move |a, _, b, _| compare(a, b)); + self.map.sort_by(move |a, _, b, _| cmp(a, b)); } - /// Sort the values of the set and return a by value iterator of + /// Sort the values of the set and return a by-value iterator of /// the values with the result. /// /// The sort is stable. @@ -580,7 +580,41 @@ where F: FnMut(&T, &T) -> Ordering, { IntoIter { - iter: self.map.sorted_by(move |a, &(), b, &()| cmp(a, b)).iter, + iter: self.map.sorted_by(move |a, _, b, _| cmp(a, b)).iter, + } + } + + /// Sort the set's values by their default ordering. + /// + /// See [`sort_unstable_by`](Self::sort_unstable_by) for details. + pub fn sort_unstable(&mut self) + where + T: Ord, + { + self.map.sort_unstable_keys() + } + + /// Sort the set's values in place using the comparison funtion `cmp`. + /// + /// Computes in **O(n log n)** time and **O(n)** space. The sort is unstable. + pub fn sort_unstable_by(&mut self, mut cmp: F) + where + F: FnMut(&T, &T) -> Ordering, + { + self.map.sort_unstable_by(move |a, _, b, _| cmp(a, b)) + } + + /// Sort the values of the set and return a by-value iterator of + /// the values with the result. + pub fn sorted_unstable_by(self, mut cmp: F) -> IntoIter + where + F: FnMut(&T, &T) -> Ordering, + { + IntoIter { + iter: self + .map + .sorted_unstable_by(move |a, _, b, _| cmp(a, b)) + .iter, } } From 7bdcfc0f70c30c6d8a91409fc00dbec8784541d5 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Thu, 9 Dec 2021 17:03:09 -0500 Subject: [PATCH 2/3] fix: add forgotten set parallel unstable sorting methods --- src/rayon/set.rs | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/rayon/set.rs b/src/rayon/set.rs index f3e0da91..a6e1251f 100644 --- a/src/rayon/set.rs +++ b/src/rayon/set.rs @@ -452,7 +452,7 @@ where }); } - /// Sort the set’s values in place and in parallel, using the comparison function `compare`. + /// Sort the set’s values in place and in parallel, using the comparison function `cmp`. pub fn par_sort_by(&mut self, cmp: F) where F: Fn(&T, &T) -> Ordering + Sync, @@ -462,7 +462,7 @@ where }); } - /// Sort the values of the set in parallel and return a by value parallel iterator of + /// Sort the values of the set in parallel and return a by-value parallel iterator of /// the values with the result. pub fn par_sorted_by(self, cmp: F) -> IntoParIter where @@ -472,6 +472,37 @@ where entries.par_sort_by(move |a, b| cmp(&a.key, &b.key)); IntoParIter { entries } } + + /// Sort the set's values in parallel by their default ordering. + pub fn par_sort_unstable(&mut self) + where + T: Ord, + { + self.with_entries(|entries| { + entries.par_sort_unstable_by(|a, b| T::cmp(&a.key, &b.key)); + }); + } + + /// Sort the set’s values in place and in parallel, using the comparison function `cmp`. + pub fn par_sort_unstable_by(&mut self, cmp: F) + where + F: Fn(&T, &T) -> Ordering + Sync, + { + self.with_entries(|entries| { + entries.par_sort_unstable_by(move |a, b| cmp(&a.key, &b.key)); + }); + } + + /// Sort the values of the set in parallel and return a by-value parallel iterator of + /// the values with the result. + pub fn par_sorted_unstable_by(self, cmp: F) -> IntoParIter + where + F: Fn(&T, &T) -> Ordering + Sync, + { + let mut entries = self.into_entries(); + entries.par_sort_unstable_by(move |a, b| cmp(&a.key, &b.key)); + IntoParIter { entries } + } } /// Requires crate feature `"rayon"`. From 6fca269adf18b1dd0ef0e62f5e8744c7cba51725 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 6 Jan 2022 10:39:49 -0800 Subject: [PATCH 3/3] No extra space is used in unstable sorts --- src/map.rs | 2 +- src/set.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/map.rs b/src/map.rs index 6032c339..76993c36 100644 --- a/src/map.rs +++ b/src/map.rs @@ -725,7 +725,7 @@ where /// The comparison function receives two key and value pairs to compare (you /// can sort by keys or values or their combination as needed). /// - /// Computes in **O(n log n + c)** time and **O(n)** space where *n* is + /// Computes in **O(n log n + c)** time where *n* is /// the length of the map and *c* is the capacity. The sort is unstable. pub fn sort_unstable_by(&mut self, mut cmp: F) where diff --git a/src/set.rs b/src/set.rs index 72a386c5..ddd1cc38 100644 --- a/src/set.rs +++ b/src/set.rs @@ -596,7 +596,7 @@ where /// Sort the set's values in place using the comparison funtion `cmp`. /// - /// Computes in **O(n log n)** time and **O(n)** space. The sort is unstable. + /// Computes in **O(n log n)** time. The sort is unstable. pub fn sort_unstable_by(&mut self, mut cmp: F) where F: FnMut(&T, &T) -> Ordering,