2
2
mirror of https://github.com/octoleo/restic.git synced 2024-11-26 14:56:29 +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 { type tables struct {
out [256]uint64 out [256]Pol
mod [256]uint64 mod [256]Pol
} }
// cache precomputed tables, these are read-only anyway // 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. // Afterwards a new byte can be shifted in.
for b := 0; b < 256; b++ { 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++ { 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 // 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 // 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 // B is used to cancel out the 8 top bits so that one XOR operation is
// enough to reduce modulo Polynomial // 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 // inline c.slide(b) and append(b) to increase performance
out := c.window[c.wpos] out := c.window[c.wpos]
c.window[c.wpos] = b 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.wpos = (c.wpos + 1) % WindowSize
// c.append(b) // c.append(b)
@ -253,7 +253,7 @@ func (c *Chunker) Next() (*Chunk, error) {
c.digest <<= 8 c.digest <<= 8
c.digest |= uint64(b) c.digest |= uint64(b)
c.digest ^= c.tables.mod[index] c.digest ^= uint64(c.tables.mod[index])
// end inline // end inline
add++ add++
@ -323,48 +323,21 @@ func (c *Chunker) append(b byte) {
c.digest <<= 8 c.digest <<= 8
c.digest |= uint64(b) c.digest |= uint64(b)
c.digest ^= c.tables.mod[index] c.digest ^= uint64(c.tables.mod[index])
} }
func (c *Chunker) slide(b byte) { func (c *Chunker) slide(b byte) {
out := c.window[c.wpos] out := c.window[c.wpos]
c.window[c.wpos] = b 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.wpos = (c.wpos + 1) % WindowSize
c.append(b) 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 <<= 8
hash |= uint64(b) hash |= Pol(b)
return mod(hash, pol) return hash.Mod(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
} }

View File

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