2
2
mirror of https://github.com/octoleo/restic.git synced 2024-12-23 03:18:55 +00:00

chunker: Use polynomial functions

This commit is contained in:
Alexander Neumann 2015-04-06 20:45:06 +02:00
parent 8986c75091
commit f02865a205
2 changed files with 17 additions and 42 deletions

View File

@ -25,8 +25,8 @@ const (
)
type tables struct {
out [256]uint64
mod [256]uint64
out [256]Pol
mod [256]Pol
}
// cache precomputed tables, these are read-only anyway
@ -151,13 +151,13 @@ func (c *Chunker) fill_tables() {
//
// Afterwards a new byte can be shifted in.
for b := 0; b < 256; b++ {
var hash uint64
var h Pol
hash = append_byte(hash, byte(b), uint64(c.pol))
h = append_byte(h, byte(b), c.pol)
for i := 0; i < WindowSize-1; i++ {
hash = append_byte(hash, 0, uint64(c.pol))
h = append_byte(h, 0, c.pol)
}
c.tables.out[b] = hash
c.tables.out[b] = h
}
// calculate table for reduction mod Polynomial
@ -170,7 +170,7 @@ func (c *Chunker) fill_tables() {
// two parts: Part A contains the result of the modulus operation, part
// B is used to cancel out the 8 top bits so that one XOR operation is
// enough to reduce modulo Polynomial
c.tables.mod[b] = mod(uint64(b)<<uint(k), uint64(c.pol)) | (uint64(b) << uint(k))
c.tables.mod[b] = Pol(uint64(b)<<uint(k)).Mod(c.pol) | (Pol(b) << uint(k))
}
}
@ -245,7 +245,7 @@ func (c *Chunker) Next() (*Chunk, error) {
// inline c.slide(b) and append(b) to increase performance
out := c.window[c.wpos]
c.window[c.wpos] = b
c.digest ^= c.tables.out[out]
c.digest ^= uint64(c.tables.out[out])
c.wpos = (c.wpos + 1) % WindowSize
// c.append(b)
@ -253,7 +253,7 @@ func (c *Chunker) Next() (*Chunk, error) {
c.digest <<= 8
c.digest |= uint64(b)
c.digest ^= c.tables.mod[index]
c.digest ^= uint64(c.tables.mod[index])
// end inline
add++
@ -323,48 +323,21 @@ func (c *Chunker) append(b byte) {
c.digest <<= 8
c.digest |= uint64(b)
c.digest ^= c.tables.mod[index]
c.digest ^= uint64(c.tables.mod[index])
}
func (c *Chunker) slide(b byte) {
out := c.window[c.wpos]
c.window[c.wpos] = b
c.digest ^= c.tables.out[out]
c.digest ^= uint64(c.tables.out[out])
c.wpos = (c.wpos + 1) % WindowSize
c.append(b)
}
func append_byte(hash uint64, b byte, pol uint64) uint64 {
func append_byte(hash Pol, b byte, pol Pol) Pol {
hash <<= 8
hash |= uint64(b)
hash |= Pol(b)
return mod(hash, pol)
}
// Mod calculates the remainder of x divided by p in F_2[X].
func mod(x, p uint64) uint64 {
for deg(x) >= deg(p) {
shift := uint(deg(x) - deg(p))
x = x ^ (p << shift)
}
return x
}
// Deg returns the degree of the polynomial p, this is equivalent to the number
// of the highest bit set in p.
func deg(p uint64) int {
var mask uint64 = 0x8000000000000000
for i := 0; i < 64; i++ {
if mask&p > 0 {
return 63 - i
}
mask >>= 1
}
return -1
return hash.Mod(pol)
}

View File

@ -64,12 +64,14 @@ func (x Pol) Deg() int {
return -1
}
var mask Pol = (1 << 63)
for i := 63; i >= 0; i-- {
// test if bit i is set
if x&(1<<uint(i)) > 0 {
if x&mask > 0 {
// this is the degree of x
return i
}
mask >>= 1
}
// fall-through, return -1