Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Implement LazyBTreeMap and use it in a few places. #50240
This is a thin wrapper around BTreeMap that avoids allocating upon creation.
I would prefer to change BTreeMap directly to make it lazy (like I did with HashSet in #36734) and I initially attempted that by making BTreeMap::root an Option<>. But then I also had to change Iter and Range to handle trees with no root, and those types have stability markers on them and I wasn't sure if that was acceptable. Also, BTreeMap has a lot of complex code and changing it all was challenging, and I didn't have high confidence about my general approach.
So I prototyped this wrapper instead and used it in the hottest locations to get some measurements about the effect. The measurements are pretty good!
@Gankro, how do you think I should proceed here? Is leaving this as a wrapper reasonable? Or should I try to make BTreeMap itself lazy? If so, can I change the representation of Iter and Range?
Click to expand the log.
Made the terrible mistake of clicking on this with my phone; will look at this closer tomorrow morning. Please feel free to ping me mercilessly assuming I have forgotten.
I agree this is something that should be looked at seriously, and sympathize with the complexity issues.
Could you elaborate on the stability issues with Iter and Range? ABI isn’t part of stability.
Have you looked at how Google’s C++ BTree handles emptiness?
Here's the current range:
Handles don't make sense when there aren't any nodes, so it'll have to change to something like this:
Which is fine, except I don't understand in detail what the
No. I didn't even know such a thing existed :)
Google Btree, which i believe has the same high-level design (parent pointers), but is also a bit of a huge templated nightmare: https://code.google.com/archive/p/cpp-btree/
re: stability — yeah we only guarantee basic source-stability for stable types/methods. So just that they exist and work. It’s possible to rely on the layout of these types but that’s unexpected and not ensured (though we would consider an exception if it was really rampant).
I wonder if we could do some kind of static empty sentinel thing..?