authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-10-06 23:58:53-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-10-08 16:54:31-07:00
logcbb9b5d9f04509260b8cea935a0441f63f33bc32
tree98589068dfbd7351f1ad82afd74f2c03a632f3ba
parent1ca442832465d9735313a326326fbe96a7ec55ed

std: add unstable sorting to array hash maps

closes #17426

3 files changed, 33 insertions(+), 4 deletions(-)

lib/std/array_hash_map.zig+30-3
...@@ -1229,14 +1229,41 @@ pub fn ArrayHashMapUnmanaged(...@@ -1229,14 +1229,41 @@ pub fn ArrayHashMapUnmanaged(
1229 /// Sorts the entries and then rebuilds the index.1229 /// Sorts the entries and then rebuilds the index.
1230 /// `sort_ctx` must have this method:1230 /// `sort_ctx` must have this method:
1231 /// `fn lessThan(ctx: @TypeOf(ctx), a_index: usize, b_index: usize) bool`1231 /// `fn lessThan(ctx: @TypeOf(ctx), a_index: usize, b_index: usize) bool`
1232 /// Uses a stable sorting algorithm.
1232 pub inline fn sort(self: *Self, sort_ctx: anytype) void {1233 pub inline fn sort(self: *Self, sort_ctx: anytype) void {
1233 if (@sizeOf(ByIndexContext) != 0)1234 if (@sizeOf(ByIndexContext) != 0)
1234 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call sortContext instead.");1235 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call sortContext instead.");
1235 return self.sortContext(sort_ctx, undefined);1236 return sortContextInternal(self, .stable, sort_ctx, undefined);
1236 }1237 }
12371238
1238 pub fn sortContext(self: *Self, sort_ctx: anytype, ctx: Context) void {1239 /// Sorts the entries and then rebuilds the index.
1239 self.entries.sort(sort_ctx);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 }
1240 const header = self.index_header orelse return;1267 const header = self.index_header orelse return;
1241 header.reset();1268 header.reset();
1242 self.insertAllEntriesIntoNewHeader(if (store_hash) {} else ctx, header);1269 self.insertAllEntriesIntoNewHeader(if (store_hash) {} else ctx, header);
lib/std/multi_array_list.zig+1-1
...@@ -467,7 +467,7 @@ pub fn MultiArrayList(comptime T: type) type {...@@ -467,7 +467,7 @@ pub fn MultiArrayList(comptime T: type) type {
467467
468 /// `ctx` has the following method:468 /// `ctx` has the following method:
469 /// `fn lessThan(ctx: @TypeOf(ctx), a_index: usize, b_index: usize) bool`469 /// `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 {
471 const sort_context: struct {471 const sort_context: struct {
472 sub_ctx: @TypeOf(ctx),472 sub_ctx: @TypeOf(ctx),
473 slice: Slice,473 slice: Slice,
lib/std/sort.zig+2
...@@ -4,6 +4,8 @@ const testing = std.testing;...@@ -4,6 +4,8 @@ const testing = std.testing;
4const mem = std.mem;4const mem = std.mem;
5const math = std.math;5const math = std.math;
66
7pub const Mode = enum { stable, unstable };
8
7pub const block = @import("sort/block.zig").block;9pub const block = @import("sort/block.zig").block;
8pub const pdq = @import("sort/pdq.zig").pdq;10pub const pdq = @import("sort/pdq.zig").pdq;
9pub const pdqContext = @import("sort/pdq.zig").pdqContext;11pub const pdqContext = @import("sort/pdq.zig").pdqContext;