-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
lib: move Rayon wrappers to lib crate (#380)
The Rayon wrapper methods are not specific to the cf-solana crate. Move them to lib so that any code in the future can easily use them if necessary.
- Loading branch information
Showing
10 changed files
with
853 additions
and
120 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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 |
---|---|---|
@@ -0,0 +1,46 @@ | ||
pub use ::blake3::Hasher; | ||
|
||
use crate::types::Hash; | ||
|
||
/// Calculates Blake3 hash of given byte slice. | ||
/// | ||
/// When `solana-program` or `solana-program-2` feature is enabled and | ||
/// building a solana program, this is using Solana’s `sol_blake3` syscall. | ||
/// Otherwise, the calculation is done by `blake3` crate. | ||
#[allow(dead_code)] | ||
pub fn hash(bytes: &[u8]) -> Hash { | ||
if cfg!(target_os = "solana-program") && | ||
(cfg!(feature = "solana-program") || | ||
cfg!(feature = "solana-program-2")) | ||
{ | ||
hashv(&[bytes]) | ||
} else { | ||
Hash(::blake3::hash(bytes).into()) | ||
} | ||
} | ||
|
||
/// Calculates Blake3 hash of concatenation of given byte slices. | ||
/// | ||
/// When `solana` or `solana2` feature is enabled and building a Solana | ||
/// program, this is using Solana’s `sol_blake3` syscall. Otherwise, the | ||
/// calculation is done by `blake3` crate. | ||
#[allow(dead_code)] | ||
pub fn hashv(slices: &[&[u8]]) -> Hash { | ||
#[cfg(all(target_os = "solana-program", feature = "solana-program-2"))] | ||
return Hash(solana_program_2::blake3::hashv(slices).0); | ||
#[cfg(all( | ||
target_os = "solana-program", | ||
feature = "solana-program", | ||
not(feature = "solana-program-2") | ||
))] | ||
return Hash(solana_program::blake3::hashv(slices).0); | ||
|
||
#[allow(dead_code)] | ||
{ | ||
let mut hasher = Hasher::default(); | ||
for bytes in slices { | ||
hasher.update(bytes); | ||
} | ||
hasher.finalize().into() | ||
} | ||
} |
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 was deleted.
Oops, something went wrong.
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 |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#[cfg(all(feature = "rayon", not(miri)))] | ||
use rayon::prelude::*; | ||
|
||
pub mod prelude { | ||
#[cfg(all(feature = "rayon", not(miri)))] | ||
pub use rayon::iter::ParallelIterator; | ||
} | ||
|
||
#[cfg(all(feature = "rayon", not(miri)))] | ||
pub type Chunks<'a, T> = rayon::slice::Chunks<'a, T>; | ||
#[cfg(any(not(feature = "rayon"), miri))] | ||
pub type Chunks<'a, T> = core::slice::Chunks<'a, T>; | ||
|
||
/// Splits array into `count`-element chunks. | ||
/// | ||
/// It uses conditional compilation and either uses Rayon’s `par_chunks` method | ||
/// (to allow parallelisation of the chunk processing) or standard `[T]::chunks` | ||
/// method. Specifically, if `rayon` feature is enabled and not building Miri | ||
/// tests, Rayon is used. | ||
/// | ||
/// Note that depending on compilation features and target the function is | ||
/// defined as returning `rayon::slice::Chunks` or `core::slice::Chunks`. types. | ||
/// | ||
/// # Example | ||
/// | ||
/// ``` | ||
/// use lib::par::prelude::*; | ||
/// | ||
/// let chunks = lib::par::chunks(&[0, 1, 2, 3, 4], 3) | ||
/// .map(|chunk| chunk.to_vec()) | ||
/// .collect::<Vec<Vec<u32>>>(); | ||
/// assert_eq!(&[vec![0, 1, 2], vec![3, 4]], chunks.as_slice()); | ||
/// ``` | ||
pub fn chunks<T: Sync>(arr: &[T], count: usize) -> Chunks<'_, T> { | ||
#[cfg(all(feature = "rayon", not(miri)))] | ||
return arr.par_chunks(count); | ||
#[cfg(any(not(feature = "rayon"), miri))] | ||
return arr.chunks(count); | ||
} | ||
|
||
#[test] | ||
fn test_chunks() { | ||
let got = chunks(&[1u32, 2, 3, 4, 5], 3) | ||
.map(|chunk| (chunk.len(), chunk.iter().sum::<u32>())) | ||
.collect::<alloc::vec::Vec<(usize, u32)>>(); | ||
assert_eq!(&[(3, 6), (2, 9)], got.as_slice()); | ||
} | ||
|
||
|
||
/// Sorts elements of a slice using given comparator. | ||
/// | ||
/// It uses conditional compilation and either uses Rayon’s | ||
/// `par_sort_unstable_by` or standard `sort_unstable_by` method. Specifically, | ||
/// if `rayon` feature is enabled and not building Miri tests, Rayon is used. | ||
/// | ||
/// # Example | ||
/// | ||
/// ``` | ||
/// let mut arr = [5, 4, 3, 1, 2, 3]; | ||
/// lib::par::sort_unstable_by(&mut arr[..], |a, b| a.cmp(b)); | ||
/// assert_eq!(&[1, 2, 3, 3, 4, 5], &arr[..]); | ||
/// ``` | ||
pub fn sort_unstable_by<T: Send + Sync>( | ||
arr: &mut [T], | ||
cmp: impl (Fn(&T, &T) -> core::cmp::Ordering) + Sync, | ||
) { | ||
#[cfg(all(feature = "rayon", not(miri)))] | ||
arr.par_sort_unstable_by(cmp); | ||
#[cfg(any(not(feature = "rayon"), miri))] | ||
arr.sort_unstable_by(cmp); | ||
} |
Oops, something went wrong.