Skip to content

Commit

Permalink
Consolidate rolling hashes.
Browse files Browse the repository at this point in the history
  • Loading branch information
andybalholm committed Mar 9, 2019
1 parent 42dac55 commit ba67d8c
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 217 deletions.
2 changes: 1 addition & 1 deletion h35.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (h *H35) Prepare(one_shot bool, input_size uint, data []byte) {
common_a.dict_num_matches = 0
h.ha.Initialize(h.params)

h.hb = new(HROLLING_FAST)
h.hb = &hashRolling{jump: 1}
common_b = h.hb.Common()
common_b.params = h.params.hasher
common_b.is_prepared_ = false
Expand Down
2 changes: 1 addition & 1 deletion h55.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func (h *H55) Prepare(one_shot bool, input_size uint, data []byte) {
common_a.dict_num_matches = 0
h.ha.Initialize(h.params)

h.hb = new(HROLLING_FAST)
h.hb = &hashRolling{jump: 4}
common_b = h.hb.Common()
common_b.params = h.params.hasher
common_b.is_prepared_ = false
Expand Down
2 changes: 1 addition & 1 deletion h65.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func (h *H65) Prepare(one_shot bool, input_size uint, data []byte) {
common_a.dict_num_matches = 0
h.ha.Initialize(h.params)

h.hb = new(HROLLING)
h.hb = &hashRolling{jump: 1}
common_b = h.hb.Common()
common_b.params = h.params.hasher
common_b.is_prepared_ = false
Expand Down
8 changes: 4 additions & 4 deletions hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,10 @@ func newHasher(typ int) HasherHandle {
return new(H5)
case 6:
return new(H6)
case 10:
return new(H10)
case 35:
return new(H35)
case 40:
return &hashForgetfulChain{
bucketBits: 15,
Expand Down Expand Up @@ -311,14 +315,10 @@ func newHasher(typ int) HasherHandle {
hashLen: 7,
useDictionary: false,
}
case 35:
return new(H35)
case 55:
return new(H55)
case 65:
return new(H65)
case 10:
return new(H10)
}

panic(fmt.Sprintf("unknown hasher type: %d", typ))
Expand Down
74 changes: 35 additions & 39 deletions hrolling.go → hash_rolling.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,37 +11,40 @@ package brotli

/* Rolling hash for long distance long string matches. Stores one position
per bucket, bucket key is computed over a long region. */
var kRollingHashMul32HROLLING uint32 = 69069
var kRollingHashMul32hashRolling uint32 = 69069

var kInvalidPosHROLLING uint32 = 0xffffffff
var kInvalidPosHashRolling uint32 = 0xffffffff

/* This hasher uses a longer forward length, but returning a higher value here
will hurt compression by the main hasher when combined with a composite
hasher. The hasher tests for forward itself instead. */
func (*HROLLING) HashTypeLength() uint {
func (*hashRolling) HashTypeLength() uint {
return 4
}

func (*HROLLING) StoreLookahead() uint {
func (*hashRolling) StoreLookahead() uint {
return 4
}

/* Computes a code from a single byte. A lookup table of 256 values could be
used, but simply adding 1 works about as good. */
func HashByteHROLLING(byte byte) uint32 {
return uint32(byte) + 1
func (*hashRolling) HashByte(b byte) uint32 {
return uint32(b) + 1
}

func HashRollingFunctionInitialHROLLING(state uint32, add byte, factor uint32) uint32 {
return uint32(factor*state + HashByteHROLLING(add))
func (h *hashRolling) HashRollingFunctionInitial(state uint32, add byte, factor uint32) uint32 {
return uint32(factor*state + h.HashByte(add))
}

func HashRollingFunctionHROLLING(state uint32, add byte, rem byte, factor uint32, factor_remove uint32) uint32 {
return uint32(factor*state + HashByteHROLLING(add) - factor_remove*HashByteHROLLING(rem))
func (h *hashRolling) HashRollingFunction(state uint32, add byte, rem byte, factor uint32, factor_remove uint32) uint32 {
return uint32(factor*state + h.HashByte(add) - factor_remove*h.HashByte(rem))
}

type HROLLING struct {
type hashRolling struct {
HasherCommon

jump int

state uint32
table []uint32
next_ix uint
Expand All @@ -50,58 +53,51 @@ type HROLLING struct {
factor_remove uint32
}

func SelfHROLLING(handle HasherHandle) *HROLLING {
return handle.(*HROLLING)
}

func (h *HROLLING) Initialize(params *BrotliEncoderParams) {
var i uint
func (h *hashRolling) Initialize(params *BrotliEncoderParams) {
h.state = 0
h.next_ix = 0

h.factor = kRollingHashMul32HROLLING
h.factor = kRollingHashMul32hashRolling

/* Compute the factor of the oldest byte to remove: factor**steps modulo
0xffffffff (the multiplications rely on 32-bit overflow) */
h.factor_remove = 1

for i = 0; i < 32; i += 1 {
for i := 0; i < 32; i += h.jump {
h.factor_remove *= h.factor
}

h.table = make([]uint32, 16777216)
for i = 0; i < 16777216; i++ {
h.table[i] = kInvalidPosHROLLING
for i := 0; i < 16777216; i++ {
h.table[i] = kInvalidPosHashRolling
}
}

func (h *HROLLING) Prepare(one_shot bool, input_size uint, data []byte) {
var i uint

func (h *hashRolling) Prepare(one_shot bool, input_size uint, data []byte) {
/* Too small size, cannot use this hasher. */
if input_size < 32 {
return
}
h.state = 0
for i = 0; i < 32; i += 1 {
h.state = HashRollingFunctionInitialHROLLING(h.state, data[i], h.factor)
for i := 0; i < 32; i += h.jump {
h.state = h.HashRollingFunctionInitial(h.state, data[i], h.factor)
}
}

func (*HROLLING) Store(data []byte, mask uint, ix uint) {
func (*hashRolling) Store(data []byte, mask uint, ix uint) {
}

func (*HROLLING) StoreRange(data []byte, mask uint, ix_start uint, ix_end uint) {
func (*hashRolling) StoreRange(data []byte, mask uint, ix_start uint, ix_end uint) {
}

func (h *HROLLING) StitchToPreviousBlock(num_bytes uint, position uint, ringbuffer []byte, ring_buffer_mask uint) {
func (h *hashRolling) StitchToPreviousBlock(num_bytes uint, position uint, ringbuffer []byte, ring_buffer_mask uint) {
var position_masked uint
/* In this case we must re-initialize the hasher from scratch from the
current position. */

var available uint = num_bytes
if position&(1-1) != 0 {
var diff uint = 1 - (position & (1 - 1))
if position&uint(h.jump-1) != 0 {
var diff uint = uint(h.jump) - (position & uint(h.jump-1))
if diff > available {
available = 0
} else {
Expand All @@ -121,14 +117,14 @@ func (h *HROLLING) StitchToPreviousBlock(num_bytes uint, position uint, ringbuff
h.next_ix = position
}

func (*HROLLING) PrepareDistanceCache(distance_cache []int) {
func (*hashRolling) PrepareDistanceCache(distance_cache []int) {
}

func (h *HROLLING) 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 *hashRolling) 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) {
var cur_ix_masked uint = cur_ix & ring_buffer_mask
var pos uint = h.next_ix

if cur_ix&(1-1) != 0 {
if cur_ix&uint(h.jump-1) != 0 {
return
}

Expand All @@ -137,18 +133,18 @@ func (h *HROLLING) FindLongestMatch(dictionary *BrotliEncoderDictionary, data []
return
}

for pos = h.next_ix; pos <= cur_ix; pos += 1 {
for pos = h.next_ix; pos <= cur_ix; pos += uint(h.jump) {
var code uint32 = h.state & ((16777216 * 64) - 1)
var rem byte = data[pos&ring_buffer_mask]
var add byte = data[(pos+32)&ring_buffer_mask]
var found_ix uint = uint(kInvalidPosHROLLING)
var found_ix uint = uint(kInvalidPosHashRolling)

h.state = HashRollingFunctionHROLLING(h.state, add, rem, h.factor, h.factor_remove)
h.state = h.HashRollingFunction(h.state, add, rem, h.factor, h.factor_remove)

if code < 16777216 {
found_ix = uint(h.table[code])
h.table[code] = uint32(pos)
if pos == cur_ix && uint32(found_ix) != kInvalidPosHROLLING {
if pos == cur_ix && uint32(found_ix) != kInvalidPosHashRolling {
/* The cast to 32-bit makes backward distances up to 4GB work even
if cur_ix is above 4GB, despite using 32-bit values in the table. */
var backward uint = uint(uint32(cur_ix - found_ix))
Expand All @@ -169,5 +165,5 @@ func (h *HROLLING) FindLongestMatch(dictionary *BrotliEncoderDictionary, data []
}
}

h.next_ix = cur_ix + 1
h.next_ix = cur_ix + uint(h.jump)
}
171 changes: 0 additions & 171 deletions hrolling_fast.go

This file was deleted.

0 comments on commit ba67d8c

Please sign in to comment.