diff options
Diffstat (limited to 'src/zenremotestore/chunking/chunkblock.cpp')
| -rw-r--r-- | src/zenremotestore/chunking/chunkblock.cpp | 84 |
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; |