Skip to content

fix: priority queue losing order on item removal or reversed inserting - #3404

Open
IXLLEGACYIXL wants to merge 2 commits into
stride3d:masterfrom
NexStandard:main
Open

IXLLEGACYIXL wants to merge 2 commits into
stride3d:masterfrom
NexStandard:main

Conversation

@IXLLEGACYIXL

Copy link
Copy Markdown
Collaborator

PR Details

PriorityQueue loses order on Remove/Reverse Inserting

Related Issue

fix #3398

Types of changes

internal bug fix

  • Docs change / refactoring / dependency upgrade
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My change requires a change to the documentation.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • I have built and run the editor to try this change out.

i was able to run around 4445 tests but it was stuck on bepu so few are missing, but the list queue tests pass now, also the old ones

@xen2

xen2 commented Sep 9, 2026

Copy link
Copy Markdown
Member

Doesn't work in all cases:

var q = new PriorityQueue<int>();
foreach (var v in new[] { 26, 38, 33, 54, 69, 64, 21 }) q.Enqueue(v);
q.Remove(54);
// drains: 21, 26, 38, 33, 64, 69   <-- 33 comes after 38

Issue #3398 explains the real problem. When Remove deletes an item, it takes the last item in the queue and puts it in the empty slot. Then it only moves that item down the tree.
But the item can also be smaller than its new parent. In that case it has to move up instead.

@IXLLEGACYIXL

Copy link
Copy Markdown
Collaborator Author

Doesn't work in all cases:

var q = new PriorityQueue<int>();
foreach (var v in new[] { 26, 38, 33, 54, 69, 64, 21 }) q.Enqueue(v);
q.Remove(54);
// drains: 21, 26, 38, 33, 64, 69   <-- 33 comes after 38

Issue #3398 explains the real problem. When Remove deletes an item, it takes the last item in the queue and puts it in the empty slot. Then it only moves that item down the tree. But the item can also be smaller than its new parent. In that case it has to move up instead.

ok so the current improvements fixes the regression that the old tests pass

i add this case as well

@IXLLEGACYIXL
IXLLEGACYIXL marked this pull request as draft September 9, 2026 02:53
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

🤖 Draft PR — automatic CI is skipped to save runner minutes.

  • Mark the PR ready for review to run the full automatic CI — or add a ci-run-on-draft label to run it now without leaving draft.
  • Or arm a specific opt-in suite: ci-enduser, ci-editor, ci-ios, ci-android.

@IXLLEGACYIXL

Copy link
Copy Markdown
Collaborator Author

ive added now your test and it passes to decide if order is broken up or downwards on removal

@IXLLEGACYIXL
IXLLEGACYIXL marked this pull request as ready for review September 14, 2026 20:13
@IXLLEGACYIXL
IXLLEGACYIXL marked this pull request as draft September 14, 2026 20:13
@IXLLEGACYIXL
IXLLEGACYIXL marked this pull request as ready for review September 16, 2026 02:18

@xen2 xen2 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PriorityNodeQueue<T>.Remove has the same bug.
It needs the same "move up if smaller than parent" step.
Please add tests in TestPriorityLinkedQueue too.

Remove and Dequeue now have the same sift-down loop.
Private SiftUp/SiftDown helpers would remove the copy (and maybe make the PriorityNodeQueue fix simple).

}

[Fact]
public void TestRemovalOnBubbleDownPreservesOrder()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: this test RemovalOnBubbleUp not Down

CheckPriorityQueue(priorityQueue);
}

private static void CheckPriorityQueue(PriorityQueue<int> priorityQueue)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CheckPriorityQueue only checks order. If Remove deleted the wrong item, the tests would still pass.
Could the new tests compare the drained values with the expected sorted list?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Priority queues return out-of-order values after removing an internal item

2 participants