parent
c05d9f8304
commit
5645ff417c
@ -0,0 +1,49 @@
|
||||
//! Extensions
|
||||
use bytes::Buf;
|
||||
use std::io::BufRead;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct BufIter<B: ?Sized>(B);
|
||||
|
||||
pub trait BufIterExt
|
||||
{
|
||||
fn chunks_iter(self) -> BufIter<Self>;
|
||||
}
|
||||
|
||||
impl<T: ?Sized + Buf> Iterator for BufIter<T>
|
||||
{
|
||||
type Item = bytes::Bytes;
|
||||
fn next(&mut self) -> Option<Self::Item>
|
||||
{
|
||||
if self.0.has_remaining() {
|
||||
Some(self.0.copy_to_bytes(self.0.chunk().len()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Buf> BufIterExt for B
|
||||
{
|
||||
fn chunks_iter(self) -> BufIter<Self> {
|
||||
BufIter(self)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
pub struct BufReadIter<B: ?Sized>(usize, B);
|
||||
|
||||
pub trait BufReadExt
|
||||
{
|
||||
fn chunks_iter(self, sz: usize) -> BufReadIter<Self>;
|
||||
}
|
||||
|
||||
impl<B: ?Sized + BufRead> Iterator for BufReadIter<B>
|
||||
{
|
||||
type Item = bytes::Bytes;
|
||||
fn next(&mut self) -> Option<Self::Item>
|
||||
{
|
||||
self.1.read_exact(buf)
|
||||
}
|
||||
}
|
||||
*/
|
@ -1,4 +1,117 @@
|
||||
|
||||
//mod pool; A)JR AOISJOAIJOIA JODIJAOSI JDFUCK THIS DOESN@T WORK FUCK ATOMICREFCELL FUCK YOU FFUCK EVERYTHING AAAAAAAAAAAAA
|
||||
pub mod encode;
|
||||
pub mod hash;
|
||||
//mod ext; use ext::*;
|
||||
mod encode;
|
||||
mod hash;
|
||||
|
||||
pub use digest;
|
||||
|
||||
pub use hash::{
|
||||
ParallelHashOutput,
|
||||
ParallelHash,
|
||||
ParallelDigest,
|
||||
};
|
||||
|
||||
pub type DefaultDigest = sha2::Sha256;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
||||
pub struct Builder<D= DefaultDigest>
|
||||
{
|
||||
digest: std::marker::PhantomData<D>,
|
||||
chunk_size: Option<std::num::NonZeroUsize>,
|
||||
}
|
||||
|
||||
impl Builder<DefaultDigest>
|
||||
{
|
||||
#[inline]
|
||||
pub fn create_default() -> ParallelDigest<DefaultDigest>
|
||||
{
|
||||
Self::new().create()
|
||||
}
|
||||
pub const fn new_default() -> Self
|
||||
{
|
||||
Self {
|
||||
digest: std::marker::PhantomData,
|
||||
chunk_size: None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: digest::Digest> Builder<D>
|
||||
{
|
||||
//pub type Digest = D;
|
||||
pub const fn new() -> Self
|
||||
{
|
||||
Self {
|
||||
digest: std::marker::PhantomData,
|
||||
chunk_size: None
|
||||
}
|
||||
}
|
||||
pub const fn with_digest<N: digest::Digest>(self) -> Builder<N>
|
||||
{
|
||||
Builder {
|
||||
chunk_size: self.chunk_size,
|
||||
digest: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
pub const fn with_chunk_size(self, chunk_size: usize) -> Self
|
||||
{
|
||||
Self {
|
||||
chunk_size: std::num::NonZeroUsize::new(chunk_size),
|
||||
..self
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<D: digest::Digest + Send + Sync> Builder<D>
|
||||
{
|
||||
#[inline]
|
||||
pub fn chunk_size(&self) -> usize
|
||||
{
|
||||
extern "C" {
|
||||
fn getpagesize() -> std::os::raw::c_int;
|
||||
}
|
||||
self.chunk_size
|
||||
.or_else(|| unsafe { std::num::NonZeroUsize::new(getpagesize().try_into().expect("Failed to get page size")) })
|
||||
.expect("Failed to get page size: cannot be zero")
|
||||
.get()
|
||||
}
|
||||
#[inline]
|
||||
pub fn create(self) -> ParallelDigest<D>
|
||||
{
|
||||
ParallelDigest::<D>::new(self.chunk_size())
|
||||
}
|
||||
#[inline]
|
||||
pub fn digest_slice(self, slice: impl AsRef<[u8]>) -> ParallelHash<D>
|
||||
{
|
||||
ParallelDigest::<D>::digest_slice(self.chunk_size(), slice)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: digest::Digest + Send + Sync> From<Builder<D>> for ParallelDigest<D>
|
||||
{
|
||||
#[inline]
|
||||
fn from(from: Builder<D>) -> Self
|
||||
{
|
||||
from.create()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests
|
||||
{
|
||||
use super::*;
|
||||
#[test]
|
||||
fn parallel_hash_specific_cs()
|
||||
{
|
||||
const CHUNK_SIZE: usize = 0;
|
||||
let slice = [10u8; 4096 << 2];//b"One two three for fize size seven eight.";
|
||||
let mut digest = Builder::new().with_chunk_size(CHUNK_SIZE).create();
|
||||
digest.append_slice(slice);
|
||||
let digest= digest.complete().finalize();
|
||||
println!("digest: {digest}");
|
||||
|
||||
assert_eq!(digest, Builder::new_default().with_chunk_size(CHUNK_SIZE).digest_slice(slice).finalize(), "phash of same input produced different output");
|
||||
|
||||
assert_ne!(digest, Builder::new_default().with_chunk_size(CHUNK_SIZE).digest_slice(&slice[..8]).finalize(), "phash of differing input produced same output");
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in new issue