mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 04:08:19 +00:00
add beginining of indirect sorting
This commit is contained in:
parent
47017179a6
commit
0e092e0225
1 changed files with 62 additions and 2 deletions
|
@ -46,10 +46,66 @@ pub fn quadsort(
|
|||
// Then have our builtin dispatch to the correct version.
|
||||
// llvm garbage collection would remove all other variants.
|
||||
// Also, for numeric types, inlining the compare function can be a 2x perf gain.
|
||||
if (element_width <= MAX_ELEMENT_BUFFER_SIZE) {
|
||||
if (element_width <= MAX_ELEMENT_BUFFER_SIZE and false) {
|
||||
quadsort_direct(source_ptr, len, cmp, cmp_data, data_is_owned, inc_n_data, element_width, alignment, copy);
|
||||
} else {
|
||||
roc_panic("todo: fallback to an indirect pointer sort", 0);
|
||||
if (utils.alloc(len * @sizeOf(usize), @alignOf(usize))) |alloc_ptr| {
|
||||
// Build list of pointers to sort.
|
||||
if (@import("builtin").target.cpu.arch != .wasm32) {
|
||||
std.debug.print("Allocated! filling array.\n", .{});
|
||||
}
|
||||
var arr_ptr = @as([*]Opaque, @ptrCast(@alignCast(alloc_ptr)));
|
||||
defer utils.dealloc(alloc_ptr, @alignOf(usize));
|
||||
for (0..len) |i| {
|
||||
arr_ptr[i] = source_ptr + i * element_width;
|
||||
}
|
||||
|
||||
// Create indirect compare function.
|
||||
if (@import("builtin").target.cpu.arch != .wasm32) {
|
||||
std.debug.print("Creating indirect sort!\n", .{});
|
||||
}
|
||||
const IndirectSort = struct {
|
||||
compare: CompareFn,
|
||||
pub fn indirect_compare(compare_data: Opaque, lhs_ptr: Opaque, rhs_ptr: Opaque) callconv(.C) u8 {
|
||||
const lhs = @as(*Opaque, @ptrCast(@alignCast(lhs_ptr))).*;
|
||||
const rhs = @as(*Opaque, @ptrCast(@alignCast(rhs_ptr))).*;
|
||||
return compare(compare_data, lhs, rhs);
|
||||
}
|
||||
};
|
||||
const indirect_sort = IndirectSort{ .compare = cmp };
|
||||
|
||||
// Sort.
|
||||
if (@import("builtin").target.cpu.arch != .wasm32) {
|
||||
std.debug.print("Sorting!\n", .{});
|
||||
}
|
||||
quadsort_direct(@ptrCast(arr_ptr), len, indirect_sort.compare, cmp_data, data_is_owned, inc_n_data, @sizeOf(usize), @alignOf(usize), &pointer_copy);
|
||||
|
||||
if (utils.alloc(len * element_width, alignment)) |collect_alloc_ptr| {
|
||||
if (@import("builtin").target.cpu.arch != .wasm32) {
|
||||
std.debug.print("Allocated2! Collecting\n", .{});
|
||||
}
|
||||
// Collect sorted pointers into correct order.
|
||||
var collect_ptr = collect_alloc_ptr;
|
||||
defer utils.dealloc(collect_alloc_ptr, alignment);
|
||||
for (0..len) |i| {
|
||||
copy(collect_ptr, arr_ptr[i]);
|
||||
collect_ptr += element_width;
|
||||
}
|
||||
|
||||
// Copy to original array as sorted.
|
||||
if (@import("builtin").target.cpu.arch != .wasm32) {
|
||||
std.debug.print("Copy out!\n", .{});
|
||||
}
|
||||
@memcpy(source_ptr[0..(len * element_width)], collect_ptr[0..(len * element_width)]);
|
||||
if (@import("builtin").target.cpu.arch != .wasm32) {
|
||||
std.debug.print("Sorted:[{d}]{d}\nAll done!\n", .{ len, @as([*]i64, @ptrCast(@alignCast(source_ptr)))[0..len] });
|
||||
}
|
||||
} else {
|
||||
roc_panic("Out of memory while trying to allocate for sorting", 0);
|
||||
}
|
||||
} else {
|
||||
roc_panic("Out of memory while trying to allocate for sorting", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2440,6 +2496,10 @@ test "swap" {
|
|||
try testing.expectEqual(arr, [2]i64{ -22, -22 });
|
||||
}
|
||||
|
||||
pub fn pointer_copy(dst_ptr: Opaque, src_ptr: Opaque) callconv(.C) void {
|
||||
@as(*usize, @alignCast(@ptrCast(dst_ptr))).* = @as(*usize, @alignCast(@ptrCast(src_ptr))).*;
|
||||
}
|
||||
|
||||
fn test_i64_compare(_: Opaque, a_ptr: Opaque, b_ptr: Opaque) callconv(.C) u8 {
|
||||
const a = @as(*i64, @alignCast(@ptrCast(a_ptr))).*;
|
||||
const b = @as(*i64, @alignCast(@ptrCast(b_ptr))).*;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue