| package spec_iterator |
| |
| func ParallelizedIndexRange(length int, parallelTotal int, parallelNode int) (startIndex int, count int) { |
| if length == 0 { |
| return 0, 0 |
| } |
| |
| // We have more nodes than tests. Trivial case. |
| if parallelTotal >= length { |
| if parallelNode > length { |
| return 0, 0 |
| } else { |
| return parallelNode - 1, 1 |
| } |
| } |
| |
| // This is the minimum amount of tests that a node will be required to run |
| minTestsPerNode := length / parallelTotal |
| |
| // This is the maximum amount of tests that a node will be required to run |
| // The algorithm guarantees that this would be equal to at least the minimum amount |
| // and at most one more |
| maxTestsPerNode := minTestsPerNode |
| if length%parallelTotal != 0 { |
| maxTestsPerNode++ |
| } |
| |
| // Number of nodes that will have to run the maximum amount of tests per node |
| numMaxLoadNodes := length % parallelTotal |
| |
| // Number of nodes that precede the current node and will have to run the maximum amount of tests per node |
| var numPrecedingMaxLoadNodes int |
| if parallelNode > numMaxLoadNodes { |
| numPrecedingMaxLoadNodes = numMaxLoadNodes |
| } else { |
| numPrecedingMaxLoadNodes = parallelNode - 1 |
| } |
| |
| // Number of nodes that precede the current node and will have to run the minimum amount of tests per node |
| var numPrecedingMinLoadNodes int |
| if parallelNode <= numMaxLoadNodes { |
| numPrecedingMinLoadNodes = 0 |
| } else { |
| numPrecedingMinLoadNodes = parallelNode - numMaxLoadNodes - 1 |
| } |
| |
| // Evaluate the test start index and number of tests to run |
| startIndex = numPrecedingMaxLoadNodes*maxTestsPerNode + numPrecedingMinLoadNodes*minTestsPerNode |
| if parallelNode > numMaxLoadNodes { |
| count = minTestsPerNode |
| } else { |
| count = maxTestsPerNode |
| } |
| return |
| } |