Tizen_4.0 base
[platform/upstream/docker-engine.git] / vendor / github.com / resin-os / librsync-go / rollsum.go
1 package librsync
2
3 type Rollsum struct {
4         count  uint64
5         s1, s2 uint16
6 }
7
8 const ROLLSUM_CHAR_OFFSET = 31
9
10 func WeakChecksum(data []byte) uint32 {
11         var sum Rollsum
12         sum.Update(data)
13         return sum.Digest()
14 }
15
16 func NewRollsum() Rollsum {
17         return Rollsum{}
18 }
19
20 func (r *Rollsum) Update(p []byte) {
21         l := len(p)
22
23         for n := 0; n < l; {
24                 if n+15 < l {
25                         for i := 0; i < 16; i++ {
26                                 r.s1 += uint16(p[n+i])
27                                 r.s2 += r.s1
28                         }
29                         n += 16
30                 } else {
31                         r.s1 += uint16(p[n])
32                         r.s2 += r.s1
33                         n += 1
34                 }
35         }
36
37         r.s1 += uint16(l * ROLLSUM_CHAR_OFFSET)
38         r.s2 += uint16(((l * (l + 1)) / 2) * ROLLSUM_CHAR_OFFSET)
39         r.count += uint64(l)
40 }
41
42 func (r *Rollsum) Rotate(out, in byte) {
43         r.s1 += uint16(in - out)
44         r.s2 += r.s1 - uint16(r.count)*(uint16(out)+uint16(ROLLSUM_CHAR_OFFSET))
45 }
46
47 func (r *Rollsum) Rollin(in byte) {
48         r.s1 += uint16(in) + uint16(ROLLSUM_CHAR_OFFSET)
49         r.s2 += r.s1
50         r.count += 1
51 }
52
53 func (r *Rollsum) Rollout(out byte) {
54         r.s1 -= uint16(out) + uint16(ROLLSUM_CHAR_OFFSET)
55         r.s2 -= uint16(r.count) * (uint16(out) + uint16(ROLLSUM_CHAR_OFFSET))
56         r.count -= 1
57 }
58
59 func (r *Rollsum) Digest() uint32 {
60         return (uint32(r.s2) << 16) | (uint32(r.s1) & 0xffff)
61 }
62
63 func (r *Rollsum) Reset() {
64         r.count = 0
65         r.s1 = 0
66         r.s2 = 0
67 }