mirror of https://github.com/perkeep/perkeep.git
55 lines
1.3 KiB
Go
55 lines
1.3 KiB
Go
/*
|
|
Copyright 2011 Google Inc.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
// Package rollsum implements rolling checksums similar to apenwarr's bup, which
|
|
// is similar to librsync.
|
|
package rollsum
|
|
|
|
import (
|
|
|
|
)
|
|
|
|
const windowSize = 64
|
|
const charOffset = 31
|
|
|
|
type RollSum struct {
|
|
s1, s2 uint32
|
|
window [windowSize]uint8
|
|
wofs int
|
|
}
|
|
|
|
func NewRollSum() *RollSum {
|
|
return &RollSum{
|
|
s1: windowSize * charOffset,
|
|
s2: windowSize * (windowSize - 1) * charOffset,
|
|
}
|
|
}
|
|
|
|
func (rs *RollSum) add(drop, add uint8) {
|
|
rs.s1 += uint32(add) - uint32(drop)
|
|
rs.s2 += rs.s1 - uint32(windowSize) * uint32(drop + charOffset)
|
|
}
|
|
|
|
func (rs *RollSum) Roll(ch byte) {
|
|
rs.add(rs.window[rs.wofs], ch)
|
|
rs.window[rs.wofs] = ch
|
|
rs.wofs = (rs.wofs + 1) % windowSize
|
|
}
|
|
|
|
func (rs *RollSum) Digest() uint32 {
|
|
return (rs.s1 << 16) | (rs.s2 & 0xffff)
|
|
}
|