aboutsummaryrefslogtreecommitdiff
path: root/src/zenremotestore/chunking/chunkblock.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/zenremotestore/chunking/chunkblock.cpp')
-rw-r--r--src/zenremotestore/chunking/chunkblock.cpp84
1 files changed, 42 insertions, 42 deletions
diff --git a/src/zenremotestore/chunking/chunkblock.cpp b/src/zenremotestore/chunking/chunkblock.cpp
index 0fe3c09ce..8b9d5474a 100644
--- a/src/zenremotestore/chunking/chunkblock.cpp
+++ b/src/zenremotestore/chunking/chunkblock.cpp
@@ -1214,7 +1214,7 @@ namespace chunkblock_analyser_testutils {
// Build a ChunkBlockDescription without any real payload.
// Hashes are derived deterministically from (BlockSeed XOR ChunkIndex) so that the same
- // seed produces the same hashes — useful for deduplication tests.
+ // seed produces the same hashes - useful for deduplication tests.
static ChunkBlockDescription MakeBlockDesc(uint64_t HeaderSize,
std::initializer_list<uint32_t> CompressedLengths,
uint32_t BlockSeed = 0)
@@ -1257,7 +1257,7 @@ namespace chunkblock_analyser_testutils {
TEST_CASE("chunkblock.mergecheapestrange.picks_smallest_gap")
{
using RD = chunkblock_impl::RangeDescriptor;
- // Gap between ranges 0-1 is 50, gap between 1-2 is 150 → pair 0-1 gets merged
+ // Gap between ranges 0-1 is 50, gap between 1-2 is 150 -> pair 0-1 gets merged
std::vector<RD> Ranges = {
{.RangeStart = 0, .RangeLength = 100, .ChunkBlockIndexStart = 0, .ChunkBlockIndexCount = 1},
{.RangeStart = 150, .RangeLength = 100, .ChunkBlockIndexStart = 1, .ChunkBlockIndexCount = 1},
@@ -1279,7 +1279,7 @@ TEST_CASE("chunkblock.mergecheapestrange.picks_smallest_gap")
TEST_CASE("chunkblock.mergecheapestrange.tiebreak_smaller_merged")
{
using RD = chunkblock_impl::RangeDescriptor;
- // Gap 0-1 == gap 1-2 == 100; merged size 0-1 (250) < merged size 1-2 (350) → pair 0-1 wins
+ // Gap 0-1 == gap 1-2 == 100; merged size 0-1 (250) < merged size 1-2 (350) -> pair 0-1 wins
std::vector<RD> Ranges = {
{.RangeStart = 0, .RangeLength = 100, .ChunkBlockIndexStart = 0, .ChunkBlockIndexCount = 1},
{.RangeStart = 200, .RangeLength = 50, .ChunkBlockIndexStart = 1, .ChunkBlockIndexCount = 1},
@@ -1304,7 +1304,7 @@ TEST_CASE("chunkblock.optimizeranges.preserves_ranges_low_latency")
{
using RD = chunkblock_impl::RangeDescriptor;
// With MaxRangeCountPerRequest unlimited, RequestCount=1
- // RequestTimeAsBytes = 100000 * 1 * 0.001 = 100 << slack=7000 → all ranges preserved
+ // RequestTimeAsBytes = 100000 * 1 * 0.001 = 100 << slack=7000 -> all ranges preserved
std::vector<RD> ExactRanges = {
{.RangeStart = 0, .RangeLength = 1000, .ChunkBlockIndexStart = 0, .ChunkBlockIndexCount = 1},
{.RangeStart = 2000, .RangeLength = 1000, .ChunkBlockIndexStart = 1, .ChunkBlockIndexCount = 1},
@@ -1325,7 +1325,7 @@ TEST_CASE("chunkblock.optimizeranges.preserves_ranges_low_latency")
TEST_CASE("chunkblock.optimizeranges.falls_back_to_full_block")
{
using RD = chunkblock_impl::RangeDescriptor;
- // 1 range already; slack=100 < SpeedBytesPerSec*LatencySec=200 → full block (empty result)
+ // 1 range already; slack=100 < SpeedBytesPerSec*LatencySec=200 -> full block (empty result)
std::vector<RD> ExactRanges = {
{.RangeStart = 100, .RangeLength = 900, .ChunkBlockIndexStart = 0, .ChunkBlockIndexCount = 3},
};
@@ -1344,7 +1344,7 @@ TEST_CASE("chunkblock.optimizeranges.falls_back_to_full_block")
TEST_CASE("chunkblock.optimizeranges.maxrangesperblock_clamp")
{
using RD = chunkblock_impl::RangeDescriptor;
- // 5 input ranges; MaxRangesPerBlock=2 clamps to ≤2 before the cost model runs
+ // 5 input ranges; MaxRangesPerBlock=2 clamps to <=2 before the cost model runs
std::vector<RD> ExactRanges = {
{.RangeStart = 0, .RangeLength = 100, .ChunkBlockIndexStart = 0, .ChunkBlockIndexCount = 1},
{.RangeStart = 300, .RangeLength = 100, .ChunkBlockIndexStart = 1, .ChunkBlockIndexCount = 1},
@@ -1378,8 +1378,8 @@ TEST_CASE("chunkblock.optimizeranges.low_maxrangecountperrequest_drives_merge")
uint64_t TotalBlockSize = 1000;
double LatencySec = 1.0;
uint64_t SpeedBytesPerSec = 500;
- // With MaxRangeCountPerRequest=-1: RequestCount=1, RequestTimeAsBytes=500 < slack=700 → preserved
- // With MaxRangeCountPerRequest=1: RequestCount=3, RequestTimeAsBytes=1500 > slack=700 → merged
+ // With MaxRangeCountPerRequest=-1: RequestCount=1, RequestTimeAsBytes=500 < slack=700 -> preserved
+ // With MaxRangeCountPerRequest=1: RequestCount=3, RequestTimeAsBytes=1500 > slack=700 -> merged
uint64_t MaxRangesPerBlock = 1024;
auto Unlimited =
@@ -1394,7 +1394,7 @@ TEST_CASE("chunkblock.optimizeranges.low_maxrangecountperrequest_drives_merge")
TEST_CASE("chunkblock.optimizeranges.unlimited_rangecountperrequest_no_extra_cost")
{
using RD = chunkblock_impl::RangeDescriptor;
- // MaxRangeCountPerRequest=-1 → RequestCount always 1, even with many ranges and high latency
+ // MaxRangeCountPerRequest=-1 -> RequestCount always 1, even with many ranges and high latency
std::vector<RD> ExactRanges = {
{.RangeStart = 0, .RangeLength = 50, .ChunkBlockIndexStart = 0, .ChunkBlockIndexCount = 1},
{.RangeStart = 200, .RangeLength = 50, .ChunkBlockIndexStart = 1, .ChunkBlockIndexCount = 1},
@@ -1418,7 +1418,7 @@ TEST_CASE("chunkblock.optimizeranges.two_range_direct_merge_path")
{
using RD = chunkblock_impl::RangeDescriptor;
// Exactly 2 ranges; cost model demands merge; exercises the RangeCount==2 direct-merge branch
- // After direct merge → 1 range with small slack → full block (empty)
+ // After direct merge -> 1 range with small slack -> full block (empty)
std::vector<RD> ExactRanges = {
{.RangeStart = 0, .RangeLength = 100, .ChunkBlockIndexStart = 0, .ChunkBlockIndexCount = 2},
{.RangeStart = 400, .RangeLength = 100, .ChunkBlockIndexStart = 2, .ChunkBlockIndexCount = 2},
@@ -1429,8 +1429,8 @@ TEST_CASE("chunkblock.optimizeranges.two_range_direct_merge_path")
uint64_t MaxRangeCountPerReq = (uint64_t)-1;
uint64_t MaxRangesPerBlock = 1024;
- // Iteration 1: RangeCount=2, RequestCount=1, RequestTimeAsBytes=500 > slack=400 → direct merge
- // After merge: 1 range [{0,500,0,4}], slack=100 < Speed*Lat=500 → full block
+ // Iteration 1: RangeCount=2, RequestCount=1, RequestTimeAsBytes=500 > slack=400 -> direct merge
+ // After merge: 1 range [{0,500,0,4}], slack=100 < Speed*Lat=500 -> full block
auto Result =
chunkblock_impl::OptimizeRanges(TotalBlockSize, ExactRanges, LatencySec, SpeedBytesPerSec, MaxRangeCountPerReq, MaxRangesPerBlock);
@@ -1506,9 +1506,9 @@ TEST_CASE("chunkblock.getneeded.dedup_low_slack_wins")
LoggerRef LogRef = Log();
std::unique_ptr<OperationLogOutput> LogOutput(CreateStandardLogOutput(LogRef));
- // Block 0: {H0, H1, SharedH, H3} — 3 of 4 needed (H3 not needed); slack = 100
- // Block 1: {H4, H5, SharedH, H6} — only SharedH needed; slack = 300
- // Block 0 has less slack → processed first → SharedH assigned to block 0
+ // Block 0: {H0, H1, SharedH, H3} - 3 of 4 needed (H3 not needed); slack = 100
+ // Block 1: {H4, H5, SharedH, H6} - only SharedH needed; slack = 300
+ // Block 0 has less slack -> processed first -> SharedH assigned to block 0
IoHash SharedH = IoHash::HashBuffer(MemoryView("shared_chunk_dedup", 18));
IoHash H0 = IoHash::HashBuffer(MemoryView("block0_chunk0", 13));
IoHash H1 = IoHash::HashBuffer(MemoryView("block0_chunk1", 13));
@@ -1533,7 +1533,7 @@ TEST_CASE("chunkblock.getneeded.dedup_low_slack_wins")
ChunkBlockAnalyser::Options Options;
ChunkBlockAnalyser Analyser(*LogOutput, Blocks, Options);
- // Map: H0→0, H1→1, SharedH→2, H3→3, H4→4, H5→5, H6→6
+ // Map: H0->0, H1->1, SharedH->2, H3->3, H4->4, H5->5, H6->6
auto HashMap = MakeHashMap(Blocks);
// Need H0(0), H1(1), SharedH(2) from block 0; SharedH from block 1 (already index 2)
// H3(3) not needed; H4,H5,H6 not needed
@@ -1541,7 +1541,7 @@ TEST_CASE("chunkblock.getneeded.dedup_low_slack_wins")
// Block 0 slack=100 (H3 unused), block 1 slack=300 (H4,H5,H6 unused)
// Block 0 processed first; picks up H0, H1, SharedH
- // Block 1 tries SharedH but it's already picked up → empty → not added
+ // Block 1 tries SharedH but it's already picked up -> empty -> not added
REQUIRE_EQ(1u, NeededBlocks.size());
CHECK_EQ(0u, NeededBlocks[0].BlockIndex);
REQUIRE_EQ(3u, NeededBlocks[0].ChunkIndexes.size());
@@ -1580,14 +1580,14 @@ TEST_CASE("chunkblock.getneeded.dedup_no_double_pickup")
ChunkBlockAnalyser::Options Options;
ChunkBlockAnalyser Analyser(*LogOutput, Blocks, Options);
- // Map: SharedH→0, H0→1, H1→2, H2→3, H3→4
+ // Map: SharedH->0, H0->1, H1->2, H2->3, H3->4
// Only SharedH (index 0) needed; no other chunks
auto HashMap = MakeHashMap(Blocks);
auto NeededBlocks = Analyser.GetNeeded(HashMap, [](uint32_t ChunkIndex) { return ChunkIndex == 0; });
- // Block 0: SharedH needed, H0 not needed → slack=100
- // Block 1: SharedH needed, H1/H2/H3 not needed → slack=300
- // Block 0 processed first → picks up SharedH; Block 1 skips it
+ // Block 0: SharedH needed, H0 not needed -> slack=100
+ // Block 1: SharedH needed, H1/H2/H3 not needed -> slack=300
+ // Block 0 processed first -> picks up SharedH; Block 1 skips it
// Count total occurrences of SharedH across all NeededBlocks
uint32_t SharedOccurrences = 0;
@@ -1612,7 +1612,7 @@ TEST_CASE("chunkblock.getneeded.skips_unrequested_chunks")
LoggerRef LogRef = Log();
std::unique_ptr<OperationLogOutput> LogOutput(CreateStandardLogOutput(LogRef));
- // Block has 4 chunks but only 2 appear in the hash map → ChunkIndexes has exactly those 2
+ // Block has 4 chunks but only 2 appear in the hash map -> ChunkIndexes has exactly those 2
auto Block = MakeBlockDesc(50, {100, 100, 100, 100});
ChunkBlockAnalyser::Options Options;
ChunkBlockAnalyser Analyser(*LogOutput, std::span<const ChunkBlockDescription>(&Block, 1), Options);
@@ -1639,7 +1639,7 @@ TEST_CASE("chunkblock.getneeded.two_blocks_both_contribute")
std::unique_ptr<OperationLogOutput> LogOutput(CreateStandardLogOutput(LogRef));
// Block 0: all 4 needed (slack=0); block 1: 3 of 4 needed (slack=100)
- // Both blocks contribute chunks → 2 NeededBlocks in result
+ // Both blocks contribute chunks -> 2 NeededBlocks in result
auto Block0 = MakeBlockDesc(50, {100, 100, 100, 100}, /*BlockSeed=*/0);
auto Block1 = MakeBlockDesc(50, {100, 100, 100, 100}, /*BlockSeed=*/200);
@@ -1647,7 +1647,7 @@ TEST_CASE("chunkblock.getneeded.two_blocks_both_contribute")
ChunkBlockAnalyser::Options Options;
ChunkBlockAnalyser Analyser(*LogOutput, Blocks, Options);
- // HashMap: Block0 hashes → indices 0-3, Block1 hashes → indices 4-7
+ // HashMap: Block0 hashes -> indices 0-3, Block1 hashes -> indices 4-7
auto HashMap = MakeHashMap(Blocks);
// Need all Block0 chunks (0-3) and Block1 chunks 0-2 (indices 4-6); not chunk index 7 (Block1 chunk 3)
auto NeededBlocks = Analyser.GetNeeded(HashMap, [](uint32_t ChunkIndex) { return ChunkIndex <= 6; });
@@ -1669,7 +1669,7 @@ TEST_CASE("chunkblock.calc.off_mode")
LoggerRef LogRef = Log();
std::unique_ptr<OperationLogOutput> LogOutput(CreateStandardLogOutput(LogRef));
- // HeaderSize > 0, chunks size matches → CanDoPartialBlockDownload = true
+ // HeaderSize > 0, chunks size matches -> CanDoPartialBlockDownload = true
// But mode Off forces full block regardless
auto Block = MakeBlockDesc(50, {100, 200, 300, 400});
ChunkBlockAnalyser::Options Options;
@@ -1701,7 +1701,7 @@ TEST_CASE("chunkblock.calc.exact_mode")
uint64_t ChunkStartOffset = CompressedBuffer::GetHeaderSizeForNoneEncoder() + Block.HeaderSize;
- // Need chunks 0 and 2 → 2 non-contiguous ranges; Exact mode passes them straight through
+ // Need chunks 0 and 2 -> 2 non-contiguous ranges; Exact mode passes them straight through
std::vector<ChunkBlockAnalyser::NeededBlock> NeededBlocks = {{.BlockIndex = 0, .ChunkIndexes = {0, 2}}};
std::vector<Mode> Modes = {Mode::Exact};
@@ -1732,14 +1732,14 @@ TEST_CASE("chunkblock.calc.singlerange_mode")
std::unique_ptr<OperationLogOutput> LogOutput(CreateStandardLogOutput(LogRef));
auto Block = MakeBlockDesc(50, {100, 200, 300, 400});
- // Default HostLatencySec=-1 → OptimizeRanges not called after SingleRange collapse
+ // Default HostLatencySec=-1 -> OptimizeRanges not called after SingleRange collapse
ChunkBlockAnalyser::Options Options;
Options.IsQuiet = true;
ChunkBlockAnalyser Analyser(*LogOutput, std::span<const ChunkBlockDescription>(&Block, 1), Options);
uint64_t ChunkStartOffset = CompressedBuffer::GetHeaderSizeForNoneEncoder() + Block.HeaderSize;
- // Need chunks 0 and 2 → 2 ranges that get collapsed to 1
+ // Need chunks 0 and 2 -> 2 ranges that get collapsed to 1
std::vector<ChunkBlockAnalyser::NeededBlock> NeededBlocks = {{.BlockIndex = 0, .ChunkIndexes = {0, 2}}};
std::vector<Mode> Modes = {Mode::SingleRange};
@@ -1765,7 +1765,7 @@ TEST_CASE("chunkblock.calc.multirange_mode")
std::unique_ptr<OperationLogOutput> LogOutput(CreateStandardLogOutput(LogRef));
auto Block = MakeBlockDesc(50, {100, 200, 300, 400});
- // Low latency: RequestTimeAsBytes=100 << slack → OptimizeRanges preserves ranges
+ // Low latency: RequestTimeAsBytes=100 << slack -> OptimizeRanges preserves ranges
ChunkBlockAnalyser::Options Options;
Options.IsQuiet = true;
Options.HostLatencySec = 0.001;
@@ -1796,8 +1796,8 @@ TEST_CASE("chunkblock.calc.multirangehighspeed_mode")
std::unique_ptr<OperationLogOutput> LogOutput(CreateStandardLogOutput(LogRef));
auto Block = MakeBlockDesc(50, {100, 200, 300, 400});
- // Block slack ≈ 714 bytes (TotalBlockSize≈1114, RangeTotalSize=400 for chunks 0+2)
- // RequestTimeAsBytes = 400000 * 1 * 0.001 = 400 < 714 → ranges preserved
+ // Block slack ~= 714 bytes (TotalBlockSize~=1114, RangeTotalSize=400 for chunks 0+2)
+ // RequestTimeAsBytes = 400000 * 1 * 0.001 = 400 < 714 -> ranges preserved
ChunkBlockAnalyser::Options Options;
Options.IsQuiet = true;
Options.HostHighSpeedLatencySec = 0.001;
@@ -1834,7 +1834,7 @@ TEST_CASE("chunkblock.calc.all_chunks_needed_full_block")
Options.HostSpeedBytesPerSec = 100000;
ChunkBlockAnalyser Analyser(*LogOutput, std::span<const ChunkBlockDescription>(&Block, 1), Options);
- // All 4 chunks needed → short-circuit to full block regardless of mode
+ // All 4 chunks needed -> short-circuit to full block regardless of mode
std::vector<ChunkBlockAnalyser::NeededBlock> NeededBlocks = {{.BlockIndex = 0, .ChunkIndexes = {0, 1, 2, 3}}};
std::vector<Mode> Modes = {Mode::Exact};
@@ -1853,7 +1853,7 @@ TEST_CASE("chunkblock.calc.headersize_zero_forces_full_block")
LoggerRef LogRef = Log();
std::unique_ptr<OperationLogOutput> LogOutput(CreateStandardLogOutput(LogRef));
- // HeaderSize=0 → CanDoPartialBlockDownload=false → full block even in Exact mode
+ // HeaderSize=0 -> CanDoPartialBlockDownload=false -> full block even in Exact mode
auto Block = MakeBlockDesc(0, {100, 200, 300, 400});
ChunkBlockAnalyser::Options Options;
Options.IsQuiet = true;
@@ -1877,8 +1877,8 @@ TEST_CASE("chunkblock.calc.low_maxrangecountperrequest")
LoggerRef LogRef = Log();
std::unique_ptr<OperationLogOutput> LogOutput(CreateStandardLogOutput(LogRef));
- // 5 chunks of 100 bytes each; need chunks 0, 2, 4 → 3 non-contiguous ranges
- // With MaxRangeCountPerRequest=1 and high latency, cost model merges aggressively → full block
+ // 5 chunks of 100 bytes each; need chunks 0, 2, 4 -> 3 non-contiguous ranges
+ // With MaxRangeCountPerRequest=1 and high latency, cost model merges aggressively -> full block
auto Block = MakeBlockDesc(10, {100, 100, 100, 100, 100});
ChunkBlockAnalyser::Options Options;
Options.IsQuiet = true;
@@ -1892,7 +1892,7 @@ TEST_CASE("chunkblock.calc.low_maxrangecountperrequest")
auto Result = Analyser.CalculatePartialBlockDownloads(NeededBlocks, Modes);
- // Cost model drives merging: 3 requests × 1000 × 0.1 = 300 > slack ≈ 210+headersize
+ // Cost model drives merging: 3 requests x 1000 x 0.1 = 300 > slack ~= 210+headersize
// After merges converges to full block
REQUIRE_EQ(1u, Result.FullBlockIndexes.size());
CHECK_EQ(0u, Result.FullBlockIndexes[0]);
@@ -1908,7 +1908,7 @@ TEST_CASE("chunkblock.calc.no_latency_skips_optimize")
std::unique_ptr<OperationLogOutput> LogOutput(CreateStandardLogOutput(LogRef));
auto Block = MakeBlockDesc(50, {100, 200, 300, 400});
- // Default HostLatencySec=-1 → OptimizeRanges not called; raw GetBlockRanges result used
+ // Default HostLatencySec=-1 -> OptimizeRanges not called; raw GetBlockRanges result used
ChunkBlockAnalyser::Options Options;
Options.IsQuiet = true;
ChunkBlockAnalyser Analyser(*LogOutput, std::span<const ChunkBlockDescription>(&Block, 1), Options);
@@ -1920,7 +1920,7 @@ TEST_CASE("chunkblock.calc.no_latency_skips_optimize")
auto Result = Analyser.CalculatePartialBlockDownloads(NeededBlocks, Modes);
- // No optimize pass → exact ranges from GetBlockRanges
+ // No optimize pass -> exact ranges from GetBlockRanges
CHECK(Result.FullBlockIndexes.empty());
REQUIRE_EQ(2u, Result.BlockRanges.size());
CHECK_EQ(ChunkStartOffset, Result.BlockRanges[0].RangeStart);
@@ -1961,11 +1961,11 @@ TEST_CASE("chunkblock.calc.multiple_blocks_different_modes")
auto Result = Analyser.CalculatePartialBlockDownloads(NeededBlocks, Modes);
- // Block 0: Off → FullBlockIndexes
+ // Block 0: Off -> FullBlockIndexes
REQUIRE_EQ(1u, Result.FullBlockIndexes.size());
CHECK_EQ(0u, Result.FullBlockIndexes[0]);
- // Block 1: Exact → 2 ranges; Block 2: MultiRange (low latency) → 2 ranges
+ // Block 1: Exact -> 2 ranges; Block 2: MultiRange (low latency) -> 2 ranges
// Total: 4 ranges
REQUIRE_EQ(4u, Result.BlockRanges.size());
@@ -2058,7 +2058,7 @@ TEST_CASE("chunkblock.getblockranges.non_contiguous")
{
using namespace chunkblock_analyser_testutils;
- // Chunks 0 and 2 needed, chunk 1 skipped → two separate ranges
+ // Chunks 0 and 2 needed, chunk 1 skipped -> two separate ranges
auto Block = MakeBlockDesc(50, {100, 200, 300});
uint64_t ChunkStartOffset = CompressedBuffer::GetHeaderSizeForNoneEncoder() + Block.HeaderSize;
@@ -2082,7 +2082,7 @@ TEST_CASE("chunkblock.getblockranges.contiguous_run")
{
using namespace chunkblock_analyser_testutils;
- // Chunks 1, 2, 3 needed (consecutive) → one merged range
+ // Chunks 1, 2, 3 needed (consecutive) -> one merged range
auto Block = MakeBlockDesc(50, {50, 100, 150, 200, 250});
uint64_t ChunkStartOffset = CompressedBuffer::GetHeaderSizeForNoneEncoder() + Block.HeaderSize;