Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

simonacca
Copy link

@simonacca simonacca commented May 17, 2024

This is an attempt to upstream applitopia's implementation of sorted map and sorted set.

The code, tests and type definitions are exactly as in the fork, except:

  • I have omitted the "partial sort" implementation in the hope of keeping this as small (and therefore as mergeable) as possible
  • I have added one commit on top with whatever was needed to make the test suite and linter happy

While I am happy with the result as it is (up to date immutable + sorted map), I am not that familiar with the internals of Immutable, therefore I am not particularly eager to steward this PR all the way to merge. If one of the maintainers is interested and willing to do so that would be much appreciated! Otherwise it can be closed and perhaps serve as a starting point for the next brave soul to attempt this feat :)

simonacca and others added 2 commits May 17, 2024 16:28
Copy exactly `applitopia/immutable-sorted`'s implementation of sorted map and sorted set minus the partial sort impplementation

applitopia/immutable-sorted@d700f18

Co-authored-by: Applitopia <[email protected]>
@simonacca simonacca force-pushed the applitopia-sorted-map-set branch from f41d323 to b62ac0a Compare May 17, 2024 14:29
@bdurrer
Copy link
Contributor

bdurrer commented May 17, 2024

An interesting fork!

Intuitively, I kinda would expect Sorted and Ordered types be the same thing?
Maybe Sorted should replace/enhance the existing Ordered? Sort with an undefined comparator simply means that it doesn't sort upon initialization and uses "add last"?

You can already get what Sorted does by always calling sort after an operation. The performance might be much worse tho (didn't test it)

Set([9,5,7,1]).sort(...);

and

.add(3).sort()

@simonacca
Copy link
Author

simonacca commented May 17, 2024

You can already get what Sorted does by always calling sort after an operation. The performance might be much worse tho (didn't test it)

Indeed, the performance is O(n) with calling sort after each operation on an "Ordered family" data structure and O(log n) with these Sorted family of data structures.

@simonacca
Copy link
Author

Intuitively, I kinda would expect Sorted and Ordered types be the same thing?
Maybe Sorted should replace/enhance the existing Ordered? Sort with an undefined comparator simply means that it doesn't sort upon initialization and uses "add last"?

Interesting idea! I see a reason to go this way from an API design point of view... a smaller API surface should be easier to learn.

On the other hand, I would say Ordered and Sorted types are conceptually different... one is not a special case of the other, that is: there is no real comparator function that one can pass to a Sorted type to produce an Ordered type, since the comparator function needs to be commutative. I would say passing an undefined comparator is more akin to a flag.

Along the same lines, I can't think of a way to implement the "Ordered" behavior with a regular b-tree, so from an implementation standpoint it would make sense to still have the current "Ordered" data structures and code underneath.

@jdeniau
Copy link
Member

jdeniau commented Mar 20, 2025

Possibly related to #88

@jdeniau
Copy link
Member

jdeniau commented Apr 19, 2025

OK now I understand this PR.
It tooks me some time, but in the end I get it.

To be sure, conceptually, it's the same as calling .sort() before each operation?

Whereas Ordered only guaranty that the insert order is saved

Set(['a', 'c', 'b'])
// order might be 'b', 'a', 'c' as Set will optimize the indexing
OrderedSet(['a', 'c', 'b'])
// order will be 'a', 'c', 'b' because Ordered Set keep the order by design
SortedSet(['a', 'c', 'b'])
// order will be 'a', 'b', 'c' as each item will be sorted

@CGamesPlay
Copy link

CGamesPlay commented Sep 19, 2025

Sorted and Ordered have different access semantics, so I don't think they should be merged into a single data structure. The key question that the Sorted variants are able to answer in O(log N) is "what is the first key that sorts before K?" This is provided by the from and fromIndex methods.

For a use-case, imagine you have a map of shortened URLs mapping to the expanded equivalents, which is a SortedMap<string, string>. If you want to ask the question, "what are the URLs that start with 'm'?", you can use .from("m") to answer this question (in O(log N) time). If you wanted to do that with an OrderedMap which was sorted by key, you can only answer is in O(N) time by iterating through all the keys, and also insertions are now O(N log N) since you have to re-sort the entire map when you insert.

Would love to see this PR merged!

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.

4 participants