From 2fe53df4aac4818352a41603ed9a997a59223c7b Mon Sep 17 00:00:00 2001 From: Daniel Reiter Horn Date: Wed, 28 Nov 2018 16:00:31 -0800 Subject: [PATCH] make hasher clonable --- src/enc/backward_references.rs | 111 ++++++++++++++++++++++++++++++++- src/enc/hash_to_binary_tree.rs | 19 +++++- 2 files changed, 126 insertions(+), 4 deletions(-) diff --git a/src/enc/backward_references.rs b/src/enc/backward_references.rs index 82543f03..62c7a300 100755 --- a/src/enc/backward_references.rs +++ b/src/enc/backward_references.rs @@ -111,6 +111,7 @@ pub enum HowPrepared { ALREADY_PREPARED, NEWLY_PREPARED, } +#[derive(Clone)] pub struct Struct1 { pub params: BrotliHasherParams, pub is_prepared_: i32, @@ -138,6 +139,10 @@ pub struct HasherSearchResult { pub score: u64, } +pub trait CloneWithAlloc + alloc::Allocator> { + fn clone_with_alloc(&self, m: &mut Alloc) -> Self; +} + pub trait AnyHasher { fn Opts(&self) -> H9Opts; fn GetHasherCommon(&mut self) -> &mut Struct1; @@ -818,7 +823,7 @@ pub trait AdvHashSpecialization { fn load_and_mix_word(&self, data: &[u8]) -> u64; } -pub struct AdvHasher + alloc::Allocator> { pub GetHasherCommon: Struct1, @@ -831,6 +836,7 @@ pub struct AdvHasher>::AllocatedMemory, pub h9_opts: H9Opts, } +#[derive(Clone)] pub struct H5Sub {} impl AdvHashSpecialization for H5Sub { fn get_hash_mask(&self) -> u64 { @@ -852,7 +858,7 @@ impl AdvHashSpecialization for H5Sub { 4 } } - +#[derive(Clone)] pub struct H6Sub { pub hash_mask: u64, } @@ -884,7 +890,7 @@ fn BackwardReferencePenaltyUsingLastDistance(distance_short_code: usize) -> u64 } -impl + alloc::Allocator> AnyHasher +impl + alloc::Allocator> AnyHasher for AdvHasher { fn Opts(&self) -> H9Opts { self.h9_opts @@ -1290,6 +1296,90 @@ fn SearchInStaticDictionary(dictionary: &BrotliDictionary is_match_found } +impl + alloc::Allocator> CloneWithAlloc for BasicHasher> { + fn clone_with_alloc(&self, m: &mut Alloc) -> Self { + let mut ret = BasicHasher::> { + GetHasherCommon: self.GetHasherCommon.clone(), + buckets_: H2Sub::{ + buckets_:>::alloc_cell(m, self.buckets_.buckets_.len()), + }, + h9_opts: self.h9_opts.clone(), + }; + ret.buckets_.buckets_.slice_mut().clone_from_slice(self.buckets_.buckets_.slice()); + ret + } +} +impl + alloc::Allocator> CloneWithAlloc for BasicHasher> { + fn clone_with_alloc(&self, m: &mut Alloc) -> Self { + let mut ret = BasicHasher::> { + GetHasherCommon: self.GetHasherCommon.clone(), + buckets_: H3Sub::{ + buckets_:>::alloc_cell(m, self.buckets_.buckets_.len()), + }, + h9_opts: self.h9_opts.clone(), + }; + ret.buckets_.buckets_.slice_mut().clone_from_slice(self.buckets_.buckets_.slice()); + ret + } +} +impl + alloc::Allocator> CloneWithAlloc for BasicHasher> { + fn clone_with_alloc(&self, m: &mut Alloc) -> Self { + let mut ret = BasicHasher::> { + GetHasherCommon: self.GetHasherCommon.clone(), + buckets_: H4Sub::{ + buckets_:>::alloc_cell(m, self.buckets_.buckets_.len()), + }, + h9_opts: self.h9_opts.clone(), + }; + ret.buckets_.buckets_.slice_mut().clone_from_slice(self.buckets_.buckets_.slice()); + ret + } +} +impl + alloc::Allocator> CloneWithAlloc for BasicHasher> { + fn clone_with_alloc(&self, m: &mut Alloc) -> Self { + let mut ret = BasicHasher::> { + GetHasherCommon: self.GetHasherCommon.clone(), + buckets_: H54Sub::{ + buckets_:>::alloc_cell(m, self.buckets_.len()), + }, + h9_opts: self.h9_opts.clone(), + }; + ret.buckets_.buckets_.slice_mut().clone_from_slice(self.buckets_.buckets_.slice()); + ret + } +} +impl + alloc::Allocator> CloneWithAlloc for H9 { + fn clone_with_alloc(&self, m: &mut Alloc) -> Self { + let mut ret = H9:: { + num_:>::alloc_cell(m, self.num_.len()), + buckets_:>::alloc_cell(m, self.buckets_.len()), + dict_search_stats_: self.dict_search_stats_.clone(), + h9_opts: self.h9_opts.clone(), + }; + ret.buckets_.slice_mut().clone_from_slice(self.buckets_.slice()); + ret.num_.slice_mut().clone_from_slice(self.num_.slice()); + ret + } +} +impl + alloc::Allocator, + Special: AdvHashSpecialization+Sized+Clone,> CloneWithAlloc for AdvHasher { + fn clone_with_alloc(&self, m: &mut Alloc) -> Self { + let mut ret = AdvHasher:: { + GetHasherCommon: self.GetHasherCommon.clone(), + bucket_size_:self.bucket_size_, + block_size_:self.block_size_, + specialization:self.specialization.clone(), + hash_shift_:self.hash_shift_, + block_mask_:self.block_mask_, + num:>::alloc_cell(m, self.num.len()), + buckets:>::alloc_cell(m, self.buckets.len()), + h9_opts: self.h9_opts.clone(), + }; + ret.buckets.slice_mut().clone_from_slice(self.buckets.slice()); + ret.num.slice_mut().clone_from_slice(self.num.slice()); + ret + } +} pub enum UnionHasher + alloc::Allocator> { Uninit, H2(BasicHasher>), @@ -1301,6 +1391,21 @@ pub enum UnionHasher + alloc::Allocator> { H9(H9), H10(H10, H10DefaultParams>), } +impl + alloc::Allocator> CloneWithAlloc for UnionHasher { + fn clone_with_alloc(&self, m: &mut Alloc) -> Self { + match *self { + UnionHasher::H2(ref hasher) => UnionHasher::H2(hasher.clone_with_alloc(m)), + UnionHasher::H3(ref hasher) => UnionHasher::H3(hasher.clone_with_alloc(m)), + UnionHasher::H4(ref hasher) => UnionHasher::H4(hasher.clone_with_alloc(m)), + UnionHasher::H5(ref hasher) => UnionHasher::H5(hasher.clone_with_alloc(m)), + UnionHasher::H6(ref hasher) => UnionHasher::H6(hasher.clone_with_alloc(m)), + UnionHasher::H54(ref hasher) => UnionHasher::H54(hasher.clone_with_alloc(m)), + UnionHasher::H9(ref hasher) => UnionHasher::H9(hasher.clone_with_alloc(m)), + UnionHasher::H10(ref hasher) => UnionHasher::H10(hasher.clone_with_alloc(m)), + UnionHasher::Uninit => UnionHasher::Uninit, + } + } +} macro_rules! match_all_hashers_mut { ($xself : expr, $func_call : ident, $( $args:expr),*) => { match $xself { diff --git a/src/enc/hash_to_binary_tree.rs b/src/enc/hash_to_binary_tree.rs index 6126638c..a62ca7f7 100755 --- a/src/enc/hash_to_binary_tree.rs +++ b/src/enc/hash_to_binary_tree.rs @@ -1,6 +1,6 @@ #![allow(dead_code, unused_imports)] use super::command::{Command, ComputeDistanceCode, InitCommand, GetInsertLengthCode, GetCopyLengthCode, CombineLengthCodes, PrefixEncodeCopyDistance, CommandCopyLen}; -use super::backward_references::{BrotliEncoderParams, kHashMul32,kHashMul64, kHashMul64Long, BrotliHasherParams, kInvalidMatch, kDistanceCacheIndex, kDistanceCacheOffset, Struct1, H9Opts, HowPrepared, AnyHasher, HasherSearchResult}; +use super::backward_references::{BrotliEncoderParams, kHashMul32,kHashMul64, kHashMul64Long, BrotliHasherParams, kInvalidMatch, kDistanceCacheIndex, kDistanceCacheOffset, Struct1, H9Opts, HowPrepared, AnyHasher, CloneWithAlloc, HasherSearchResult}; use super::dictionary_hash::kStaticDictionaryHash; use super::static_dict::{BROTLI_UNALIGNED_LOAD32, BROTLI_UNALIGNED_LOAD64, FindMatchLengthWithLimit}; use super::static_dict::{BrotliDictionary, kBrotliEncDictionary, BrotliFindAllStaticDictionaryMatches}; @@ -138,6 +138,23 @@ impl, self.buckets_.free(m32); } } +impl + alloc::Allocator, Buckets:Allocable+SliceWrapperMut+SliceWrapper, Params:H10Params, + > CloneWithAlloc for H10 { + fn clone_with_alloc(&self, m: &mut Alloc) -> Self { + let mut ret = H10:: { + window_mask_: self.window_mask_, + common: self.common.clone(), + buckets_:Buckets::new(m, 0), + invalid_pos_:self.invalid_pos_, + forest:>::alloc_cell(m, self.forest.len()), + _params: core::marker::PhantomData::::default(), + }; + ret.buckets_.slice_mut().clone_from_slice(self.buckets_.slice()); + ret.forest.slice_mut().clone_from_slice(self.forest.slice()); + ret + } +} + impl, Buckets: Allocable+SliceWrapperMut+SliceWrapper, Params:H10Params> AnyHasher for H10 {