| ... | ... | @@ -449,17 +449,20 @@ pub fn PriorityDequeue(comptime T: type, comptime Context: type, comptime compar |
| 449 | 449 | }; |
| 450 | 450 | } |
| 451 | 451 | |
| 452 | /// If a min heap is constructed from slice `{5, 8, 2, 9, 7, 1, 4, 4}` using this |
| 453 | /// method, then the elements will be in order: {1, 2, 4, 4, 5, 7, 8, 9} |
| 452 | 454 | fn lessThanComparison(context: void, a: u32, b: u32) Order { |
| 453 | 455 | _ = context; |
| 454 | 456 | return std.math.order(a, b); |
| 455 | 457 | } |
| 456 | 458 | |
| 457 | | const PDQ = PriorityDequeue(u32, void, lessThanComparison); |
| 459 | /// Elements with lower priority will be removed first |
| 460 | const MinHeap = PriorityDequeue(u32, void, lessThanComparison); |
| 458 | 461 | |
| 459 | | test "push and pop min" { |
| 462 | test "push and pop min in min heap" { |
| 460 | 463 | const gpa = std.testing.allocator; |
| 461 | 464 | |
| 462 | | var queue: PDQ = .empty; |
| 465 | var queue: MinHeap = .empty; |
| 463 | 466 | defer queue.deinit(gpa); |
| 464 | 467 | |
| 465 | 468 | try queue.push(gpa, 54); |
| ... | ... | @@ -506,10 +509,10 @@ test "push and pop min structs" { |
| 506 | 509 | try expectEqual(@as(u32, 54), queue.popMin().?.size); |
| 507 | 510 | } |
| 508 | 511 | |
| 509 | | test "push and pop max" { |
| 512 | test "push and pop max in min heap" { |
| 510 | 513 | const gpa = std.testing.allocator; |
| 511 | 514 | |
| 512 | | var queue: PDQ = .empty; |
| 515 | var queue: MinHeap = .empty; |
| 513 | 516 | defer queue.deinit(gpa); |
| 514 | 517 | |
| 515 | 518 | try queue.push(gpa, 54); |
| ... | ... | @@ -527,10 +530,10 @@ test "push and pop max" { |
| 527 | 530 | try expectEqual(@as(u32, 7), queue.popMax()); |
| 528 | 531 | } |
| 529 | 532 | |
| 530 | | test "push and pop same min" { |
| 533 | test "push and pop same min in min heap" { |
| 531 | 534 | const gpa = std.testing.allocator; |
| 532 | 535 | |
| 533 | | var queue: PDQ = .empty; |
| 536 | var queue: MinHeap = .empty; |
| 534 | 537 | defer queue.deinit(gpa); |
| 535 | 538 | |
| 536 | 539 | try queue.push(gpa, 1); |
| ... | ... | @@ -548,10 +551,10 @@ test "push and pop same min" { |
| 548 | 551 | try expectEqual(@as(u32, 2), queue.popMin()); |
| 549 | 552 | } |
| 550 | 553 | |
| 551 | | test "push and pop same max" { |
| 554 | test "push and pop same max in min heap" { |
| 552 | 555 | const gpa = std.testing.allocator; |
| 553 | 556 | |
| 554 | | var queue: PDQ = .empty; |
| 557 | var queue: MinHeap = .empty; |
| 555 | 558 | defer queue.deinit(gpa); |
| 556 | 559 | |
| 557 | 560 | try queue.push(gpa, 1); |
| ... | ... | @@ -569,20 +572,20 @@ test "push and pop same max" { |
| 569 | 572 | try expectEqual(@as(u32, 1), queue.popMax()); |
| 570 | 573 | } |
| 571 | 574 | |
| 572 | | test "popOrNull empty" { |
| 575 | test "pop empty in min heap" { |
| 573 | 576 | const gpa = std.testing.allocator; |
| 574 | 577 | |
| 575 | | var queue: PDQ = .empty; |
| 578 | var queue: MinHeap = .empty; |
| 576 | 579 | defer queue.deinit(gpa); |
| 577 | 580 | |
| 578 | 581 | try expect(queue.popMin() == null); |
| 579 | 582 | try expect(queue.popMax() == null); |
| 580 | 583 | } |
| 581 | 584 | |
| 582 | | test "edge case 3 elements" { |
| 585 | test "edge case 3 elements popMin in min heap" { |
| 583 | 586 | const gpa = std.testing.allocator; |
| 584 | 587 | |
| 585 | | var queue: PDQ = .empty; |
| 588 | var queue: MinHeap = .empty; |
| 586 | 589 | defer queue.deinit(gpa); |
| 587 | 590 | |
| 588 | 591 | try queue.push(gpa, 9); |
| ... | ... | @@ -594,10 +597,10 @@ test "edge case 3 elements" { |
| 594 | 597 | try expectEqual(@as(u32, 9), queue.popMin()); |
| 595 | 598 | } |
| 596 | 599 | |
| 597 | | test "edge case 3 elements max" { |
| 600 | test "edge case 3 elements popmax in min heap" { |
| 598 | 601 | const gpa = std.testing.allocator; |
| 599 | 602 | |
| 600 | | var queue: PDQ = .empty; |
| 603 | var queue: MinHeap = .empty; |
| 601 | 604 | defer queue.deinit(gpa); |
| 602 | 605 | |
| 603 | 606 | try queue.push(gpa, 9); |
| ... | ... | @@ -609,10 +612,10 @@ test "edge case 3 elements max" { |
| 609 | 612 | try expectEqual(@as(u32, 2), queue.popMax()); |
| 610 | 613 | } |
| 611 | 614 | |
| 612 | | test "peekMin" { |
| 615 | test "peekMin in min heap" { |
| 613 | 616 | const gpa = std.testing.allocator; |
| 614 | 617 | |
| 615 | | var queue: PDQ = .empty; |
| 618 | var queue: MinHeap = .empty; |
| 616 | 619 | defer queue.deinit(gpa); |
| 617 | 620 | |
| 618 | 621 | try expect(queue.peekMin() == null); |
| ... | ... | @@ -625,10 +628,10 @@ test "peekMin" { |
| 625 | 628 | try expect(queue.peekMin().? == 2); |
| 626 | 629 | } |
| 627 | 630 | |
| 628 | | test "peekMax" { |
| 631 | test "peekMax in min heap" { |
| 629 | 632 | const gpa = std.testing.allocator; |
| 630 | 633 | |
| 631 | | var queue: PDQ = .empty; |
| 634 | var queue: MinHeap = .empty; |
| 632 | 635 | defer queue.deinit(gpa); |
| 633 | 636 | |
| 634 | 637 | try expect(queue.peekMin() == null); |
| ... | ... | @@ -641,10 +644,10 @@ test "peekMax" { |
| 641 | 644 | try expect(queue.peekMax().? == 9); |
| 642 | 645 | } |
| 643 | 646 | |
| 644 | | test "sift up with odd indices, popMin" { |
| 647 | test "sift up with odd indices and popMin in min heap" { |
| 645 | 648 | const gpa = std.testing.allocator; |
| 646 | 649 | |
| 647 | | var queue: PDQ = .empty; |
| 650 | var queue: MinHeap = .empty; |
| 648 | 651 | defer queue.deinit(gpa); |
| 649 | 652 | |
| 650 | 653 | const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 }; |
| ... | ... | @@ -658,10 +661,10 @@ test "sift up with odd indices, popMin" { |
| 658 | 661 | } |
| 659 | 662 | } |
| 660 | 663 | |
| 661 | | test "sift up with odd indices, popMax" { |
| 664 | test "sift up with odd indices and popMax in min heap" { |
| 662 | 665 | const gpa = std.testing.allocator; |
| 663 | 666 | |
| 664 | | var queue: PDQ = .empty; |
| 667 | var queue: MinHeap = .empty; |
| 665 | 668 | defer queue.deinit(gpa); |
| 666 | 669 | |
| 667 | 670 | const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 }; |
| ... | ... | @@ -675,10 +678,10 @@ test "sift up with odd indices, popMax" { |
| 675 | 678 | } |
| 676 | 679 | } |
| 677 | 680 | |
| 678 | | test "pushSlice min" { |
| 681 | test "pushSlice in min heap and popMin" { |
| 679 | 682 | const gpa = std.testing.allocator; |
| 680 | 683 | |
| 681 | | var queue: PDQ = .empty; |
| 684 | var queue: MinHeap = .empty; |
| 682 | 685 | defer queue.deinit(gpa); |
| 683 | 686 | |
| 684 | 687 | const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 }; |
| ... | ... | @@ -690,10 +693,10 @@ test "pushSlice min" { |
| 690 | 693 | } |
| 691 | 694 | } |
| 692 | 695 | |
| 693 | | test "pushSlice max" { |
| 696 | test "pushSlice in min heap and popMax" { |
| 694 | 697 | const gpa = std.testing.allocator; |
| 695 | 698 | |
| 696 | | var queue: PDQ = .empty; |
| 699 | var queue: MinHeap = .empty; |
| 697 | 700 | defer queue.deinit(gpa); |
| 698 | 701 | |
| 699 | 702 | const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 }; |
| ... | ... | @@ -705,26 +708,26 @@ test "pushSlice max" { |
| 705 | 708 | } |
| 706 | 709 | } |
| 707 | 710 | |
| 708 | | test "fromOwnedSlice trivial case 0" { |
| 711 | test "fromOwnedSlice trivial case 0 min heap" { |
| 709 | 712 | const gpa = std.testing.allocator; |
| 710 | 713 | |
| 711 | 714 | const items = [0]u32{}; |
| 712 | 715 | const queue_items = try gpa.dupe(u32, &items); |
| 713 | 716 | |
| 714 | | var queue = PDQ.fromOwnedSlice(queue_items[0..], {}); |
| 717 | var queue: MinHeap = .fromOwnedSlice(queue_items[0..], {}); |
| 715 | 718 | defer queue.deinit(gpa); |
| 716 | 719 | |
| 717 | 720 | try expectEqual(@as(usize, 0), queue.len); |
| 718 | 721 | try expect(queue.popMin() == null); |
| 719 | 722 | } |
| 720 | 723 | |
| 721 | | test "fromOwnedSlice trivial case 1" { |
| 724 | test "fromOwnedSlice trivial case 1 min heap" { |
| 722 | 725 | const gpa = std.testing.allocator; |
| 723 | 726 | |
| 724 | 727 | const items = [1]u32{1}; |
| 725 | 728 | const queue_items = try gpa.dupe(u32, &items); |
| 726 | 729 | |
| 727 | | var queue = PDQ.fromOwnedSlice(queue_items[0..], {}); |
| 730 | var queue: MinHeap = .fromOwnedSlice(queue_items[0..], {}); |
| 728 | 731 | defer queue.deinit(gpa); |
| 729 | 732 | |
| 730 | 733 | try expectEqual(@as(usize, 1), queue.len); |
| ... | ... | @@ -732,13 +735,13 @@ test "fromOwnedSlice trivial case 1" { |
| 732 | 735 | try expect(queue.popMin() == null); |
| 733 | 736 | } |
| 734 | 737 | |
| 735 | | test "fromOwnedSlice" { |
| 738 | test "fromOwnedSlice min heap" { |
| 736 | 739 | const gpa = std.testing.allocator; |
| 737 | 740 | |
| 738 | 741 | const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 }; |
| 739 | 742 | const queue_items = try gpa.dupe(u32, items[0..]); |
| 740 | 743 | |
| 741 | | var queue = PDQ.fromOwnedSlice(queue_items[0..], {}); |
| 744 | var queue: MinHeap = .fromOwnedSlice(queue_items[0..], {}); |
| 742 | 745 | defer queue.deinit(gpa); |
| 743 | 746 | |
| 744 | 747 | const sorted_items = [_]u32{ 1, 2, 5, 6, 7, 7, 11, 12, 13, 14, 15, 15, 16, 21, 22, 24, 24, 25 }; |
| ... | ... | @@ -747,10 +750,10 @@ test "fromOwnedSlice" { |
| 747 | 750 | } |
| 748 | 751 | } |
| 749 | 752 | |
| 750 | | test "update min queue" { |
| 753 | test "update and popMin in min heap" { |
| 751 | 754 | const gpa = std.testing.allocator; |
| 752 | 755 | |
| 753 | | var queue: PDQ = .empty; |
| 756 | var queue: MinHeap = .empty; |
| 754 | 757 | defer queue.deinit(gpa); |
| 755 | 758 | |
| 756 | 759 | try queue.push(gpa, 55); |
| ... | ... | @@ -764,10 +767,10 @@ test "update min queue" { |
| 764 | 767 | try expectEqual(@as(u32, 5), queue.popMin()); |
| 765 | 768 | } |
| 766 | 769 | |
| 767 | | test "update same min queue" { |
| 770 | test "update same element and popMin in min heap" { |
| 768 | 771 | const gpa = std.testing.allocator; |
| 769 | 772 | |
| 770 | | var queue: PDQ = .empty; |
| 773 | var queue: MinHeap = .empty; |
| 771 | 774 | defer queue.deinit(gpa); |
| 772 | 775 | |
| 773 | 776 | try queue.push(gpa, 1); |
| ... | ... | @@ -782,10 +785,10 @@ test "update same min queue" { |
| 782 | 785 | try expectEqual(@as(u32, 5), queue.popMin()); |
| 783 | 786 | } |
| 784 | 787 | |
| 785 | | test "update max queue" { |
| 788 | test "update and popMax in min heap" { |
| 786 | 789 | const gpa = std.testing.allocator; |
| 787 | 790 | |
| 788 | | var queue: PDQ = .empty; |
| 791 | var queue: MinHeap = .empty; |
| 789 | 792 | defer queue.deinit(gpa); |
| 790 | 793 | |
| 791 | 794 | try queue.push(gpa, 55); |
| ... | ... | @@ -800,10 +803,10 @@ test "update max queue" { |
| 800 | 803 | try expectEqual(@as(u32, 1), queue.popMax()); |
| 801 | 804 | } |
| 802 | 805 | |
| 803 | | test "update same max queue" { |
| 806 | test "update same element and popMax in min heap" { |
| 804 | 807 | const gpa = std.testing.allocator; |
| 805 | 808 | |
| 806 | | var queue: PDQ = .empty; |
| 809 | var queue: MinHeap = .empty; |
| 807 | 810 | defer queue.deinit(gpa); |
| 808 | 811 | |
| 809 | 812 | try queue.push(gpa, 1); |
| ... | ... | @@ -818,10 +821,10 @@ test "update same max queue" { |
| 818 | 821 | try expectEqual(@as(u32, 1), queue.popMax()); |
| 819 | 822 | } |
| 820 | 823 | |
| 821 | | test "update after pop" { |
| 824 | test "update after pop in min heap" { |
| 822 | 825 | const gpa = std.testing.allocator; |
| 823 | 826 | |
| 824 | | var queue: PDQ = .empty; |
| 827 | var queue: MinHeap = .empty; |
| 825 | 828 | defer queue.deinit(gpa); |
| 826 | 829 | |
| 827 | 830 | try queue.push(gpa, 1); |
| ... | ... | @@ -829,10 +832,10 @@ test "update after pop" { |
| 829 | 832 | try expectError(error.ElementNotFound, queue.update(1, 1)); |
| 830 | 833 | } |
| 831 | 834 | |
| 832 | | test "iterator" { |
| 835 | test "min heap iterator" { |
| 833 | 836 | const gpa = std.testing.allocator; |
| 834 | 837 | |
| 835 | | var queue: PDQ = .empty; |
| 838 | var queue: MinHeap = .empty; |
| 836 | 839 | var map = std.AutoHashMap(u32, void).init(testing.allocator); |
| 837 | 840 | defer { |
| 838 | 841 | queue.deinit(gpa); |
| ... | ... | @@ -853,10 +856,10 @@ test "iterator" { |
| 853 | 856 | try expectEqual(@as(usize, 0), map.count()); |
| 854 | 857 | } |
| 855 | 858 | |
| 856 | | test "pop at index" { |
| 859 | test "pop at index in min heap" { |
| 857 | 860 | const gpa = std.testing.allocator; |
| 858 | 861 | |
| 859 | | var queue: PDQ = .empty; |
| 862 | var queue: MinHeap = .empty; |
| 860 | 863 | defer queue.deinit(gpa); |
| 861 | 864 | |
| 862 | 865 | try queue.push(gpa, 3); |
| ... | ... | @@ -878,10 +881,10 @@ test "pop at index" { |
| 878 | 881 | try expectEqual(queue.popMin(), null); |
| 879 | 882 | } |
| 880 | 883 | |
| 881 | | test "iterator while empty" { |
| 884 | test "min heap iterator while empty" { |
| 882 | 885 | const gpa = std.testing.allocator; |
| 883 | 886 | |
| 884 | | var queue: PDQ = .empty; |
| 887 | var queue: MinHeap = .empty; |
| 885 | 888 | defer queue.deinit(gpa); |
| 886 | 889 | |
| 887 | 890 | var it = queue.iterator(); |
| ... | ... | @@ -889,10 +892,10 @@ test "iterator while empty" { |
| 889 | 892 | try expectEqual(it.next(), null); |
| 890 | 893 | } |
| 891 | 894 | |
| 892 | | test "shrinkAndFree" { |
| 895 | test "min heap shrinkAndFree" { |
| 893 | 896 | const gpa = std.testing.allocator; |
| 894 | 897 | |
| 895 | | var queue: PDQ = .empty; |
| 898 | var queue: MinHeap = .empty; |
| 896 | 899 | defer queue.deinit(gpa); |
| 897 | 900 | |
| 898 | 901 | try queue.ensureTotalCapacity(gpa, 4); |
| ... | ... | @@ -932,7 +935,7 @@ fn fuzzTestMin(rng: std.Random, comptime queue_size: usize) !void { |
| 932 | 935 | |
| 933 | 936 | const items = try generateRandomSlice(gpa, rng, queue_size); |
| 934 | 937 | |
| 935 | | var queue = PDQ.fromOwnedSlice(items, {}); |
| 938 | var queue: MinHeap = .fromOwnedSlice(items, {}); |
| 936 | 939 | defer queue.deinit(gpa); |
| 937 | 940 | |
| 938 | 941 | var last_removed: ?u32 = null; |
| ... | ... | @@ -962,7 +965,7 @@ fn fuzzTestMax(rng: std.Random, queue_size: usize) !void { |
| 962 | 965 | |
| 963 | 966 | const items = try generateRandomSlice(gpa, rng, queue_size); |
| 964 | 967 | |
| 965 | | var queue = PDQ.fromOwnedSlice(items, {}); |
| 968 | var queue: MinHeap = .fromOwnedSlice(items, {}); |
| 966 | 969 | defer queue.deinit(gpa); |
| 967 | 970 | |
| 968 | 971 | var last_removed: ?u32 = null; |
| ... | ... | @@ -992,7 +995,7 @@ fn fuzzTestMinMax(rng: std.Random, queue_size: usize) !void { |
| 992 | 995 | |
| 993 | 996 | const items = try generateRandomSlice(gpa, rng, queue_size); |
| 994 | 997 | |
| 995 | | var queue = PDQ.fromOwnedSlice(items, {}); |
| 998 | var queue: MinHeap = .fromOwnedSlice(items, {}); |
| 996 | 999 | defer queue.deinit(gpa); |
| 997 | 1000 | |
| 998 | 1001 | var last_min: ?u32 = null; |
| ... | ... | @@ -1032,14 +1035,14 @@ fn contextLessThanComparison(context: []const u32, a: usize, b: usize) Order { |
| 1032 | 1035 | return std.math.order(context[a], context[b]); |
| 1033 | 1036 | } |
| 1034 | 1037 | |
| 1035 | | const CPDQ = PriorityDequeue(usize, []const u32, contextLessThanComparison); |
| 1038 | const MinHeapWithContext = PriorityDequeue(usize, []const u32, contextLessThanComparison); |
| 1036 | 1039 | |
| 1037 | 1040 | test "push and pop" { |
| 1038 | 1041 | const gpa = std.testing.allocator; |
| 1039 | 1042 | |
| 1040 | 1043 | const context = [_]u32{ 5, 3, 4, 2, 2, 8, 0 }; |
| 1041 | 1044 | |
| 1042 | | var queue: CPDQ = .initContext(context[0..]); |
| 1045 | var queue: MinHeapWithContext = .initContext(context[0..]); |
| 1043 | 1046 | defer queue.deinit(gpa); |
| 1044 | 1047 | |
| 1045 | 1048 | try queue.push(gpa, 0); |