Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 199839b

Browse files
committed
Pathfinder: pre-compute hash chain (and use 32 bits)
1 parent e819531 commit 199839b

File tree

1 file changed

+20
-18
lines changed

1 file changed

+20
-18
lines changed

matchfinder/pathfinder.go

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ type Pathfinder struct {
3131
ChainLength int
3232

3333
table []uint32
34-
chain []uint16
34+
chain []uint32
3535

3636
history []byte
3737
arrivals []arrival
@@ -57,7 +57,7 @@ type arrival struct {
5757
}
5858

5959
const (
60-
baseMatchCost float32 = 5
60+
baseMatchCost float32 = 4
6161
repeatMatchCost float32 = 6
6262
)
6363

@@ -106,9 +106,7 @@ func (q *Pathfinder) FindMatches(dst []Match, src []byte) []Match {
106106
delta := len(q.history) - q.MaxDistance
107107
copy(q.history, q.history[delta:])
108108
q.history = q.history[:q.MaxDistance]
109-
if q.ChainLength > 0 {
110-
q.chain = q.chain[:q.MaxDistance]
111-
}
109+
q.chain = q.chain[:q.MaxDistance]
112110

113111
for i, v := range q.table {
114112
newV := max(int(v)-delta, 0)
@@ -119,11 +117,20 @@ func (q *Pathfinder) FindMatches(dst []Match, src []byte) []Match {
119117
// Append src to the history buffer.
120118
historyLen := len(q.history)
121119
q.history = append(q.history, src...)
122-
if q.ChainLength > 0 {
123-
q.chain = append(q.chain, make([]uint16, len(src))...)
124-
}
120+
q.chain = append(q.chain, make([]uint32, len(src))...)
125121
src = q.history
126122

123+
// Calculate hashes and build the chain.
124+
for i := historyLen; i < len(src)-7; i++ {
125+
h := ((binary.LittleEndian.Uint64(src[i:]) & (1<<(8*q.HashLen) - 1)) * hashMul64) >> (64 - q.TableBits)
126+
candidate := int(q.table[h])
127+
q.table[h] = uint32(i)
128+
if candidate != 0 {
129+
delta := i - candidate
130+
q.chain[i] = uint32(delta)
131+
}
132+
}
133+
127134
for i := historyLen; i < len(src); i++ {
128135
var arrivedHere arrival
129136
if i > historyLen {
@@ -161,17 +168,12 @@ func (q *Pathfinder) FindMatches(dst []Match, src []byte) []Match {
161168
}
162169
}
163170

164-
// Calculate and store the hash.
165-
h := ((binary.LittleEndian.Uint64(src[i:]) & (1<<(8*q.HashLen) - 1)) * hashMul64) >> (64 - q.TableBits)
166-
candidate := int(q.table[h])
167-
q.table[h] = uint32(i)
168-
if q.ChainLength > 0 && candidate != 0 {
169-
delta := i - candidate
170-
if delta < 1<<16 {
171-
q.chain[i] = uint16(delta)
172-
}
171+
delta := q.chain[i]
172+
if delta == 0 {
173+
continue
173174
}
174-
if candidate == 0 || i-candidate > q.MaxDistance {
175+
candidate := i - int(delta)
176+
if candidate <= 0 || i-candidate > q.MaxDistance {
175177
continue
176178
}
177179

0 commit comments

Comments
 (0)