authorgravatar for git@zander.xyzZander Khan <git@zander.xyz> 2021-01-17 14:41:20+00:00
committergravatar for git@zander.xyzZander Khan <git@zander.xyz> 2021-01-17 14:41:20+00:00
log9a09ebb1b92f33913bdcc16e9d978fb6e5a820f1
tree1a178892bfa500026b16a4a3434d1cc243142d9a
parente1ab425bcead727a73e4512aeca1ba9112b2c88e

Replace `shrink` with `shrinkAndFree` and `shrinkRetainingCapacity`


2 files changed, 100 insertions(+), 6 deletions(-)

lib/std/priority_dequeue.zig+50-3
......@@ -382,9 +382,29 @@ pub fn PriorityDequeue(comptime T: type) type {
382382 self.len = new_len;
383383 }
384384
385 pub fn shrink(self: *Self, new_len: usize) void {
386 // TODO take advantage of the new realloc semantics
387 assert(new_len <= self.len);
385 /// Reduce allocated capacity to `new_len`.
386 pub fn shrinkAndFree(self: *Self, new_len: usize) void {
387 assert(new_len <= self.items.len);
388
389 // Cannot shrink to smaller than the current queue size without invalidating the heap property
390 assert(new_len >= self.len);
391
392 self.items = self.allocator.realloc(self.items[0..], new_len) catch |e| switch (e) {
393 error.OutOfMemory => { // no problem, capacity is still correct then.
394 self.items.len = new_len;
395 return;
396 },
397 };
398 self.len = new_len;
399 }
400
401 /// Reduce length to `new_len`.
402 pub fn shrinkRetainingCapacity(self: *Self, new_len: usize) void {
403 assert(new_len <= self.items.len);
404
405 // Cannot shrink to smaller than the current queue size without invalidating the heap property
406 assert(new_len >= self.len);
407
388408 self.len = new_len;
389409 }
390410
......@@ -798,6 +818,33 @@ test "std.PriorityDequeue: iterator while empty" {
798818 expectEqual(it.next(), null);
799819}
800820
821test "std.PriorityDequeue: shrinkRetainingCapacity and shrinkAndFree" {
822 var queue = PDQ.init(testing.allocator, lessThanComparison);
823 defer queue.deinit();
824
825 try queue.ensureCapacity(4);
826 expect(queue.capacity() >= 4);
827
828 try queue.add(1);
829 try queue.add(2);
830 try queue.add(3);
831 expect(queue.capacity() >= 4);
832 expectEqual(@as(usize, 3), queue.len);
833
834 queue.shrinkRetainingCapacity(3);
835 expect(queue.capacity() >= 4);
836 expectEqual(@as(usize, 3), queue.len);
837
838 queue.shrinkAndFree(3);
839 expectEqual(@as(usize, 3), queue.capacity());
840 expectEqual(@as(usize, 3), queue.len);
841
842 expectEqual(@as(u32, 3), queue.removeMax());
843 expectEqual(@as(u32, 2), queue.removeMax());
844 expectEqual(@as(u32, 1), queue.removeMax());
845 expect(queue.removeMaxOrNull() == null);
846}
847
801848test "std.PriorityDequeue: fuzz testing min" {
802849 var prng = std.rand.DefaultPrng.init(0x12345678);
803850
lib/std/priority_queue.zig+50-3
......@@ -192,9 +192,29 @@ pub fn PriorityQueue(comptime T: type) type {
192192 self.len = new_len;
193193 }
194194
195 pub fn shrink(self: *Self, new_len: usize) void {
196 // TODO take advantage of the new realloc semantics
197 assert(new_len <= self.len);
195 /// Reduce allocated capacity to `new_len`.
196 pub fn shrinkAndFree(self: *Self, new_len: usize) void {
197 assert(new_len <= self.items.len);
198
199 // Cannot shrink to smaller than the current queue size without invalidating the heap property
200 assert(new_len >= self.len);
201
202 self.items = self.allocator.realloc(self.items[0..], new_len) catch |e| switch (e) {
203 error.OutOfMemory => { // no problem, capacity is still correct then.
204 self.items.len = new_len;
205 return;
206 },
207 };
208 self.len = new_len;
209 }
210
211 /// Reduce length to `new_len`.
212 pub fn shrinkRetainingCapacity(self: *Self, new_len: usize) void {
213 assert(new_len <= self.items.len);
214
215 // Cannot shrink to smaller than the current queue size without invalidating the heap property
216 assert(new_len >= self.len);
217
198218 self.len = new_len;
199219 }
200220
......@@ -477,6 +497,33 @@ test "std.PriorityQueue: iterator while empty" {
477497 expectEqual(it.next(), null);
478498}
479499
500test "std.PriorityQueue: shrinkRetainingCapacity and shrinkAndFree" {
501 var queue = PQ.init(testing.allocator, lessThan);
502 defer queue.deinit();
503
504 try queue.ensureCapacity(4);
505 expect(queue.capacity() >= 4);
506
507 try queue.add(1);
508 try queue.add(2);
509 try queue.add(3);
510 expect(queue.capacity() >= 4);
511 expectEqual(@as(usize, 3), queue.len);
512
513 queue.shrinkRetainingCapacity(3);
514 expect(queue.capacity() >= 4);
515 expectEqual(@as(usize, 3), queue.len);
516
517 queue.shrinkAndFree(3);
518 expectEqual(@as(usize, 3), queue.capacity());
519 expectEqual(@as(usize, 3), queue.len);
520
521 expectEqual(@as(u32, 1), queue.remove());
522 expectEqual(@as(u32, 2), queue.remove());
523 expectEqual(@as(u32, 3), queue.remove());
524 expect(queue.removeOrNull() == null);
525}
526
480527test "std.PriorityQueue: update min heap" {
481528 var queue = PQ.init(testing.allocator, lessThan);
482529 defer queue.deinit();