Make chunker resettable

This commit is contained in:
Alexander Neumann 2015-02-09 23:37:33 +01:00
parent bda33e612c
commit 3daeee8e2c
2 changed files with 18 additions and 12 deletions

View file

@ -77,14 +77,17 @@ func New(rd io.Reader, bufsize int, hashfn func() hash.Hash) *Chunker {
c := &Chunker{ c := &Chunker{
buf: make([]byte, bufsize), buf: make([]byte, bufsize),
hfn: hashfn, hfn: hashfn,
rd: rd,
} }
c.reset() c.Reset(rd)
return c return c
} }
func (c *Chunker) reset() { // Reset restarts a chunker so that it can be reused with a different reader as
// the source.
func (c *Chunker) Reset(rd io.Reader) {
c.rd = rd
for i := 0; i < WindowSize; i++ { for i := 0; i < WindowSize; i++ {
c.window[i] = 0 c.window[i] = 0
} }
@ -92,6 +95,7 @@ func (c *Chunker) reset() {
c.digest = 0 c.digest = 0
c.wpos = 0 c.wpos = 0
c.pos = 0 c.pos = 0
c.start = 0
c.count = 0 c.count = 0
c.slide(1) c.slide(1)
@ -230,9 +234,9 @@ func (c *Chunker) Next() (*Chunk, error) {
c.resetHash() c.resetHash()
// keep position // reset chunker, but keep position
pos := c.pos pos := c.pos
c.reset() c.Reset(c.rd)
c.pos = pos c.pos = pos
c.start = pos c.start = pos
c.pre = MinSize - WindowSize c.pre = MinSize - WindowSize

View file

@ -91,22 +91,22 @@ func test_with_data(t *testing.T, chnker *chunker.Chunker, testChunks []chunk) [
if c != nil { if c != nil {
if c.Start != pos { if c.Start != pos {
t.Fatalf("Start for chunk %d does not match: expected %d, got %d", t.Fatalf("Start for chunk %d does not match: expected %d, got %d",
i, c.Start, pos) i, pos, c.Start)
} }
if c.Length != chunk.Length { if c.Length != chunk.Length {
t.Fatalf("Length for chunk %d does not match: expected %d, got %d", t.Fatalf("Length for chunk %d does not match: expected %d, got %d",
i, c.Length, chunk.Length) i, chunk.Length, c.Length)
} }
if c.Cut != chunk.CutFP { if c.Cut != chunk.CutFP {
t.Fatalf("Cut fingerprint for chunk %d/%d does not match: expected %016x, got %016x", t.Fatalf("Cut fingerprint for chunk %d/%d does not match: expected %016x, got %016x",
i, len(chunks)-1, c.Cut, chunk.CutFP) i, len(chunks)-1, chunk.CutFP, c.Cut)
} }
if !bytes.Equal(c.Digest, chunk.Digest) { if !bytes.Equal(c.Digest, chunk.Digest) {
t.Fatalf("Digest fingerprint for chunk %d/%d does not match: expected %q, got %q", t.Fatalf("Digest fingerprint for chunk %d/%d does not match: expected %02x, got %02x",
i, len(chunks)-1, hex.EncodeToString(c.Digest), hex.EncodeToString(chunk.Digest)) i, len(chunks)-1, chunk.Digest, c.Digest)
} }
pos += c.Length pos += c.Length
@ -179,9 +179,11 @@ func TestChunker(t *testing.T) {
func TestChunkerReuse(t *testing.T) { func TestChunkerReuse(t *testing.T) {
// test multiple uses of the same chunker // test multiple uses of the same chunker
for i := 0; i < 4; i++ { ch := chunker.New(nil, *testBufSize, sha256.New)
buf := get_random(23, 32*1024*1024) buf := get_random(23, 32*1024*1024)
ch := chunker.New(bytes.NewReader(buf), *testBufSize, sha256.New)
for i := 0; i < 4; i++ {
ch.Reset(bytes.NewReader(buf))
test_with_data(t, ch, chunks1) test_with_data(t, ch, chunks1)
} }
} }