| author | |
| committer | |
| log | 9a09ebb1b92f33913bdcc16e9d978fb6e5a820f1 |
| tree | 1a178892bfa500026b16a4a3434d1cc243142d9a |
| parent | e1ab425bcead727a73e4512aeca1ba9112b2c88e |
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 { |
| 382 | 382 | self.len = new_len; |
| 383 | 383 | } |
| 384 | 384 | |
| 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 | ||
| 388 | 408 | self.len = new_len; |
| 389 | 409 | } |
| 390 | 410 | |
| ... | ... | @@ -798,6 +818,33 @@ test "std.PriorityDequeue: iterator while empty" { |
| 798 | 818 | expectEqual(it.next(), null); |
| 799 | 819 | } |
| 800 | 820 | |
| 821 | test "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 | ||
| 801 | 848 | test "std.PriorityDequeue: fuzz testing min" { |
| 802 | 849 | var prng = std.rand.DefaultPrng.init(0x12345678); |
| 803 | 850 |
lib/std/priority_queue.zig+50-3| ... | ... | @@ -192,9 +192,29 @@ pub fn PriorityQueue(comptime T: type) type { |
| 192 | 192 | self.len = new_len; |
| 193 | 193 | } |
| 194 | 194 | |
| 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 | ||
| 198 | 218 | self.len = new_len; |
| 199 | 219 | } |
| 200 | 220 | |
| ... | ... | @@ -477,6 +497,33 @@ test "std.PriorityQueue: iterator while empty" { |
| 477 | 497 | expectEqual(it.next(), null); |
| 478 | 498 | } |
| 479 | 499 | |
| 500 | test "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 | ||
| 480 | 527 | test "std.PriorityQueue: update min heap" { |
| 481 | 528 | var queue = PQ.init(testing.allocator, lessThan); |
| 482 | 529 | defer queue.deinit(); |