Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get rid of Collection conformance or implement it differently #22

Closed
wants to merge 3 commits into from

Conversation

vale-cocoa
Copy link
Contributor

Added test showing that Collection conformance doesn't match the Sequ…ence conformance: when iterating elements via iterator the PriorityQueue uses the pop() method, effectively returning the elements in order. On the other hand if one iterates via indexes subscription, the elements are returned in the same order as they are stored in the underlaying storage, which doesn't necessarily matches the order in which elements are popped via the pop() method.

Fix: get rid of Collection conformance, otherwise implement a different Index type which takes into account how the effective order elements are popped out from the storage (most likely subscripting or creation of indexes won't be an O(1) operation).

…ence conformance: when iterating elements via iterator the PriorityQueue uses the pop() method, effectively returning the elements in order. On the other hand if one iterates via indexes subscription, the elements are returned in the same order as they are stored in the underlaying storage, which doesn't necessarily matches the order in which elements are popped via the pop() method.

Fix: get rid of Collection conformance, otherwise implement a different Index type which takes into account how the effective order elements are popped out from the storage (most likely subscripting or creation of indexes won't be an O(1) operation).
@davecom
Copy link
Owner

davecom commented Oct 22, 2020

Thanks. Yeah I should probably of never added Collection conformance. It doesn’t really make sense in retrospect. The issue is, what if someone is relying on it now? This project is 6 years old and has found its way into quite a few codebases and this could be considered a pretty major breaking change.

@vale-cocoa
Copy link
Contributor Author

vale-cocoa commented Oct 22, 2020

A solution could be in trading speed for accuracy, hence having the Collection subscript retrieve elements via the enumerated() method.
This will make the subscript O(log n) operation rather than O(1); moreover iterating via the indexes, would be an O(n log n) operation.

@davecom
Copy link
Owner

davecom commented Dec 19, 2020

I could be wrong, but wouldn't this mean that when you do a subscript, you are popping all of the elements before the index of the element you subscripted to? Because our implementation of next() is a pop():

mutating public func next() -> Element? { return pop() }

This could lead to some unintended consequences when calling the other Collection APIs.

@vale-cocoa
Copy link
Contributor Author

I could be wrong, but wouldn't this mean that when you do a subscript, you are popping all of the elements before the index of the element you subscripted to? Because our implementation of next() is a pop():

mutating public func next() -> Element? { return pop() }

This could lead to some unintended consequences when calling the other Collection APIs.

Please check the unit test I've just added: testIteratingViaIndexesValueSemantics()
It won't because of value semantics (the heap is a Swift Array).
Otherwise you'd had this same problem by simply doing a fast iteration, and that would happen on your original version either.
But again, this workaround is not really a desirable solution as we both agreed on due to the O(n) complexity of this subscript.

@davecom davecom closed this Jan 12, 2023
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.

None yet

2 participants