1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
//! # rdst
//!
//! rdst is a flexible native Rust implementation of multi-threaded unstable radix sort.
//!
//! ## Usage
//!
//! In the simplest case, you can use this sort by simply calling `my_vec.radix_sort_unstable()`. If you have a custom type to sort, you may need to implement `RadixKey` for that type.
//!
//! ## Default Implementations
//!
//! `RadixKey` is implemented for `Vec` of the following types out-of-the-box:
//!
//! * `u8`, `u16`, `u32`, `u64`, `u128`, `usize`
//! * `i8`, `i16`, `i32`, `i64`, `i128`, `isize`
//! * `f32`, `f64`
//! * `[u8; N]`
//!
//! ### Implementing `RadixKey`
//!
//! To be able to sort custom types, implement `RadixKey` as below.
//!
//! * `LEVELS` should be set to the total number of bytes you will consider for each item being sorted
//! * `get_level` should return the corresponding bytes from the least significant byte to the most significant byte
//!
//! Notes:
//! * This allows you to implement radix keys that span multiple values, or to implement radix keys that only look at part of a value.
//! * You should try to make this as fast as possible, so consider using branchless implementations wherever possible
//!
//! ```ignore
//! use rdst::RadixKey;
//!
//! impl RadixKey for u16 {
//! const LEVELS: usize = 2;
//!
//! #[inline]
//! fn get_level(&self, level: usize) -> u8 {
//! self.to_le_bytes()[level]
//! }
//! }
//! ```
//!
//! #### Partial `RadixKey`
//!
//! If you know your type has bytes that will always be zero, you can skip those bytes to speed up the sorting process. For instance, if you have a `u32` where values never exceed `10000`, you only need to consider two of the bytes. You could implement this as such:
//!
//! ```ignore
//! impl RadixKey for u32 {
//! const LEVELS: usize = 2;
//!
//! #[inline]
//! fn get_level(&self, level: usize) -> u8 {
//! (self >> (level * 8)) as u8
//! }
//! }
//! ```
//!
//! #### Multi-value `RadixKey`
//!
//! If your type has multiple values you need to search by, simply create a `RadixKey` that spans both values.
//!
//! ```ignore
//! impl RadixKey for MyStruct {
//! const LEVELS: usize = 4;
//!
//! #[inline]
//! fn get_level(&self, level: usize) -> u8 {
//! match level {
//! 0 => self.key_1[0],
//! 1 => self.key_1[1],
//! 2 => self.key_2[0],
//! 3 => self.key_2[1],
//! }
//! }
//! }
//! ```
//!
//! ## License
//!
//! Licensed under either of
//!
//! * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
//! * MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
//!
//! at your option.
//!
//! ### Contribution
//!
//! Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
mod director;
mod radix_key;
#[cfg(feature = "default-implementations")]
mod radix_key_impl;
#[cfg(not(any(test, feature = "bench")))]
mod sorts;
#[cfg(any(test, feature = "bench"))]
pub mod sorts;
#[cfg(not(any(test, feature = "bench")))]
mod tuning_parameters;
#[cfg(any(test, feature = "bench"))]
pub mod tuning_parameters;
#[cfg(not(any(test, feature = "bench")))]
mod utils;
#[cfg(any(test, feature = "bench"))]
pub mod utils;
#[cfg(feature = "bench")]
pub mod bench_utils;
#[cfg(any(test, feature = "bench"))]
pub mod test_utils;
mod radix_sort;
mod sort_manager;
// Public exports
pub use radix_key::RadixKey;
pub use radix_sort::RadixSort;