rabin.go 1.2 KB
Newer Older
1 2 3
package chunk

import (
4
	"hash/fnv"
5
	"io"
6

7
	"github.com/whyrusleeping/chunker"
8 9
)

tavit ohanian's avatar
tavit ohanian committed
10 11
// Dms3RabinPoly is the irreducible polynomial of degree 53 used by for Rabin.
var Dms3RabinPoly = chunker.Pol(17437180132763653)
12

13 14
// Rabin implements the Splitter interface and splits content with Rabin
// fingerprints.
15
type Rabin struct {
16 17
	r      *chunker.Chunker
	reader io.Reader
18 19
}

20 21
// NewRabin creates a new Rabin splitter with the given
// average block size.
22 23 24
func NewRabin(r io.Reader, avgBlkSize uint64) *Rabin {
	min := avgBlkSize / 3
	max := avgBlkSize + (avgBlkSize / 2)
25

26
	return NewRabinMinMax(r, min, avgBlkSize, max)
27
}
28

29 30
// NewRabinMinMax returns a new Rabin splitter which uses
// the given min, average and max block sizes.
31 32
func NewRabinMinMax(r io.Reader, min, avg, max uint64) *Rabin {
	h := fnv.New32a()
tavit ohanian's avatar
tavit ohanian committed
33
	ch := chunker.New(r, Dms3RabinPoly, h, avg, min, max)
34

35
	return &Rabin{
36 37
		r:      ch,
		reader: r,
38 39
	}
}
40

41
// NextBytes reads the next bytes from the reader and returns a slice.
42 43 44 45 46
func (r *Rabin) NextBytes() ([]byte, error) {
	ch, err := r.r.Next()
	if err != nil {
		return nil, err
	}
47

48
	return ch.Data, nil
49
}
50

51
// Reader returns the io.Reader associated to this Splitter.
52 53 54
func (r *Rabin) Reader() io.Reader {
	return r.reader
}