github.com/sabhiram/gsync@v0.0.0-20180214150410-b9089a1b7f13/gsync.go (about) 1 // This Source Code Form is subject to the terms of the Mozilla Public 2 // License, version 2.0. If a copy of the MPL was not distributed with this 3 // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5 // Package gsync implements a rsync-based algorithm for sending delta updates to a remote server. 6 package gsync 7 8 import "sync" 9 10 const ( 11 // DefaultBlockSize is the default block size. 12 DefaultBlockSize = 6 * 1024 // 6kb 13 ) 14 15 // Rolling checksum is up to 16 bit length for simplicity and speed. 16 const ( 17 mod = 1 << 16 18 ) 19 20 // rollingHash as defined in https://www.samba.org/~tridge/phd_thesis.pdf, based on Adler-32 21 // Calculates the hash for an entire block. 22 func rollingHash(block []byte) (uint32, uint32, uint32) { 23 var a, b uint32 24 l := uint32(len(block)) 25 for index, value := range block { 26 a += uint32(value) 27 b += (l - uint32(index)) * uint32(value) 28 } 29 r1 := a % mod 30 r2 := b % mod 31 r := r1 + (mod * r2) 32 33 return r1, r2, r 34 } 35 36 // rollingHash2 incrementally calculates rolling checksum. 37 func rollingHash2(l, r1, r2, outgoingValue, incomingValue uint32) (uint32, uint32, uint32) { 38 r1 = (r1 - outgoingValue + incomingValue) % mod 39 r2 = (r2 - (l * outgoingValue) + r1) % mod 40 r := r1 + (mod * r2) 41 42 return r1, r2, r 43 } 44 45 // BlockSignature contains file block index and checksums. 46 type BlockSignature struct { 47 // Index is the block index 48 Index uint64 49 // Strong refers to the strong checksum, it need not to be cryptographic. 50 Strong []byte 51 // Weak refers to the fast rsync rolling checksum 52 Weak uint32 53 // Error is used to report the error reading the file or calculating checksums. 54 Error error 55 } 56 57 // BlockOperation represents a file re-construction instruction. 58 type BlockOperation struct { 59 // Index is the block index involved. 60 Index uint64 61 // Data is the delta to be applied to the remote file. No data means 62 // the client found a matching checksum for this block, which in turn means 63 // the remote end proceeds to get the block data from its local 64 // copy instead. 65 Data []byte 66 // Error is used to report any error while sending operations. 67 Error error 68 } 69 70 var bufferPool = sync.Pool{ 71 New: func() interface{} { 72 b := make([]byte, DefaultBlockSize) 73 return &b 74 }, 75 }