authorgravatar for saurabh.m@proton.meSaurabh Mishra <saurabh.m@proton.me> 2026-02-18 11:20:32-08:00
committergravatar for saurabh.m@proton.meSaurabh Mishra <saurabh.m@proton.me> 2026-02-18 11:20:32-08:00
logd297f7b8f2f598967a8b91a45df1b1932dd3c81d
treef25a5a5c140588f96741c5aba641d3a4215991a6
parent0e3c6514a4d1f89498bf411b58131d129218807f

make priority dequeue an unmanaged container and ensure tests pass


1 files changed, 237 insertions(+), 175 deletions(-)

lib/std/priority_dequeue.zig+237-175
...@@ -21,33 +21,31 @@ pub fn PriorityDequeue(comptime T: type, comptime Context: type, comptime compar...@@ -21,33 +21,31 @@ pub fn PriorityDequeue(comptime T: type, comptime Context: type, comptime compar
2121
22 items: []T,22 items: []T,
23 len: usize,23 len: usize,
24 allocator: Allocator,
25 context: Context,24 context: Context,
2625
27 /// Initialize and return a new priority dequeue.26 /// Initialize and return a new priority dequeue.
28 pub fn init(allocator: Allocator, context: Context) Self {27 pub fn init(context: Context) Self {
29 return Self{28 return Self{
30 .items = &[_]T{},29 .items = &[_]T{},
31 .len = 0,30 .len = 0,
32 .allocator = allocator,
33 .context = context,31 .context = context,
34 };32 };
35 }33 }
3634
37 /// Free memory used by the dequeue.35 /// Free memory used by the dequeue.
38 pub fn deinit(self: Self) void {36 pub fn deinit(self: Self, allocator: Allocator) void {
39 self.allocator.free(self.items);37 allocator.free(self.items);
40 }38 }
4139
42 /// Insert a new element, maintaining priority.40 /// Insert a new element, maintaining priority.
43 pub fn add(self: *Self, elem: T) !void {41 pub fn add(self: *Self, allocator: Allocator, elem: T) !void {
44 try self.ensureUnusedCapacity(1);42 try self.ensureUnusedCapacity(allocator, 1);
45 addUnchecked(self, elem);43 addUnchecked(self, elem);
46 }44 }
4745
48 /// Add each element in `items` to the dequeue.46 /// Add each element in `items` to the dequeue.
49 pub fn addSlice(self: *Self, items: []const T) !void {47 pub fn addSlice(self: *Self, allocator: Allocator, items: []const T) !void {
50 try self.ensureUnusedCapacity(items.len);48 try self.ensureUnusedCapacity(allocator, items.len);
51 for (items) |e| {49 for (items) |e| {
52 self.addUnchecked(e);50 self.addUnchecked(e);
53 }51 }
...@@ -333,14 +331,12 @@ pub fn PriorityDequeue(comptime T: type, comptime Context: type, comptime compar...@@ -333,14 +331,12 @@ pub fn PriorityDequeue(comptime T: type, comptime Context: type, comptime compar
333 return self.items.len;331 return self.items.len;
334 }332 }
335333
336 /// Dequeue takes ownership of the passed in slice. The slice must have been334 /// Dequeue takes ownership of the passed in slice. The slice must be de-initialize
337 /// allocated with `allocator`.335 /// with `deinit`.
338 /// De-initialize with `deinit`.336 pub fn fromOwnedSlice(items: []T, context: Context) Self {
339 pub fn fromOwnedSlice(allocator: Allocator, items: []T, context: Context) Self {
340 var queue = Self{337 var queue = Self{
341 .items = items,338 .items = items,
342 .len = items.len,339 .len = items.len,
343 .allocator = allocator,
344 .context = context,340 .context = context,
345 };341 };
346342
...@@ -356,29 +352,29 @@ pub fn PriorityDequeue(comptime T: type, comptime Context: type, comptime compar...@@ -356,29 +352,29 @@ pub fn PriorityDequeue(comptime T: type, comptime Context: type, comptime compar
356 }352 }
357353
358 /// Ensure that the dequeue can fit at least `new_capacity` items.354 /// Ensure that the dequeue can fit at least `new_capacity` items.
359 pub fn ensureTotalCapacity(self: *Self, new_capacity: usize) !void {355 pub fn ensureTotalCapacity(self: *Self, allocator: Allocator, new_capacity: usize) !void {
360 var better_capacity = self.capacity();356 var better_capacity = self.capacity();
361 if (better_capacity >= new_capacity) return;357 if (better_capacity >= new_capacity) return;
362 while (true) {358 while (true) {
363 better_capacity += better_capacity / 2 + 8;359 better_capacity += better_capacity / 2 + 8;
364 if (better_capacity >= new_capacity) break;360 if (better_capacity >= new_capacity) break;
365 }361 }
366 self.items = try self.allocator.realloc(self.items, better_capacity);362 self.items = try allocator.realloc(self.items, better_capacity);
367 }363 }
368364
369 /// Ensure that the dequeue can fit at least `additional_count` **more** items.365 /// Ensure that the dequeue can fit at least `additional_count` **more** items.
370 pub fn ensureUnusedCapacity(self: *Self, additional_count: usize) !void {366 pub fn ensureUnusedCapacity(self: *Self, allocator: Allocator, additional_count: usize) !void {
371 return self.ensureTotalCapacity(self.len + additional_count);367 return self.ensureTotalCapacity(allocator, self.len + additional_count);
372 }368 }
373369
374 /// Reduce allocated capacity to `new_len`.370 /// Reduce allocated capacity to `new_len`.
375 pub fn shrinkAndFree(self: *Self, new_len: usize) void {371 pub fn shrinkAndFree(self: *Self, allocator: Allocator, new_len: usize) void {
376 assert(new_len <= self.items.len);372 assert(new_len <= self.items.len);
377373
378 // Cannot shrink to smaller than the current queue size without invalidating the heap property374 // Cannot shrink to smaller than the current queue size without invalidating the heap property
379 assert(new_len >= self.len);375 assert(new_len >= self.len);
380376
381 self.items = self.allocator.realloc(self.items[0..], new_len) catch |e| switch (e) {377 self.items = allocator.realloc(self.items[0..], new_len) catch |e| switch (e) {
382 error.OutOfMemory => { // no problem, capacity is still correct then.378 error.OutOfMemory => { // no problem, capacity is still correct then.
383 self.items.len = new_len;379 self.items.len = new_len;
384 return;380 return;
...@@ -468,15 +464,16 @@ fn lessThanComparison(context: void, a: u32, b: u32) Order {...@@ -468,15 +464,16 @@ fn lessThanComparison(context: void, a: u32, b: u32) Order {
468const PDQ = PriorityDequeue(u32, void, lessThanComparison);464const PDQ = PriorityDequeue(u32, void, lessThanComparison);
469465
470test "add and remove min" {466test "add and remove min" {
471 var queue = PDQ.init(testing.allocator, {});467 const gpa = std.testing.allocator;
472 defer queue.deinit();468 var queue = PDQ.init({});
469 defer queue.deinit(gpa);
473470
474 try queue.add(54);471 try queue.add(gpa, 54);
475 try queue.add(12);472 try queue.add(gpa, 12);
476 try queue.add(7);473 try queue.add(gpa, 7);
477 try queue.add(23);474 try queue.add(gpa, 23);
478 try queue.add(25);475 try queue.add(gpa, 25);
479 try queue.add(13);476 try queue.add(gpa, 13);
480477
481 try expectEqual(@as(u32, 7), queue.removeMin());478 try expectEqual(@as(u32, 7), queue.removeMin());
482 try expectEqual(@as(u32, 12), queue.removeMin());479 try expectEqual(@as(u32, 12), queue.removeMin());
...@@ -487,6 +484,8 @@ test "add and remove min" {...@@ -487,6 +484,8 @@ test "add and remove min" {
487}484}
488485
489test "add and remove min structs" {486test "add and remove min structs" {
487 const gpa = std.testing.allocator;
488
490 const S = struct {489 const S = struct {
491 size: u32,490 size: u32,
492 };491 };
...@@ -495,15 +494,15 @@ test "add and remove min structs" {...@@ -495,15 +494,15 @@ test "add and remove min structs" {
495 _ = context;494 _ = context;
496 return std.math.order(a.size, b.size);495 return std.math.order(a.size, b.size);
497 }496 }
498 }.order).init(testing.allocator, {});497 }.order).init({});
499 defer queue.deinit();498 defer queue.deinit(gpa);
500499
501 try queue.add(.{ .size = 54 });500 try queue.add(gpa, .{ .size = 54 });
502 try queue.add(.{ .size = 12 });501 try queue.add(gpa, .{ .size = 12 });
503 try queue.add(.{ .size = 7 });502 try queue.add(gpa, .{ .size = 7 });
504 try queue.add(.{ .size = 23 });503 try queue.add(gpa, .{ .size = 23 });
505 try queue.add(.{ .size = 25 });504 try queue.add(gpa, .{ .size = 25 });
506 try queue.add(.{ .size = 13 });505 try queue.add(gpa, .{ .size = 13 });
507506
508 try expectEqual(@as(u32, 7), queue.removeMin().size);507 try expectEqual(@as(u32, 7), queue.removeMin().size);
509 try expectEqual(@as(u32, 12), queue.removeMin().size);508 try expectEqual(@as(u32, 12), queue.removeMin().size);
...@@ -514,15 +513,17 @@ test "add and remove min structs" {...@@ -514,15 +513,17 @@ test "add and remove min structs" {
514}513}
515514
516test "add and remove max" {515test "add and remove max" {
517 var queue = PDQ.init(testing.allocator, {});516 const gpa = std.testing.allocator;
518 defer queue.deinit();517
518 var queue = PDQ.init({});
519 defer queue.deinit(gpa);
519520
520 try queue.add(54);521 try queue.add(gpa, 54);
521 try queue.add(12);522 try queue.add(gpa, 12);
522 try queue.add(7);523 try queue.add(gpa, 7);
523 try queue.add(23);524 try queue.add(gpa, 23);
524 try queue.add(25);525 try queue.add(gpa, 25);
525 try queue.add(13);526 try queue.add(gpa, 13);
526527
527 try expectEqual(@as(u32, 54), queue.removeMax());528 try expectEqual(@as(u32, 54), queue.removeMax());
528 try expectEqual(@as(u32, 25), queue.removeMax());529 try expectEqual(@as(u32, 25), queue.removeMax());
...@@ -533,15 +534,17 @@ test "add and remove max" {...@@ -533,15 +534,17 @@ test "add and remove max" {
533}534}
534535
535test "add and remove same min" {536test "add and remove same min" {
536 var queue = PDQ.init(testing.allocator, {});537 const gpa = std.testing.allocator;
537 defer queue.deinit();538
539 var queue = PDQ.init({});
540 defer queue.deinit(gpa);
538541
539 try queue.add(1);542 try queue.add(gpa, 1);
540 try queue.add(1);543 try queue.add(gpa, 1);
541 try queue.add(2);544 try queue.add(gpa, 2);
542 try queue.add(2);545 try queue.add(gpa, 2);
543 try queue.add(1);546 try queue.add(gpa, 1);
544 try queue.add(1);547 try queue.add(gpa, 1);
545548
546 try expectEqual(@as(u32, 1), queue.removeMin());549 try expectEqual(@as(u32, 1), queue.removeMin());
547 try expectEqual(@as(u32, 1), queue.removeMin());550 try expectEqual(@as(u32, 1), queue.removeMin());
...@@ -552,15 +555,17 @@ test "add and remove same min" {...@@ -552,15 +555,17 @@ test "add and remove same min" {
552}555}
553556
554test "add and remove same max" {557test "add and remove same max" {
555 var queue = PDQ.init(testing.allocator, {});558 const gpa = std.testing.allocator;
556 defer queue.deinit();
557559
558 try queue.add(1);560 var queue = PDQ.init({});
559 try queue.add(1);561 defer queue.deinit(gpa);
560 try queue.add(2);562
561 try queue.add(2);563 try queue.add(gpa, 1);
562 try queue.add(1);564 try queue.add(gpa, 1);
563 try queue.add(1);565 try queue.add(gpa, 2);
566 try queue.add(gpa, 2);
567 try queue.add(gpa, 1);
568 try queue.add(gpa, 1);
564569
565 try expectEqual(@as(u32, 2), queue.removeMax());570 try expectEqual(@as(u32, 2), queue.removeMax());
566 try expectEqual(@as(u32, 2), queue.removeMax());571 try expectEqual(@as(u32, 2), queue.removeMax());
...@@ -571,20 +576,24 @@ test "add and remove same max" {...@@ -571,20 +576,24 @@ test "add and remove same max" {
571}576}
572577
573test "removeOrNull empty" {578test "removeOrNull empty" {
574 var queue = PDQ.init(testing.allocator, {});579 const gpa = std.testing.allocator;
575 defer queue.deinit();580
581 var queue = PDQ.init({});
582 defer queue.deinit(gpa);
576583
577 try expect(queue.removeMinOrNull() == null);584 try expect(queue.removeMinOrNull() == null);
578 try expect(queue.removeMaxOrNull() == null);585 try expect(queue.removeMaxOrNull() == null);
579}586}
580587
581test "edge case 3 elements" {588test "edge case 3 elements" {
582 var queue = PDQ.init(testing.allocator, {});589 const gpa = std.testing.allocator;
583 defer queue.deinit();
584590
585 try queue.add(9);591 var queue = PDQ.init({});
586 try queue.add(3);592 defer queue.deinit(gpa);
587 try queue.add(2);593
594 try queue.add(gpa, 9);
595 try queue.add(gpa, 3);
596 try queue.add(gpa, 2);
588597
589 try expectEqual(@as(u32, 2), queue.removeMin());598 try expectEqual(@as(u32, 2), queue.removeMin());
590 try expectEqual(@as(u32, 3), queue.removeMin());599 try expectEqual(@as(u32, 3), queue.removeMin());
...@@ -592,12 +601,14 @@ test "edge case 3 elements" {...@@ -592,12 +601,14 @@ test "edge case 3 elements" {
592}601}
593602
594test "edge case 3 elements max" {603test "edge case 3 elements max" {
595 var queue = PDQ.init(testing.allocator, {});604 const gpa = std.testing.allocator;
596 defer queue.deinit();605
606 var queue = PDQ.init({});
607 defer queue.deinit(gpa);
597608
598 try queue.add(9);609 try queue.add(gpa, 9);
599 try queue.add(3);610 try queue.add(gpa, 3);
600 try queue.add(2);611 try queue.add(gpa, 2);
601612
602 try expectEqual(@as(u32, 9), queue.removeMax());613 try expectEqual(@as(u32, 9), queue.removeMax());
603 try expectEqual(@as(u32, 3), queue.removeMax());614 try expectEqual(@as(u32, 3), queue.removeMax());
...@@ -605,39 +616,46 @@ test "edge case 3 elements max" {...@@ -605,39 +616,46 @@ test "edge case 3 elements max" {
605}616}
606617
607test "peekMin" {618test "peekMin" {
608 var queue = PDQ.init(testing.allocator, {});619 const gpa = std.testing.allocator;
609 defer queue.deinit();620
621 var queue = PDQ.init({});
622 defer queue.deinit(gpa);
610623
611 try expect(queue.peekMin() == null);624 try expect(queue.peekMin() == null);
612625
613 try queue.add(9);626 try queue.add(gpa, 9);
614 try queue.add(3);627 try queue.add(gpa, 3);
615 try queue.add(2);628 try queue.add(gpa, 2);
616629
617 try expect(queue.peekMin().? == 2);630 try expect(queue.peekMin().? == 2);
618 try expect(queue.peekMin().? == 2);631 try expect(queue.peekMin().? == 2);
619}632}
620633
621test "peekMax" {634test "peekMax" {
622 var queue = PDQ.init(testing.allocator, {});635 const gpa = std.testing.allocator;
623 defer queue.deinit();636
637 var queue = PDQ.init({});
638 defer queue.deinit(gpa);
624639
625 try expect(queue.peekMin() == null);640 try expect(queue.peekMin() == null);
626641
627 try queue.add(9);642 try queue.add(gpa, 9);
628 try queue.add(3);643 try queue.add(gpa, 3);
629 try queue.add(2);644 try queue.add(gpa, 2);
630645
631 try expect(queue.peekMax().? == 9);646 try expect(queue.peekMax().? == 9);
632 try expect(queue.peekMax().? == 9);647 try expect(queue.peekMax().? == 9);
633}648}
634649
635test "sift up with odd indices, removeMin" {650test "sift up with odd indices, removeMin" {
636 var queue = PDQ.init(testing.allocator, {});651 const gpa = std.testing.allocator;
637 defer queue.deinit();652
653 var queue = PDQ.init({});
654 defer queue.deinit(gpa);
655
638 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };656 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
639 for (items) |e| {657 for (items) |e| {
640 try queue.add(e);658 try queue.add(gpa, e);
641 }659 }
642660
643 const sorted_items = [_]u32{ 1, 2, 5, 6, 7, 7, 11, 12, 13, 14, 15, 15, 16, 21, 22, 24, 24, 25 };661 const sorted_items = [_]u32{ 1, 2, 5, 6, 7, 7, 11, 12, 13, 14, 15, 15, 16, 21, 22, 24, 24, 25 };
...@@ -647,11 +665,14 @@ test "sift up with odd indices, removeMin" {...@@ -647,11 +665,14 @@ test "sift up with odd indices, removeMin" {
647}665}
648666
649test "sift up with odd indices, removeMax" {667test "sift up with odd indices, removeMax" {
650 var queue = PDQ.init(testing.allocator, {});668 const gpa = std.testing.allocator;
651 defer queue.deinit();669
670 var queue = PDQ.init({});
671 defer queue.deinit(gpa);
672
652 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };673 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
653 for (items) |e| {674 for (items) |e| {
654 try queue.add(e);675 try queue.add(gpa, e);
655 }676 }
656677
657 const sorted_items = [_]u32{ 25, 24, 24, 22, 21, 16, 15, 15, 14, 13, 12, 11, 7, 7, 6, 5, 2, 1 };678 const sorted_items = [_]u32{ 25, 24, 24, 22, 21, 16, 15, 15, 14, 13, 12, 11, 7, 7, 6, 5, 2, 1 };
...@@ -661,10 +682,13 @@ test "sift up with odd indices, removeMax" {...@@ -661,10 +682,13 @@ test "sift up with odd indices, removeMax" {
661}682}
662683
663test "addSlice min" {684test "addSlice min" {
664 var queue = PDQ.init(testing.allocator, {});685 const gpa = std.testing.allocator;
665 defer queue.deinit();686
687 var queue = PDQ.init({});
688 defer queue.deinit(gpa);
689
666 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };690 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
667 try queue.addSlice(items[0..]);691 try queue.addSlice(gpa, items[0..]);
668692
669 const sorted_items = [_]u32{ 1, 2, 5, 6, 7, 7, 11, 12, 13, 14, 15, 15, 16, 21, 22, 24, 24, 25 };693 const sorted_items = [_]u32{ 1, 2, 5, 6, 7, 7, 11, 12, 13, 14, 15, 15, 16, 21, 22, 24, 24, 25 };
670 for (sorted_items) |e| {694 for (sorted_items) |e| {
...@@ -673,10 +697,13 @@ test "addSlice min" {...@@ -673,10 +697,13 @@ test "addSlice min" {
673}697}
674698
675test "addSlice max" {699test "addSlice max" {
676 var queue = PDQ.init(testing.allocator, {});700 const gpa = std.testing.allocator;
677 defer queue.deinit();701
702 var queue = PDQ.init({});
703 defer queue.deinit(gpa);
704
678 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };705 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
679 try queue.addSlice(items[0..]);706 try queue.addSlice(gpa, items[0..]);
680707
681 const sorted_items = [_]u32{ 25, 24, 24, 22, 21, 16, 15, 15, 14, 13, 12, 11, 7, 7, 6, 5, 2, 1 };708 const sorted_items = [_]u32{ 25, 24, 24, 22, 21, 16, 15, 15, 14, 13, 12, 11, 7, 7, 6, 5, 2, 1 };
682 for (sorted_items) |e| {709 for (sorted_items) |e| {
...@@ -685,19 +712,26 @@ test "addSlice max" {...@@ -685,19 +712,26 @@ test "addSlice max" {
685}712}
686713
687test "fromOwnedSlice trivial case 0" {714test "fromOwnedSlice trivial case 0" {
715 const gpa = std.testing.allocator;
716
688 const items = [0]u32{};717 const items = [0]u32{};
689 const queue_items = try testing.allocator.dupe(u32, &items);718 const queue_items = try gpa.dupe(u32, &items);
690 var queue = PDQ.fromOwnedSlice(testing.allocator, queue_items[0..], {});719
691 defer queue.deinit();720 var queue = PDQ.fromOwnedSlice(queue_items[0..], {});
721 defer queue.deinit(gpa);
722
692 try expectEqual(@as(usize, 0), queue.len);723 try expectEqual(@as(usize, 0), queue.len);
693 try expect(queue.removeMinOrNull() == null);724 try expect(queue.removeMinOrNull() == null);
694}725}
695726
696test "fromOwnedSlice trivial case 1" {727test "fromOwnedSlice trivial case 1" {
728 const gpa = std.testing.allocator;
729
697 const items = [1]u32{1};730 const items = [1]u32{1};
698 const queue_items = try testing.allocator.dupe(u32, &items);731 const queue_items = try gpa.dupe(u32, &items);
699 var queue = PDQ.fromOwnedSlice(testing.allocator, queue_items[0..], {});732
700 defer queue.deinit();733 var queue = PDQ.fromOwnedSlice(queue_items[0..], {});
734 defer queue.deinit(gpa);
701735
702 try expectEqual(@as(usize, 1), queue.len);736 try expectEqual(@as(usize, 1), queue.len);
703 try expectEqual(items[0], queue.removeMin());737 try expectEqual(items[0], queue.removeMin());
...@@ -705,10 +739,13 @@ test "fromOwnedSlice trivial case 1" {...@@ -705,10 +739,13 @@ test "fromOwnedSlice trivial case 1" {
705}739}
706740
707test "fromOwnedSlice" {741test "fromOwnedSlice" {
742 const gpa = std.testing.allocator;
743
708 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };744 const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
709 const queue_items = try testing.allocator.dupe(u32, items[0..]);745 const queue_items = try gpa.dupe(u32, items[0..]);
710 var queue = PDQ.fromOwnedSlice(testing.allocator, queue_items[0..], {});746
711 defer queue.deinit();747 var queue = PDQ.fromOwnedSlice(queue_items[0..], {});
748 defer queue.deinit(gpa);
712749
713 const sorted_items = [_]u32{ 1, 2, 5, 6, 7, 7, 11, 12, 13, 14, 15, 15, 16, 21, 22, 24, 24, 25 };750 const sorted_items = [_]u32{ 1, 2, 5, 6, 7, 7, 11, 12, 13, 14, 15, 15, 16, 21, 22, 24, 24, 25 };
714 for (sorted_items) |e| {751 for (sorted_items) |e| {
...@@ -717,12 +754,14 @@ test "fromOwnedSlice" {...@@ -717,12 +754,14 @@ test "fromOwnedSlice" {
717}754}
718755
719test "update min queue" {756test "update min queue" {
720 var queue = PDQ.init(testing.allocator, {});757 const gpa = std.testing.allocator;
721 defer queue.deinit();
722758
723 try queue.add(55);759 var queue = PDQ.init({});
724 try queue.add(44);760 defer queue.deinit(gpa);
725 try queue.add(11);761
762 try queue.add(gpa, 55);
763 try queue.add(gpa, 44);
764 try queue.add(gpa, 11);
726 try queue.update(55, 5);765 try queue.update(55, 5);
727 try queue.update(44, 4);766 try queue.update(44, 4);
728 try queue.update(11, 1);767 try queue.update(11, 1);
...@@ -732,13 +771,15 @@ test "update min queue" {...@@ -732,13 +771,15 @@ test "update min queue" {
732}771}
733772
734test "update same min queue" {773test "update same min queue" {
735 var queue = PDQ.init(testing.allocator, {});774 const gpa = std.testing.allocator;
736 defer queue.deinit();775
776 var queue = PDQ.init({});
777 defer queue.deinit(gpa);
737778
738 try queue.add(1);779 try queue.add(gpa, 1);
739 try queue.add(1);780 try queue.add(gpa, 1);
740 try queue.add(2);781 try queue.add(gpa, 2);
741 try queue.add(2);782 try queue.add(gpa, 2);
742 try queue.update(1, 5);783 try queue.update(1, 5);
743 try queue.update(2, 4);784 try queue.update(2, 4);
744 try expectEqual(@as(u32, 1), queue.removeMin());785 try expectEqual(@as(u32, 1), queue.removeMin());
...@@ -748,12 +789,14 @@ test "update same min queue" {...@@ -748,12 +789,14 @@ test "update same min queue" {
748}789}
749790
750test "update max queue" {791test "update max queue" {
751 var queue = PDQ.init(testing.allocator, {});792 const gpa = std.testing.allocator;
752 defer queue.deinit();793
794 var queue = PDQ.init({});
795 defer queue.deinit(gpa);
753796
754 try queue.add(55);797 try queue.add(gpa, 55);
755 try queue.add(44);798 try queue.add(gpa, 44);
756 try queue.add(11);799 try queue.add(gpa, 11);
757 try queue.update(55, 5);800 try queue.update(55, 5);
758 try queue.update(44, 1);801 try queue.update(44, 1);
759 try queue.update(11, 4);802 try queue.update(11, 4);
...@@ -764,13 +807,15 @@ test "update max queue" {...@@ -764,13 +807,15 @@ test "update max queue" {
764}807}
765808
766test "update same max queue" {809test "update same max queue" {
767 var queue = PDQ.init(testing.allocator, {});810 const gpa = std.testing.allocator;
768 defer queue.deinit();
769811
770 try queue.add(1);812 var queue = PDQ.init({});
771 try queue.add(1);813 defer queue.deinit(gpa);
772 try queue.add(2);814
773 try queue.add(2);815 try queue.add(gpa, 1);
816 try queue.add(gpa, 1);
817 try queue.add(gpa, 2);
818 try queue.add(gpa, 2);
774 try queue.update(1, 5);819 try queue.update(1, 5);
775 try queue.update(2, 4);820 try queue.update(2, 4);
776 try expectEqual(@as(u32, 5), queue.removeMax());821 try expectEqual(@as(u32, 5), queue.removeMax());
...@@ -780,25 +825,29 @@ test "update same max queue" {...@@ -780,25 +825,29 @@ test "update same max queue" {
780}825}
781826
782test "update after remove" {827test "update after remove" {
783 var queue = PDQ.init(testing.allocator, {});828 const gpa = std.testing.allocator;
784 defer queue.deinit();829
830 var queue = PDQ.init({});
831 defer queue.deinit(gpa);
785832
786 try queue.add(1);833 try queue.add(gpa, 1);
787 try expectEqual(@as(u32, 1), queue.removeMin());834 try expectEqual(@as(u32, 1), queue.removeMin());
788 try expectError(error.ElementNotFound, queue.update(1, 1));835 try expectError(error.ElementNotFound, queue.update(1, 1));
789}836}
790837
791test "iterator" {838test "iterator" {
792 var queue = PDQ.init(testing.allocator, {});839 const gpa = std.testing.allocator;
840
841 var queue = PDQ.init({});
793 var map = std.AutoHashMap(u32, void).init(testing.allocator);842 var map = std.AutoHashMap(u32, void).init(testing.allocator);
794 defer {843 defer {
795 queue.deinit();844 queue.deinit(gpa);
796 map.deinit();845 map.deinit();
797 }846 }
798847
799 const items = [_]u32{ 54, 12, 7, 23, 25, 13 };848 const items = [_]u32{ 54, 12, 7, 23, 25, 13 };
800 for (items) |e| {849 for (items) |e| {
801 _ = try queue.add(e);850 _ = try queue.add(gpa, e);
802 _ = try map.put(e, {});851 _ = try map.put(e, {});
803 }852 }
804853
...@@ -811,12 +860,14 @@ test "iterator" {...@@ -811,12 +860,14 @@ test "iterator" {
811}860}
812861
813test "remove at index" {862test "remove at index" {
814 var queue = PDQ.init(testing.allocator, {});863 const gpa = std.testing.allocator;
815 defer queue.deinit();864
865 var queue = PDQ.init({});
866 defer queue.deinit(gpa);
816867
817 try queue.add(3);868 try queue.add(gpa, 3);
818 try queue.add(2);869 try queue.add(gpa, 2);
819 try queue.add(1);870 try queue.add(gpa, 1);
820871
821 var it = queue.iterator();872 var it = queue.iterator();
822 var elem = it.next();873 var elem = it.next();
...@@ -834,8 +885,10 @@ test "remove at index" {...@@ -834,8 +885,10 @@ test "remove at index" {
834}885}
835886
836test "iterator while empty" {887test "iterator while empty" {
837 var queue = PDQ.init(testing.allocator, {});888 const gpa = std.testing.allocator;
838 defer queue.deinit();889
890 var queue = PDQ.init({});
891 defer queue.deinit(gpa);
839892
840 var it = queue.iterator();893 var it = queue.iterator();
841894
...@@ -843,19 +896,21 @@ test "iterator while empty" {...@@ -843,19 +896,21 @@ test "iterator while empty" {
843}896}
844897
845test "shrinkAndFree" {898test "shrinkAndFree" {
846 var queue = PDQ.init(testing.allocator, {});899 const gpa = std.testing.allocator;
847 defer queue.deinit();
848900
849 try queue.ensureTotalCapacity(4);901 var queue = PDQ.init({});
902 defer queue.deinit(gpa);
903
904 try queue.ensureTotalCapacity(gpa, 4);
850 try expect(queue.capacity() >= 4);905 try expect(queue.capacity() >= 4);
851906
852 try queue.add(1);907 try queue.add(gpa, 1);
853 try queue.add(2);908 try queue.add(gpa, 2);
854 try queue.add(3);909 try queue.add(gpa, 3);
855 try expect(queue.capacity() >= 4);910 try expect(queue.capacity() >= 4);
856 try expectEqual(@as(usize, 3), queue.len);911 try expectEqual(@as(usize, 3), queue.len);
857912
858 queue.shrinkAndFree(3);913 queue.shrinkAndFree(gpa, 3);
859 try expectEqual(@as(usize, 3), queue.capacity());914 try expectEqual(@as(usize, 3), queue.capacity());
860 try expectEqual(@as(usize, 3), queue.len);915 try expectEqual(@as(usize, 3), queue.len);
861916
...@@ -879,11 +934,12 @@ test "fuzz testing min" {...@@ -879,11 +934,12 @@ test "fuzz testing min" {
879}934}
880935
881fn fuzzTestMin(rng: std.Random, comptime queue_size: usize) !void {936fn fuzzTestMin(rng: std.Random, comptime queue_size: usize) !void {
882 const allocator = testing.allocator;937 const gpa = std.testing.allocator;
883 const items = try generateRandomSlice(allocator, rng, queue_size);938
939 const items = try generateRandomSlice(gpa, rng, queue_size);
884940
885 var queue = PDQ.fromOwnedSlice(allocator, items, {});941 var queue = PDQ.fromOwnedSlice(items, {});
886 defer queue.deinit();942 defer queue.deinit(gpa);
887943
888 var last_removed: ?u32 = null;944 var last_removed: ?u32 = null;
889 while (queue.removeMinOrNull()) |next| {945 while (queue.removeMinOrNull()) |next| {
...@@ -908,11 +964,12 @@ test "fuzz testing max" {...@@ -908,11 +964,12 @@ test "fuzz testing max" {
908}964}
909965
910fn fuzzTestMax(rng: std.Random, queue_size: usize) !void {966fn fuzzTestMax(rng: std.Random, queue_size: usize) !void {
911 const allocator = testing.allocator;967 const gpa = std.testing.allocator;
912 const items = try generateRandomSlice(allocator, rng, queue_size);
913968
914 var queue = PDQ.fromOwnedSlice(testing.allocator, items, {});969 const items = try generateRandomSlice(gpa, rng, queue_size);
915 defer queue.deinit();970
971 var queue = PDQ.fromOwnedSlice(items, {});
972 defer queue.deinit(gpa);
916973
917 var last_removed: ?u32 = null;974 var last_removed: ?u32 = null;
918 while (queue.removeMaxOrNull()) |next| {975 while (queue.removeMaxOrNull()) |next| {
...@@ -937,11 +994,12 @@ test "fuzz testing min and max" {...@@ -937,11 +994,12 @@ test "fuzz testing min and max" {
937}994}
938995
939fn fuzzTestMinMax(rng: std.Random, queue_size: usize) !void {996fn fuzzTestMinMax(rng: std.Random, queue_size: usize) !void {
940 const allocator = testing.allocator;997 const gpa = std.testing.allocator;
941 const items = try generateRandomSlice(allocator, rng, queue_size);998
999 const items = try generateRandomSlice(gpa, rng, queue_size);
9421000
943 var queue = PDQ.fromOwnedSlice(allocator, items, {});1001 var queue = PDQ.fromOwnedSlice(items, {});
944 defer queue.deinit();1002 defer queue.deinit(gpa);
9451003
946 var last_min: ?u32 = null;1004 var last_min: ?u32 = null;
947 var last_max: ?u32 = null;1005 var last_max: ?u32 = null;
...@@ -983,18 +1041,20 @@ fn contextLessThanComparison(context: []const u32, a: usize, b: usize) Order {...@@ -983,18 +1041,20 @@ fn contextLessThanComparison(context: []const u32, a: usize, b: usize) Order {
983const CPDQ = PriorityDequeue(usize, []const u32, contextLessThanComparison);1041const CPDQ = PriorityDequeue(usize, []const u32, contextLessThanComparison);
9841042
985test "add and remove" {1043test "add and remove" {
1044 const gpa = std.testing.allocator;
1045
986 const context = [_]u32{ 5, 3, 4, 2, 2, 8, 0 };1046 const context = [_]u32{ 5, 3, 4, 2, 2, 8, 0 };
9871047
988 var queue = CPDQ.init(testing.allocator, context[0..]);1048 var queue = CPDQ.init(context[0..]);
989 defer queue.deinit();1049 defer queue.deinit(gpa);
9901050
991 try queue.add(0);1051 try queue.add(gpa, 0);
992 try queue.add(1);1052 try queue.add(gpa, 1);
993 try queue.add(2);1053 try queue.add(gpa, 2);
994 try queue.add(3);1054 try queue.add(gpa, 3);
995 try queue.add(4);1055 try queue.add(gpa, 4);
996 try queue.add(5);1056 try queue.add(gpa, 5);
997 try queue.add(6);1057 try queue.add(gpa, 6);
998 try expectEqual(@as(usize, 6), queue.removeMin());1058 try expectEqual(@as(usize, 6), queue.removeMin());
999 try expectEqual(@as(usize, 5), queue.removeMax());1059 try expectEqual(@as(usize, 5), queue.removeMax());
1000 try expectEqual(@as(usize, 3), queue.removeMin());1060 try expectEqual(@as(usize, 3), queue.removeMin());
...@@ -1007,20 +1067,22 @@ test "add and remove" {...@@ -1007,20 +1067,22 @@ test "add and remove" {
1007var all_cmps_unique = true;1067var all_cmps_unique = true;
10081068
1009test "don't compare a value to a copy of itself" {1069test "don't compare a value to a copy of itself" {
1070 const gpa = std.testing.allocator;
1071
1010 var depq = PriorityDequeue(u32, void, struct {1072 var depq = PriorityDequeue(u32, void, struct {
1011 fn uniqueLessThan(_: void, a: u32, b: u32) Order {1073 fn uniqueLessThan(_: void, a: u32, b: u32) Order {
1012 all_cmps_unique = all_cmps_unique and (a != b);1074 all_cmps_unique = all_cmps_unique and (a != b);
1013 return std.math.order(a, b);1075 return std.math.order(a, b);
1014 }1076 }
1015 }.uniqueLessThan).init(testing.allocator, {});1077 }.uniqueLessThan).init({});
1016 defer depq.deinit();1078 defer depq.deinit(gpa);
10171079
1018 try depq.add(1);1080 try depq.add(gpa, 1);
1019 try depq.add(2);1081 try depq.add(gpa, 2);
1020 try depq.add(3);1082 try depq.add(gpa, 3);
1021 try depq.add(4);1083 try depq.add(gpa, 4);
1022 try depq.add(5);1084 try depq.add(gpa, 5);
1023 try depq.add(6);1085 try depq.add(gpa, 6);
10241086
1025 _ = depq.removeIndex(2);1087 _ = depq.removeIndex(2);
1026 try expectEqual(all_cmps_unique, true);1088 try expectEqual(all_cmps_unique, true);