diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2025-05-18 12:45:30 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2025-08-11 13:32:12 -0700 |
| commit | 59de7e3a5725f0c4eeb64bc464db85e019af7446 (patch) | |
| tree | 02f14fd8a1601993ea41473f29ed4ef05f20e122 /lib/std/array_hash_map.zig | |
| parent | 282c3575b16499518b19ee9b1a8364c9379dab94 (diff) | |
| download | zig-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.zig | 53 |
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()); +} |
