-
Notifications
You must be signed in to change notification settings - Fork 297
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
partitioningIndex(where:)
for Sorted Set/Dictionary
#256
Comments
Absolutely! This is one area where we're currently missing key functionality, and this will definitely need to be addressed before shipping these types. I've grown to really like using a subscript to allow easy lookups for any range of items in sorted collections. For example, let bits: BitSet = [2, 5, 6, 8, 9]
let a = bits[members: 3..<7] // [5, 6]
let b = bits[members: 4...] // [5, 6, 8, 9]
let c = bits[members: ..<8] // [2, 5, 6]
Generalizing this operation for sorted [multi]dictionaries, These subscripts may also provide a reason to introduce (Edit: in fact, for a true multidictionary, we probably want the core |
Yes, subscripts make sense for any kind of projection, and slicing is a good example. I suppose you're aware that if your
Sure, but please don't neglect to expose the fundamental partition point-finding operation on which that would be based! BTW, I hope you're aware of https://github.com/loftware/StandardLibraryProtocolChecks which can be useful for your test coverage. |
Yes, and that's exactly how indices work in The guideline I'm strictly enforcing is to never use a
Interesting! I'm also so very tempted to make Perhaps this would be more viable if we could set default values for generic parameters. Failing that, my plan is to eventually add the fully generic types under different names, and to change the current types to be simple wrappers (or even just typealiases). |
Do you think we need to explicitly expose that as a core operation? (Isn't it generally equivalent to the proposed |
I am! 👍 Have you seen |
Yeah, I did see that. I was wondering, what's the point of MinimalTypes? |
I kinda think you do, especially if you're going to have insert-with-hint functionality, and especially if indices are going to continue to contain an array. It's a matter of exposing the basis operations of the datatype in a way that they can easily be known, and without loss of efficiency. |
Those are reusable types with deliberately over-pedantic (and/or unusually configurable) conformances that can be used to exercise commonly forgotten code paths in functions & types that are generic over the corresponding protocols. The The package tests don't often use these at the moment, other than |
Hm; I do expect that indices will continue to encode a path in the tree, although the implementation is not final. For indexing to be efficient in high-fanout trees, indices need to also contain an unsafe/unowned reference to the final node on the path, which has some unfortunate consequences -- such as that mutations need to invalidate every index. This makes indices fragile, fleeting things that tend to fall apart at the slightest change. That said, I can't say I get how the index representation would matter when it comes to expressing the core lookup operation. Can you expand a little bit on what you mean? I don't think spelling the partitioning operation as, say, I'm very open to getting convinced, though! (I wasn't planning to have an insert-with-hint in the initial release. Something more like the old cursor construct may be something to consider later, though. A hint seems far easier to validate if it sits beside the collection that produced it, in a mutable construct that owns and maintains both. Additionally, allowing the mutator construct to loosen some collection invariants (such as the tree's augmentation with subtree counts) can be a crucial performance boost when applying a batch of updates.) |
While there's a little bit of overlap, I think there's quite a bit that's distinct. You should steal that code and feel free to turn it into whatever you want. Moreover it looks like the collection adapters in the SwiftAlgorithms collection don't have any testing in the same area. |
It's just that the range you return from that operation is going to contain two indices instead of just one. it's a bit more overhead.
That's where I disagree with you. The principle of generic programming I'm upholding is that when you discover the fundamental building blocks of useful operations/components, you expose them, because then other high-performance components can be built on top.
or
I don't know, I'm very much regretting the comparability requirement for indices and a few other things. Looking forward to greenfield stdlib development with Val so I can make new/different mistakes! |
I realize the docs say this code is still unstable, but it's never too early to ask for more, right? 😉
There should be something analogous to
partitioningIndex(where:)
for the sorted associative containers. An example of why: I have a multimap K:V where the chance of having multiple V's for any K is very low and for any K, all Vs are unique. The best storage format is roughly as a sorted set of lexicographically ordered (K,V) pairs. There should be a way to find the beginning and end of the sequence of contiguous items with a given K value, without (obviously) the cost of treating the tree as a flat collection and using indices.In fact I'm very surprised not to see something like this in the BTree source (though it's so spread out, I may have missed it); it seems like
contains
and perhaps a few other things might be able to be built upon it. Thanks!The text was updated successfully, but these errors were encountered: