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  }