main pico / pkg / rsync-receiver / rsynccommon / rsynccommon.go
Eric Bower  ·  2026-05-31
 1// Package rsynccommon contains functionality that both the sender and the
 2// receiver implementation need.
 3package rsynccommon
 4
 5import (
 6	"math"
 7
 8	"github.com/picosh/pico/pkg/rsync-receiver/rsync"
 9)
10
11const blockSize = 700 // rsync/rsync.h
12
13// Corresponds to rsync/generator.c:sum_sizes_sqroot.
14func SumSizesSqroot(contentLen int64) rsync.SumHead {
15	// * The block size is a rounded square root of file length.
16
17	// 	The block size algorithm plays a crucial role in the protocol efficiency. In general, the block size is the rounded square root of the total file size. The minimum block size, however, is 700 B. Otherwise, the square root computation is simply sqrt(3) followed by ceil(3)
18
19	// For reasons unknown, the square root result is rounded up to the nearest multiple of eight.
20
21	// TODO: round this
22	blockLength := max(int32(math.Sqrt(float64(contentLen))), blockSize)
23
24	// * The checksum size is determined according to:
25	// *     blocksum_bits = BLOCKSUM_EXP + 2*log2(file_len) - log2(block_len)
26	// * provided by Donovan Baarda which gives a probability of rsync
27	// * algorithm corrupting data and falling back using the whole md4
28	// * checksums.
29	const checksumLength = 16 // TODO?
30
31	return rsync.SumHead{
32		ChecksumCount:   int32((contentLen + (int64(blockLength) - 1)) / int64(blockLength)),
33		RemainderLength: int32(contentLen % int64(blockLength)),
34		BlockLength:     blockLength,
35		ChecksumLength:  checksumLength,
36	}
37}