Sort the subarray a[begin:end) by their ix-th character, * where begin = bucketEdge[0] and end = bucketEdge[UMAX_CHAR] + bucketSize[UMAX_CHAR]. * * We expect that the ix-length prefix of every entry in a[being:end) to be identical * so that the result is that the a[begin:end) subarray ends up sorted by their first 'ix + 1' characters. * * Precondition: For all begin <= i < end, NULL != a[i];
| 85 | * Postcondition: The contents of bucketSize is not preserved! |
| 86 | */ |
| 87 | static void sort_buckets(const sha256_midstate** a, uint32_t* restrict bucketSize, const uint32_t* restrict bucketEdge, unsigned int ix) { |
| 88 | /* The implementation works by finding the first non-empty bucket and then swapping the first element of that bucket into its position |
| 89 | at the far end of the bucket where it belongs. |
| 90 | |
| 91 | After moving the element into that position the size of the target bucket is decreased by one, |
| 92 | and thus the next element that will be swapped into that bucket will be placed behind it. |
| 93 | |
| 94 | This process continues until the first element of the first non-empty bucket gets swapped with itself |
| 95 | and its own bucket is decremented from size 1 to size 0. |
| 96 | |
| 97 | At that point we search again for the next non-empty bucket and repeat this process until there are no more non-empty buckets. |
| 98 | */ |
| 99 | for (unsigned int i = 0; i < CHAR_COUNT; ++i) { |
| 100 | size_t start = bucketEdge[i]; |
| 101 | while (bucketSize[i]) { |
| 102 | /* Each time through this while loop some bucketSize is decremented. |
| 103 | Therefore this body is executed 'sum(i < CHAR_COUNT, bucketSize[i]) = end - begin' many times. |
| 104 | */ |
| 105 | size_t bucket = readIndex(a[start], ix); |
| 106 | simplicity_assert(bucketSize[bucket]); |
| 107 | bucketSize[bucket]--; |
| 108 | swap(a + start, a + bucketEdge[bucket] + bucketSize[bucket]); |
| 109 | } |
| 110 | } |
| 111 | } |
| 112 | |
| 113 | /* Attempts to (partially) sort an array of pointers to 'sha256_midstate's in place in memcmp order. |
| 114 | * If NULL == hasDuplicates then sorting is always run to completion. |