| 959 | } |
| 960 | |
| 961 | std::pair<qindex, qindex> util_getBlockMultipleSubRange( |
| 962 | qindex rangeLen, qindex blockLen, int idSubRange, int numSubRanges |
| 963 | ) { |
| 964 | // divides a range into whole blocks (and a single leftover sub-block) and |
| 965 | // attempts to uniformly distribute the blocks across the specified number of |
| 966 | // sub-ranges. When the blocks do not divide evenly between sub-ranges, the |
| 967 | // leftover blocks are spread apart across sub-ranges. When the range does not |
| 968 | // divide evenly into blocks, the overflow is given to the final sub-range. |
| 969 | |
| 970 | qindex numFullBlocks = rangeLen / blockLen; // floors |
| 971 | qindex subBlockLen = rangeLen % blockLen; |
| 972 | |
| 973 | qindex baseNumBlocksPerSubRange = numFullBlocks / numSubRanges; |
| 974 | qindex numExtraBlocks = numFullBlocks % numSubRanges; |
| 975 | |
| 976 | // determine how many extra blocks this subrange should contain |
| 977 | qindex prevExtra = (idSubRange * numExtraBlocks) / numSubRanges; |
| 978 | qindex prevShift = (idSubRange * numExtraBlocks) % numSubRanges; |
| 979 | bool hereExtra = (prevShift + numExtraBlocks) >= numSubRanges; |
| 980 | |
| 981 | // allocate blocks to this sub-range |
| 982 | qindex startBlockInd = idSubRange * baseNumBlocksPerSubRange + prevExtra; |
| 983 | qindex endBlockInd = startBlockInd + baseNumBlocksPerSubRange + hereExtra; |
| 984 | |
| 985 | // find this sub-range indices within [0, rangeLen) |
| 986 | qindex startInd = startBlockInd * blockLen; |
| 987 | qindex endInd = endBlockInd * blockLen; // exclusive |
| 988 | |
| 989 | // arbitrarily allocate the leftover sub-block to the final sub-range |
| 990 | if (idSubRange == numSubRanges - 1) |
| 991 | endInd += subBlockLen; |
| 992 | |
| 993 | return std::make_pair(startInd, endInd); |
| 994 | } |
| 995 | |
| 996 | |
| 997 |
no outgoing calls
no test coverage detected