-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
perfect sort optimization for window expressions (#2614)
- Loading branch information
Showing
5 changed files
with
50 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,4 @@ pub mod arena; | |
pub mod contention_pool; | ||
mod error; | ||
pub mod mem; | ||
pub mod sort; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
use rayon::{prelude::*, ThreadPool}; | ||
|
||
/// This is a perfect sort particularly useful for an argsort of an argsort | ||
/// The second argsort sorts indices from `0` to `len` so can be just assigned to the | ||
/// new index location. | ||
/// | ||
/// Besides that we know that all indices are unique ang thus not alias so we can parallelize. | ||
/// | ||
/// This sort does not sort in place and will allocate. | ||
/// | ||
/// - The right indices are used for sorting | ||
/// - The left indices are placed at the location right points to. | ||
/// | ||
/// # Safety | ||
/// The caller must ensure that the right indexes fo `&[(_, u32)]` are integers ranging from `0..idx.len` | ||
pub unsafe fn perfect_sort(pool: &ThreadPool, idx: &[(u32, u32)]) -> Vec<u32> { | ||
let chunk_size = std::cmp::max( | ||
idx.len() / pool.current_num_threads(), | ||
pool.current_num_threads(), | ||
); | ||
|
||
let mut out: Vec<u32> = Vec::with_capacity(idx.len()); | ||
let ptr = out.as_mut_ptr() as *const u32 as usize; | ||
|
||
pool.install(|| { | ||
idx.par_chunks(chunk_size).for_each(|indices| { | ||
let ptr = ptr as *mut u32; | ||
for (idx_val, idx_location) in indices { | ||
// Safety: | ||
// idx_location is in bounds by invariant of this function | ||
// and we ensured we have at least `idx.len()` capacity | ||
*ptr.add(*idx_location as usize) = *idx_val; | ||
} | ||
}); | ||
}); | ||
// Safety: | ||
// all elements are written | ||
out.set_len(idx.len()); | ||
out | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.