Consolidate composite hashes.

This commit is contained in:
Andy Balholm 2019-03-09 14:01:03 -08:00
parent ba67d8c1de
commit 99596c61a1
4 changed files with 23 additions and 226 deletions

102
h55.go
View File

@ -1,102 +0,0 @@
package brotli
/* NOLINT(build/header_guard) */
/* Copyright 2018 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
/* Composite hasher: This hasher allows to combine two other hashers, HASHER_A
and HASHER_B. */
func (h *H55) HashTypeLength() uint {
var a uint = h.ha.HashTypeLength()
var b uint = h.hb.HashTypeLength()
if a > b {
return a
} else {
return b
}
}
func (h *H55) StoreLookahead() uint {
var a uint = h.ha.StoreLookahead()
var b uint = h.hb.StoreLookahead()
if a > b {
return a
} else {
return b
}
}
type H55 struct {
HasherCommon
ha HasherHandle
hb HasherHandle
params *BrotliEncoderParams
}
func SelfH55(handle HasherHandle) *H55 {
return handle.(*H55)
}
func (h *H55) Initialize(params *BrotliEncoderParams) {
h.ha = nil
h.hb = nil
h.params = params
}
/* TODO: Initialize of the hashers is defered to Prepare (and params
remembered here) because we don't get the one_shot and input_size params
here that are needed to know the memory size of them. Instead provide
those params to all hashers InitializeH55 */
func (h *H55) Prepare(one_shot bool, input_size uint, data []byte) {
if h.ha == nil {
var common_a *HasherCommon
var common_b *HasherCommon
h.ha = newHasher(54)
common_a = h.ha.Common()
common_a.params = h.params.hasher
common_a.is_prepared_ = false
common_a.dict_num_lookups = 0
common_a.dict_num_matches = 0
h.ha.Initialize(h.params)
h.hb = &hashRolling{jump: 4}
common_b = h.hb.Common()
common_b.params = h.params.hasher
common_b.is_prepared_ = false
common_b.dict_num_lookups = 0
common_b.dict_num_matches = 0
h.hb.Initialize(h.params)
}
h.ha.Prepare(one_shot, input_size, data)
h.hb.Prepare(one_shot, input_size, data)
}
func (h *H55) Store(data []byte, mask uint, ix uint) {
h.ha.Store(data, mask, ix)
h.hb.Store(data, mask, ix)
}
func (h *H55) StoreRange(data []byte, mask uint, ix_start uint, ix_end uint) {
h.ha.StoreRange(data, mask, ix_start, ix_end)
h.hb.StoreRange(data, mask, ix_start, ix_end)
}
func (h *H55) StitchToPreviousBlock(num_bytes uint, position uint, ringbuffer []byte, ring_buffer_mask uint) {
h.ha.StitchToPreviousBlock(num_bytes, position, ringbuffer, ring_buffer_mask)
h.hb.StitchToPreviousBlock(num_bytes, position, ringbuffer, ring_buffer_mask)
}
func (h *H55) PrepareDistanceCache(distance_cache []int) {
h.ha.PrepareDistanceCache(distance_cache)
h.hb.PrepareDistanceCache(distance_cache)
}
func (h *H55) FindLongestMatch(dictionary *BrotliEncoderDictionary, data []byte, ring_buffer_mask uint, distance_cache []int, cur_ix uint, max_length uint, max_backward uint, gap uint, max_distance uint, out *HasherSearchResult) {
h.ha.FindLongestMatch(dictionary, data, ring_buffer_mask, distance_cache, cur_ix, max_length, max_backward, gap, max_distance, out)
h.hb.FindLongestMatch(dictionary, data, ring_buffer_mask, distance_cache, cur_ix, max_length, max_backward, gap, max_distance, out)
}

102
h65.go
View File

@ -1,102 +0,0 @@
package brotli
/* NOLINT(build/header_guard) */
/* Copyright 2018 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
/* Composite hasher: This hasher allows to combine two other hashers, HASHER_A
and HASHER_B. */
func (h *H65) HashTypeLength() uint {
var a uint = h.ha.HashTypeLength()
var b uint = h.hb.HashTypeLength()
if a > b {
return a
} else {
return b
}
}
func (h *H65) StoreLookahead() uint {
var a uint = h.ha.StoreLookahead()
var b uint = h.hb.StoreLookahead()
if a > b {
return a
} else {
return b
}
}
type H65 struct {
HasherCommon
ha HasherHandle
hb HasherHandle
params *BrotliEncoderParams
}
func SelfH65(handle HasherHandle) *H65 {
return handle.(*H65)
}
func (h *H65) Initialize(params *BrotliEncoderParams) {
h.ha = nil
h.hb = nil
h.params = params
}
/* TODO: Initialize of the hashers is defered to Prepare (and params
remembered here) because we don't get the one_shot and input_size params
here that are needed to know the memory size of them. Instead provide
those params to all hashers InitializeH65 */
func (h *H65) Prepare(one_shot bool, input_size uint, data []byte) {
if h.ha == nil {
var common_a *HasherCommon
var common_b *HasherCommon
h.ha = new(H6)
common_a = h.ha.Common()
common_a.params = h.params.hasher
common_a.is_prepared_ = false
common_a.dict_num_lookups = 0
common_a.dict_num_matches = 0
h.ha.Initialize(h.params)
h.hb = &hashRolling{jump: 1}
common_b = h.hb.Common()
common_b.params = h.params.hasher
common_b.is_prepared_ = false
common_b.dict_num_lookups = 0
common_b.dict_num_matches = 0
h.hb.Initialize(h.params)
}
h.ha.Prepare(one_shot, input_size, data)
h.hb.Prepare(one_shot, input_size, data)
}
func (h *H65) Store(data []byte, mask uint, ix uint) {
h.ha.Store(data, mask, ix)
h.hb.Store(data, mask, ix)
}
func (h *H65) StoreRange(data []byte, mask uint, ix_start uint, ix_end uint) {
h.ha.StoreRange(data, mask, ix_start, ix_end)
h.hb.StoreRange(data, mask, ix_start, ix_end)
}
func (h *H65) StitchToPreviousBlock(num_bytes uint, position uint, ringbuffer []byte, ring_buffer_mask uint) {
h.ha.StitchToPreviousBlock(num_bytes, position, ringbuffer, ring_buffer_mask)
h.hb.StitchToPreviousBlock(num_bytes, position, ringbuffer, ring_buffer_mask)
}
func (h *H65) PrepareDistanceCache(distance_cache []int) {
h.ha.PrepareDistanceCache(distance_cache)
h.hb.PrepareDistanceCache(distance_cache)
}
func (h *H65) FindLongestMatch(dictionary *BrotliEncoderDictionary, data []byte, ring_buffer_mask uint, distance_cache []int, cur_ix uint, max_length uint, max_backward uint, gap uint, max_distance uint, out *HasherSearchResult) {
h.ha.FindLongestMatch(dictionary, data, ring_buffer_mask, distance_cache, cur_ix, max_length, max_backward, gap, max_distance, out)
h.hb.FindLongestMatch(dictionary, data, ring_buffer_mask, distance_cache, cur_ix, max_length, max_backward, gap, max_distance, out)
}

15
hash.go
View File

@ -286,7 +286,10 @@ func newHasher(typ int) HasherHandle {
case 10: case 10:
return new(H10) return new(H10)
case 35: case 35:
return new(H35) return &hashComposite{
ha: newHasher(3),
hb: &hashRolling{jump: 4},
}
case 40: case 40:
return &hashForgetfulChain{ return &hashForgetfulChain{
bucketBits: 15, bucketBits: 15,
@ -316,9 +319,15 @@ func newHasher(typ int) HasherHandle {
useDictionary: false, useDictionary: false,
} }
case 55: case 55:
return new(H55) return &hashComposite{
ha: newHasher(54),
hb: &hashRolling{jump: 4},
}
case 65: case 65:
return new(H65) return &hashComposite{
ha: newHasher(6),
hb: &hashRolling{jump: 1},
}
} }
panic(fmt.Sprintf("unknown hasher type: %d", typ)) panic(fmt.Sprintf("unknown hasher type: %d", typ))

View File

@ -11,7 +11,7 @@ package brotli
/* Composite hasher: This hasher allows to combine two other hashers, HASHER_A /* Composite hasher: This hasher allows to combine two other hashers, HASHER_A
and HASHER_B. */ and HASHER_B. */
func (h *H35) HashTypeLength() uint { func (h *hashComposite) HashTypeLength() uint {
var a uint = h.ha.HashTypeLength() var a uint = h.ha.HashTypeLength()
var b uint = h.hb.HashTypeLength() var b uint = h.hb.HashTypeLength()
if a > b { if a > b {
@ -21,7 +21,7 @@ func (h *H35) HashTypeLength() uint {
} }
} }
func (h *H35) StoreLookahead() uint { func (h *hashComposite) StoreLookahead() uint {
var a uint = h.ha.StoreLookahead() var a uint = h.ha.StoreLookahead()
var b uint = h.hb.StoreLookahead() var b uint = h.hb.StoreLookahead()
if a > b { if a > b {
@ -31,33 +31,26 @@ func (h *H35) StoreLookahead() uint {
} }
} }
type H35 struct { type hashComposite struct {
HasherCommon HasherCommon
ha HasherHandle ha HasherHandle
hb HasherHandle hb HasherHandle
params *BrotliEncoderParams params *BrotliEncoderParams
} }
func SelfH35(handle HasherHandle) *H35 { func (h *hashComposite) Initialize(params *BrotliEncoderParams) {
return handle.(*H35)
}
func (h *H35) Initialize(params *BrotliEncoderParams) {
h.ha = nil
h.hb = nil
h.params = params h.params = params
} }
/* TODO: Initialize of the hashers is defered to Prepare (and params /* TODO: Initialize of the hashers is defered to Prepare (and params
remembered here) because we don't get the one_shot and input_size params remembered here) because we don't get the one_shot and input_size params
here that are needed to know the memory size of them. Instead provide here that are needed to know the memory size of them. Instead provide
those params to all hashers InitializeH35 */ those params to all hashers InitializehashComposite */
func (h *H35) Prepare(one_shot bool, input_size uint, data []byte) { func (h *hashComposite) Prepare(one_shot bool, input_size uint, data []byte) {
if h.ha == nil { if h.ha == nil {
var common_a *HasherCommon var common_a *HasherCommon
var common_b *HasherCommon var common_b *HasherCommon
h.ha = newHasher(3)
common_a = h.ha.Common() common_a = h.ha.Common()
common_a.params = h.params.hasher common_a.params = h.params.hasher
common_a.is_prepared_ = false common_a.is_prepared_ = false
@ -65,7 +58,6 @@ func (h *H35) Prepare(one_shot bool, input_size uint, data []byte) {
common_a.dict_num_matches = 0 common_a.dict_num_matches = 0
h.ha.Initialize(h.params) h.ha.Initialize(h.params)
h.hb = &hashRolling{jump: 1}
common_b = h.hb.Common() common_b = h.hb.Common()
common_b.params = h.params.hasher common_b.params = h.params.hasher
common_b.is_prepared_ = false common_b.is_prepared_ = false
@ -78,27 +70,27 @@ func (h *H35) Prepare(one_shot bool, input_size uint, data []byte) {
h.hb.Prepare(one_shot, input_size, data) h.hb.Prepare(one_shot, input_size, data)
} }
func (h *H35) Store(data []byte, mask uint, ix uint) { func (h *hashComposite) Store(data []byte, mask uint, ix uint) {
h.ha.Store(data, mask, ix) h.ha.Store(data, mask, ix)
h.hb.Store(data, mask, ix) h.hb.Store(data, mask, ix)
} }
func (h *H35) StoreRange(data []byte, mask uint, ix_start uint, ix_end uint) { func (h *hashComposite) StoreRange(data []byte, mask uint, ix_start uint, ix_end uint) {
h.ha.StoreRange(data, mask, ix_start, ix_end) h.ha.StoreRange(data, mask, ix_start, ix_end)
h.hb.StoreRange(data, mask, ix_start, ix_end) h.hb.StoreRange(data, mask, ix_start, ix_end)
} }
func (h *H35) StitchToPreviousBlock(num_bytes uint, position uint, ringbuffer []byte, ring_buffer_mask uint) { func (h *hashComposite) StitchToPreviousBlock(num_bytes uint, position uint, ringbuffer []byte, ring_buffer_mask uint) {
h.ha.StitchToPreviousBlock(num_bytes, position, ringbuffer, ring_buffer_mask) h.ha.StitchToPreviousBlock(num_bytes, position, ringbuffer, ring_buffer_mask)
h.hb.StitchToPreviousBlock(num_bytes, position, ringbuffer, ring_buffer_mask) h.hb.StitchToPreviousBlock(num_bytes, position, ringbuffer, ring_buffer_mask)
} }
func (h *H35) PrepareDistanceCache(distance_cache []int) { func (h *hashComposite) PrepareDistanceCache(distance_cache []int) {
h.ha.PrepareDistanceCache(distance_cache) h.ha.PrepareDistanceCache(distance_cache)
h.hb.PrepareDistanceCache(distance_cache) h.hb.PrepareDistanceCache(distance_cache)
} }
func (h *H35) FindLongestMatch(dictionary *BrotliEncoderDictionary, data []byte, ring_buffer_mask uint, distance_cache []int, cur_ix uint, max_length uint, max_backward uint, gap uint, max_distance uint, out *HasherSearchResult) { func (h *hashComposite) FindLongestMatch(dictionary *BrotliEncoderDictionary, data []byte, ring_buffer_mask uint, distance_cache []int, cur_ix uint, max_length uint, max_backward uint, gap uint, max_distance uint, out *HasherSearchResult) {
h.ha.FindLongestMatch(dictionary, data, ring_buffer_mask, distance_cache, cur_ix, max_length, max_backward, gap, max_distance, out) h.ha.FindLongestMatch(dictionary, data, ring_buffer_mask, distance_cache, cur_ix, max_length, max_backward, gap, max_distance, out)
h.hb.FindLongestMatch(dictionary, data, ring_buffer_mask, distance_cache, cur_ix, max_length, max_backward, gap, max_distance, out) h.hb.FindLongestMatch(dictionary, data, ring_buffer_mask, distance_cache, cur_ix, max_length, max_backward, gap, max_distance, out)
} }