| ... | ... | @@ -175,17 +175,78 @@ fn partition(a: usize, b: usize, pivot: *usize, context: anytype) bool { |
| 175 | 175 | i += 1; |
| 176 | 176 | j -= 1; |
| 177 | 177 | |
| 178 | | while (true) { |
| 179 | | while (i <= j and context.lessThan(i, a)) i += 1; |
| 180 | | while (i <= j and !context.lessThan(j, a)) j -= 1; |
| 181 | | if (i > j) break; |
| 178 | const block_size = 64; |
| 179 | var offsets_l: [block_size]u8 align(std.atomic.cache_line) = undefined; |
| 180 | var offsets_r: [block_size]u8 align(std.atomic.cache_line) = undefined; |
| 181 | |
| 182 | var offsets_l_base = i; |
| 183 | var offsets_r_base = j; |
| 184 | var num_l: usize = 0; |
| 185 | var num_r: usize = 0; |
| 186 | var start_l: usize = 0; |
| 187 | var start_r: usize = 0; |
| 188 | |
| 189 | while (i <= j) { |
| 190 | const num_unknown = j + 1 - i; |
| 191 | const left_split = if (num_l == 0) |
| 192 | @min(block_size, if (num_r == 0) num_unknown / 2 else num_unknown) |
| 193 | else |
| 194 | 0; |
| 195 | const right_split = if (num_r == 0) |
| 196 | @min(block_size, num_unknown - left_split) |
| 197 | else |
| 198 | 0; |
| 199 | |
| 200 | for (0..left_split) |k| { |
| 201 | offsets_l[num_l] = @intCast(k); |
| 202 | num_l += @intFromBool(!context.lessThan(i + k, a)); |
| 203 | } |
| 204 | i += left_split; |
| 182 | 205 | |
| 183 | | context.swap(i, j); |
| 184 | | i += 1; |
| 185 | | j -= 1; |
| 206 | for (0..right_split) |k| { |
| 207 | offsets_r[num_r] = @intCast(k); |
| 208 | num_r += @intFromBool(context.lessThan(j - k, a)); |
| 209 | } |
| 210 | j -= right_split; |
| 211 | |
| 212 | const num = @min(num_l, num_r); |
| 213 | for (0..num) |m| { |
| 214 | context.swap( |
| 215 | offsets_l_base + offsets_l[start_l + m], |
| 216 | offsets_r_base - offsets_r[start_r + m], |
| 217 | ); |
| 218 | } |
| 219 | num_l -= num; |
| 220 | num_r -= num; |
| 221 | start_l += num; |
| 222 | start_r += num; |
| 223 | |
| 224 | if (num_l == 0) { |
| 225 | start_l = 0; |
| 226 | offsets_l_base = i; |
| 227 | } |
| 228 | if (num_r == 0) { |
| 229 | start_r = 0; |
| 230 | offsets_r_base = j; |
| 231 | } |
| 186 | 232 | } |
| 187 | 233 | |
| 188 | | // TODO: Enable the BlockQuicksort optimization |
| 234 | if (num_l > 0) { |
| 235 | while (num_l > 0) { |
| 236 | num_l -= 1; |
| 237 | context.swap(offsets_l_base + offsets_l[start_l + num_l], j); |
| 238 | j -= 1; |
| 239 | } |
| 240 | i = j + 1; |
| 241 | } |
| 242 | if (num_r > 0) { |
| 243 | while (num_r > 0) { |
| 244 | num_r -= 1; |
| 245 | context.swap(offsets_r_base - offsets_r[start_r + num_r], i); |
| 246 | i += 1; |
| 247 | } |
| 248 | j = i - 1; |
| 249 | } |
| 189 | 250 | |
| 190 | 251 | context.swap(j, a); |
| 191 | 252 | pivot.* = j; |