Loading include/global/arithmetic/arithmetic.hpp +12 −12 Original line number Diff line number Diff line Loading @@ -169,32 +169,32 @@ block_index(const uint64_t offset, const size_t block_size) { * overflow. * * @param [in] offset the operation's initial offset. * @param [in] count the number of bytes affected by the operation. * @param [in] chnk_size the block size that should be used to compute the * @param [in] size the number of bytes affected by the operation. * @param [in] block_size the block size that should be used to compute the * number of blocks. * @returns the number of blocks affected by the operation. */ constexpr std::size_t chnk_count_for_offset(const uint64_t offset, const size_t count, const size_t chnk_size) { block_count(const uint64_t offset, const size_t size, const size_t block_size) { using gkfs::utils::arithmetic::log2; // These checks are automatically removed in release builds assert(is_power_of_2(chnk_size)); assert(is_power_of_2(block_size)); #if defined(__GNUC__) && !defined(__clang__) assert(!__builtin_add_overflow_p(offset, count, static_cast<uint64_t>(0))); assert(!__builtin_add_overflow_p(offset, size, static_cast<uint64_t>(0))); #else assert(offset + count > offset); assert(offset + size > offset); #endif const uint64_t chnk_start = align_left(offset, chnk_size); const uint64_t chnk_end = align_left(offset + count, chnk_size); const size_t mask = -!!count; // this is either 0 or ~0 const uint64_t first_block = align_left(offset, block_size); const uint64_t final_block = align_left(offset + size, block_size); const size_t mask = -!!size; // this is either 0 or ~0 return (((chnk_end >> log2(chnk_size)) - (chnk_start >> log2(chnk_size)) + !is_divisible(offset + count, chnk_size))) & return (((final_block >> log2(block_size)) - (first_block >> log2(block_size)) + !is_divisible(offset + size, block_size))) & mask; } Loading tests/unit/test_utils_arithmetic.cpp +25 −29 Original line number Diff line number Diff line Loading @@ -512,7 +512,7 @@ SCENARIO(" chunk IDs can be computed correctly ", SCENARIO(" the number of chunks involved in an operation can be computed " "correctly ", "[utils][numeric][chnk_count_for_offset]") { "[utils][numeric][block_count]") { GIVEN(" an offset, an operation size, and a block size ") { Loading @@ -533,7 +533,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == 0 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 0; REQUIRE(n == expected_n); } Loading @@ -548,7 +548,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == 1 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 1; REQUIRE(n == expected_n); } Loading @@ -562,7 +562,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == 1 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 1; REQUIRE(n == expected_n); } Loading @@ -580,7 +580,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count corresponds to the number " "of blocks involved in the operation ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = (offset + size) / block_size - offset / block_size + Loading @@ -604,7 +604,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == 1 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 0; REQUIRE(n == expected_n); } Loading @@ -620,7 +620,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count equals 1 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 1; REQUIRE(n == expected_n); } Loading @@ -634,7 +634,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == 1 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 1; REQUIRE(n == expected_n); } Loading @@ -652,7 +652,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count corresponds to the number " "of blocks involved in the operation ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = (offset + size) / block_size - offset / block_size + Loading @@ -675,7 +675,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == 0 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 0; REQUIRE(n == expected_n); } Loading @@ -689,7 +689,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == 1 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 1; REQUIRE(n == expected_n); } Loading @@ -707,7 +707,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count corresponds to the number " "of blocks involved in the operation ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = (offset + size) / block_size - offset / block_size + Loading @@ -730,8 +730,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " CAPTURE(offset, size, block_size); THEN(" the computed block count == 1 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); const std::size_t n = block_count(offset, size, block_size); const std::size_t expected_n = 0; REQUIRE(n == expected_n); } Loading @@ -744,8 +743,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " CAPTURE(offset, size, block_size); THEN(" the computed block count == M ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); const std::size_t n = block_count(offset, size, block_size); const std::size_t expected_n = m; REQUIRE(n == expected_n); } Loading @@ -760,8 +758,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count corresponds to the number " "of blocks involved in the operation ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); const std::size_t n = block_count(offset, size, block_size); const std::size_t expected_n = (offset + size) / block_size - offset / block_size + ((offset + size) % block_size ? 1u : 0); Loading @@ -777,8 +774,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count corresponds to the number " "of blocks involved in the operation ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); const std::size_t n = block_count(offset, size, block_size); const std::size_t expected_n = (offset + size) / block_size - offset / block_size + ((offset + size) % block_size ? 1u : 0); Loading @@ -805,7 +801,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == 1 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 0; REQUIRE(n == expected_n); } Loading @@ -819,7 +815,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == M ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = m; REQUIRE(n == expected_n); } Loading @@ -836,7 +832,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count corresponds to the number " "of blocks involved in the operation ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = (offset + size) / block_size - offset / block_size + Loading @@ -854,7 +850,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count corresponds to the number " "of blocks involved in the operation ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = (offset + size) / block_size - offset / block_size + Loading @@ -878,7 +874,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == 1 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 0; REQUIRE(n == expected_n); } Loading @@ -892,7 +888,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == M ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = m; REQUIRE(n == expected_n); } Loading @@ -909,7 +905,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count corresponds to the number " "of blocks involved in the operation ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = (offset + size) / block_size - offset / block_size + Loading @@ -927,7 +923,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count corresponds to the number " "of blocks involved in the operation ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = (offset + size) / block_size - offset / block_size + Loading @@ -950,7 +946,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == 1 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 0; REQUIRE(n == expected_n); } Loading Loading
include/global/arithmetic/arithmetic.hpp +12 −12 Original line number Diff line number Diff line Loading @@ -169,32 +169,32 @@ block_index(const uint64_t offset, const size_t block_size) { * overflow. * * @param [in] offset the operation's initial offset. * @param [in] count the number of bytes affected by the operation. * @param [in] chnk_size the block size that should be used to compute the * @param [in] size the number of bytes affected by the operation. * @param [in] block_size the block size that should be used to compute the * number of blocks. * @returns the number of blocks affected by the operation. */ constexpr std::size_t chnk_count_for_offset(const uint64_t offset, const size_t count, const size_t chnk_size) { block_count(const uint64_t offset, const size_t size, const size_t block_size) { using gkfs::utils::arithmetic::log2; // These checks are automatically removed in release builds assert(is_power_of_2(chnk_size)); assert(is_power_of_2(block_size)); #if defined(__GNUC__) && !defined(__clang__) assert(!__builtin_add_overflow_p(offset, count, static_cast<uint64_t>(0))); assert(!__builtin_add_overflow_p(offset, size, static_cast<uint64_t>(0))); #else assert(offset + count > offset); assert(offset + size > offset); #endif const uint64_t chnk_start = align_left(offset, chnk_size); const uint64_t chnk_end = align_left(offset + count, chnk_size); const size_t mask = -!!count; // this is either 0 or ~0 const uint64_t first_block = align_left(offset, block_size); const uint64_t final_block = align_left(offset + size, block_size); const size_t mask = -!!size; // this is either 0 or ~0 return (((chnk_end >> log2(chnk_size)) - (chnk_start >> log2(chnk_size)) + !is_divisible(offset + count, chnk_size))) & return (((final_block >> log2(block_size)) - (first_block >> log2(block_size)) + !is_divisible(offset + size, block_size))) & mask; } Loading
tests/unit/test_utils_arithmetic.cpp +25 −29 Original line number Diff line number Diff line Loading @@ -512,7 +512,7 @@ SCENARIO(" chunk IDs can be computed correctly ", SCENARIO(" the number of chunks involved in an operation can be computed " "correctly ", "[utils][numeric][chnk_count_for_offset]") { "[utils][numeric][block_count]") { GIVEN(" an offset, an operation size, and a block size ") { Loading @@ -533,7 +533,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == 0 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 0; REQUIRE(n == expected_n); } Loading @@ -548,7 +548,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == 1 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 1; REQUIRE(n == expected_n); } Loading @@ -562,7 +562,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == 1 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 1; REQUIRE(n == expected_n); } Loading @@ -580,7 +580,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count corresponds to the number " "of blocks involved in the operation ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = (offset + size) / block_size - offset / block_size + Loading @@ -604,7 +604,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == 1 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 0; REQUIRE(n == expected_n); } Loading @@ -620,7 +620,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count equals 1 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 1; REQUIRE(n == expected_n); } Loading @@ -634,7 +634,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == 1 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 1; REQUIRE(n == expected_n); } Loading @@ -652,7 +652,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count corresponds to the number " "of blocks involved in the operation ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = (offset + size) / block_size - offset / block_size + Loading @@ -675,7 +675,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == 0 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 0; REQUIRE(n == expected_n); } Loading @@ -689,7 +689,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == 1 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 1; REQUIRE(n == expected_n); } Loading @@ -707,7 +707,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count corresponds to the number " "of blocks involved in the operation ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = (offset + size) / block_size - offset / block_size + Loading @@ -730,8 +730,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " CAPTURE(offset, size, block_size); THEN(" the computed block count == 1 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); const std::size_t n = block_count(offset, size, block_size); const std::size_t expected_n = 0; REQUIRE(n == expected_n); } Loading @@ -744,8 +743,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " CAPTURE(offset, size, block_size); THEN(" the computed block count == M ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); const std::size_t n = block_count(offset, size, block_size); const std::size_t expected_n = m; REQUIRE(n == expected_n); } Loading @@ -760,8 +758,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count corresponds to the number " "of blocks involved in the operation ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); const std::size_t n = block_count(offset, size, block_size); const std::size_t expected_n = (offset + size) / block_size - offset / block_size + ((offset + size) % block_size ? 1u : 0); Loading @@ -777,8 +774,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count corresponds to the number " "of blocks involved in the operation ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); const std::size_t n = block_count(offset, size, block_size); const std::size_t expected_n = (offset + size) / block_size - offset / block_size + ((offset + size) % block_size ? 1u : 0); Loading @@ -805,7 +801,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == 1 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 0; REQUIRE(n == expected_n); } Loading @@ -819,7 +815,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == M ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = m; REQUIRE(n == expected_n); } Loading @@ -836,7 +832,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count corresponds to the number " "of blocks involved in the operation ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = (offset + size) / block_size - offset / block_size + Loading @@ -854,7 +850,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count corresponds to the number " "of blocks involved in the operation ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = (offset + size) / block_size - offset / block_size + Loading @@ -878,7 +874,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == 1 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 0; REQUIRE(n == expected_n); } Loading @@ -892,7 +888,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == M ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = m; REQUIRE(n == expected_n); } Loading @@ -909,7 +905,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count corresponds to the number " "of blocks involved in the operation ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = (offset + size) / block_size - offset / block_size + Loading @@ -927,7 +923,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count corresponds to the number " "of blocks involved in the operation ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = (offset + size) / block_size - offset / block_size + Loading @@ -950,7 +946,7 @@ SCENARIO(" the number of chunks involved in an operation can be computed " THEN(" the computed block count == 1 ") { const std::size_t n = chnk_count_for_offset(offset, size, block_size); block_count(offset, size, block_size); const std::size_t expected_n = 0; REQUIRE(n == expected_n); } Loading