Skip to content

Commit 49bb45c

Browse files
committed
std: add unstable sorting to array hash maps
closes #17426
1 parent 833de10 commit 49bb45c

File tree

3 files changed

+33
-4
lines changed

3 files changed

+33
-4
lines changed

lib/std/array_hash_map.zig

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,14 +1229,41 @@ pub fn ArrayHashMapUnmanaged(
12291229
/// Sorts the entries and then rebuilds the index.
12301230
/// `sort_ctx` must have this method:
12311231
/// `fn lessThan(ctx: @TypeOf(ctx), a_index: usize, b_index: usize) bool`
1232+
/// Uses a stable sorting algorithm.
12321233
pub inline fn sort(self: *Self, sort_ctx: anytype) void {
12331234
if (@sizeOf(ByIndexContext) != 0)
12341235
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call sortContext instead.");
1235-
return self.sortContext(sort_ctx, undefined);
1236+
return sortContextInternal(self, .stable, sort_ctx, undefined);
12361237
}
12371238

1238-
pub fn sortContext(self: *Self, sort_ctx: anytype, ctx: Context) void {
1239-
self.entries.sort(sort_ctx);
1239+
/// Sorts the entries and then rebuilds the index.
1240+
/// `sort_ctx` must have this method:
1241+
/// `fn lessThan(ctx: @TypeOf(ctx), a_index: usize, b_index: usize) bool`
1242+
/// Uses an unstable sorting algorithm.
1243+
pub inline fn sortUnstable(self: *Self, sort_ctx: anytype) void {
1244+
if (@sizeOf(ByIndexContext) != 0)
1245+
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call sortUnstableContext instead.");
1246+
return self.sortContextInternal(.unstable, sort_ctx, undefined);
1247+
}
1248+
1249+
pub inline fn sortContext(self: *Self, sort_ctx: anytype, ctx: Context) void {
1250+
return sortContextInternal(self, .stable, sort_ctx, ctx);
1251+
}
1252+
1253+
pub inline fn sortUnstableContext(self: *Self, sort_ctx: anytype, ctx: Context) void {
1254+
return sortContextInternal(self, .unstable, sort_ctx, ctx);
1255+
}
1256+
1257+
fn sortContextInternal(
1258+
self: *Self,
1259+
comptime mode: std.sort.Mode,
1260+
sort_ctx: anytype,
1261+
ctx: Context,
1262+
) void {
1263+
switch (mode) {
1264+
.stable => self.entries.sort(sort_ctx),
1265+
.unstable => self.entries.sortUnstable(sort_ctx),
1266+
}
12401267
const header = self.index_header orelse return;
12411268
header.reset();
12421269
self.insertAllEntriesIntoNewHeader(if (store_hash) {} else ctx, header);

lib/std/multi_array_list.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ pub fn MultiArrayList(comptime T: type) type {
467467

468468
/// `ctx` has the following method:
469469
/// `fn lessThan(ctx: @TypeOf(ctx), a_index: usize, b_index: usize) bool`
470-
fn sortInternal(self: Self, a: usize, b: usize, ctx: anytype, comptime mode: enum { stable, unstable }) void {
470+
fn sortInternal(self: Self, a: usize, b: usize, ctx: anytype, comptime mode: std.sort.Mode) void {
471471
const sort_context: struct {
472472
sub_ctx: @TypeOf(ctx),
473473
slice: Slice,

lib/std/sort.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ const testing = std.testing;
44
const mem = std.mem;
55
const math = std.math;
66

7+
pub const Mode = enum { stable, unstable };
8+
79
pub const block = @import("sort/block.zig").block;
810
pub const pdq = @import("sort/pdq.zig").pdq;
911
pub const pdqContext = @import("sort/pdq.zig").pdqContext;

0 commit comments

Comments
 (0)