diff --git a/buzhash.go b/buzhash.go index 099b723b183c3cf2d6ddf4d3b197bebfb1b59cad..1a9b747de978d0a51f867d8efe0ea35a6db51614 100644 --- a/buzhash.go +++ b/buzhash.go @@ -40,14 +40,16 @@ func (b *Buzhash) NextBytes() ([]byte, error) { buf := b.buf n, err := io.ReadFull(b.r, buf[b.n:]) if err != nil { - if err == io.ErrUnexpectedEOF { - b.err = io.EOF - res := make([]byte, n+b.n) - copy(res, buf) - - pool.Put(b.buf) - b.buf = nil - return res, nil + if err == io.ErrUnexpectedEOF || err == io.EOF { + if b.n+n < buzMin { + b.err = io.EOF + res := make([]byte, b.n+n) + copy(res, buf) + + pool.Put(b.buf) + b.buf = nil + return res, nil + } } else { b.err = err pool.Put(buf) @@ -65,14 +67,18 @@ func (b *Buzhash) NextBytes() ([]byte, error) { state = state ^ bytehash[buf[i]] } - for ; state&buzMask != 0 && i < buzMax; i++ { + if b.n+n > len(buf) { + panic("this is impossible, but gives +9 to performance") + } + + for ; state&buzMask != 0 && i < b.n+n; i++ { state = bits.RotateLeft32(state, 1) ^ bytehash[buf[i-32]] ^ bytehash[buf[i]] } res := make([]byte, i) copy(res, b.buf) - b.n = copy(b.buf, buf[i:]) + b.n = copy(b.buf, buf[i:b.n+n]) return res, nil } diff --git a/buzhash_test.go b/buzhash_test.go index 6e59d6be8c98c337ffed7133ea1ae6aedae33473..f630cef89b77afbaf8cc31e33730336c8d157308 100644 --- a/buzhash_test.go +++ b/buzhash_test.go @@ -53,7 +53,7 @@ func BenchmarkBuzhash2(b *testing.B) { }) } -func TestBuzhashBitsHash(t *testing.T) { +func TestBuzhashBitsHashBias(t *testing.T) { counts := make([]byte, 32) for _, h := range bytehash { for i := 0; i < 32; i++ {