master
go 39 lines 1.55 KB
Raw
1 package testutils
2
3 import "math/bits"
4
5 // VarintLen returns the number of bytes needed to encode v as a protobuf varint.
6 func VarintLen(v uint64) int {
7 return int(9*uint32(bits.Len64(v))+64) / 64
8 }
9
10 // LinkSerializedSize calculates the serialized size of a single PBLink in a dag-pb block.
11 // This matches the calculation in boxo/ipld/unixfs/io/directory.go estimatedBlockSize().
12 //
13 // The protobuf wire format for a PBLink is:
14 //
15 // PBNode.Links wrapper tag (1 byte)
16 // + varint length of inner message
17 // + Hash field: tag (1) + varint(cidLen) + cidLen
18 // + Name field: tag (1) + varint(nameLen) + nameLen
19 // + Tsize field: tag (1) + varint(tsize)
20 func LinkSerializedSize(nameLen, cidLen int, tsize uint64) int {
21 // Inner link message size
22 linkLen := 1 + VarintLen(uint64(cidLen)) + cidLen + // Hash field
23 1 + VarintLen(uint64(nameLen)) + nameLen + // Name field
24 1 + VarintLen(tsize) // Tsize field
25
26 // Outer wrapper: tag (1 byte) + varint(linkLen) + linkLen
27 return 1 + VarintLen(uint64(linkLen)) + linkLen
28 }
29
30 // EstimateFilesForBlockThreshold estimates how many files with given name/cid lengths
31 // will fit under the block size threshold.
32 // Returns the number of files that keeps the block size just under the threshold.
33 func EstimateFilesForBlockThreshold(threshold, nameLen, cidLen int, tsize uint64) int {
34 linkSize := LinkSerializedSize(nameLen, cidLen, tsize)
35 // Base overhead for empty directory node (Data field + minimal structure)
36 // Empirically determined to be 4 bytes for dag-pb directories
37 baseOverhead := 4
38 return (threshold - baseOverhead) / linkSize
39 }