aboutsummaryrefslogtreecommitdiff
path: root/lib/std/array_hash_map.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2025-05-18 12:45:30 -0700
committerAndrew Kelley <andrew@ziglang.org>2025-08-11 13:32:12 -0700
commit59de7e3a5725f0c4eeb64bc464db85e019af7446 (patch)
tree02f14fd8a1601993ea41473f29ed4ef05f20e122 /lib/std/array_hash_map.zig
parent282c3575b16499518b19ee9b1a8364c9379dab94 (diff)
downloadzig-59de7e3a5725f0c4eeb64bc464db85e019af7446.tar.gz
zig-59de7e3a5725f0c4eeb64bc464db85e019af7446.zip
std: introduce orderedRemoveMany
This algorithm is non-trivial and makes sense for any data structure that acts as an array list, so I thought it would make sense as a method. I have a real world case for this in a music player application (deleting queue items). Adds the method to: * ArrayList * ArrayHashMap * MultiArrayList
Diffstat (limited to 'lib/std/array_hash_map.zig')
-rw-r--r--lib/std/array_hash_map.zig53
1 files changed, 53 insertions, 0 deletions
diff --git a/lib/std/array_hash_map.zig b/lib/std/array_hash_map.zig
index 9ddd0fe2bd..02ae8895aa 100644
--- a/lib/std/array_hash_map.zig
+++ b/lib/std/array_hash_map.zig
@@ -1273,6 +1273,33 @@ pub fn ArrayHashMapUnmanaged(
self.removeByIndex(index, if (store_hash) {} else ctx, .ordered);
}
+ /// Remove the entries indexed by `sorted_indexes`. The indexes to be
+ /// removed correspond to state before deletion.
+ ///
+ /// This operation is O(N).
+ ///
+ /// Asserts that each index to be removed is in bounds.
+ ///
+ /// Invalidates key and element pointers beyond the first deleted index.
+ pub fn orderedRemoveAtMany(self: *Self, gpa: Allocator, sorted_indexes: []const usize) Oom!void {
+ if (@sizeOf(ByIndexContext) != 0)
+ @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call orderedRemoveAtContext instead.");
+ return self.orderedRemoveAtManyContext(gpa, sorted_indexes, undefined);
+ }
+
+ pub fn orderedRemoveAtManyContext(
+ self: *Self,
+ gpa: Allocator,
+ sorted_indexes: []const usize,
+ ctx: Context,
+ ) Oom!void {
+ self.pointer_stability.lock();
+ defer self.pointer_stability.unlock();
+
+ self.entries.orderedRemoveMany(sorted_indexes);
+ try self.reIndexContext(gpa, ctx);
+ }
+
/// Create a copy of the hash map which can be modified separately.
/// The copy uses the same context as this instance, but is allocated
/// with the provided allocator.
@@ -2651,3 +2678,29 @@ pub fn getAutoHashStratFn(comptime K: type, comptime Context: type, comptime str
}
}.hash;
}
+
+test "orderedRemoveAtMany" {
+ const gpa = testing.allocator;
+
+ var map: AutoArrayHashMapUnmanaged(usize, void) = .empty;
+ defer map.deinit(gpa);
+
+ for (0..10) |n| {
+ try map.put(gpa, n, {});
+ }
+
+ try map.orderedRemoveAtMany(gpa, &.{ 1, 5, 5, 7, 9 });
+ try testing.expectEqualSlices(usize, &.{ 0, 2, 3, 4, 6, 8 }, map.keys());
+
+ try map.orderedRemoveAtMany(gpa, &.{0});
+ try testing.expectEqualSlices(usize, &.{ 2, 3, 4, 6, 8 }, map.keys());
+
+ try map.orderedRemoveAtMany(gpa, &.{});
+ try testing.expectEqualSlices(usize, &.{ 2, 3, 4, 6, 8 }, map.keys());
+
+ try map.orderedRemoveAtMany(gpa, &.{ 1, 2, 3, 4 });
+ try testing.expectEqualSlices(usize, &.{2}, map.keys());
+
+ try map.orderedRemoveAtMany(gpa, &.{0});
+ try testing.expectEqualSlices(usize, &.{}, map.keys());
+}