How does SQLite work? Part 2: btrees
jvns.ca
jvns.ca
[0]https://jvns.ca/blog/2014/09/27/how-does-sqlite-work-part-1-...
And I'll never understand how efficient B+Tree implementations are not in the standard library of every language/runtime.
- databases
- file systems
- hash maps
The first 2 are not something you code everyday, so if you go for that, installing a dep doing it is not a problem.
The last is usually included in all languages.
Why would you need them available in all languages for?
I think they're only used for databases and file systems because those are cases where people actually bother to write them since they care about performance. If they were in the stdlib then they'd be used for many more things.
I can't remember one time in the last decade where I was in need of a _sorted_ hash map.
And if it ever happen I can easily depend install one.
I'm unsure of having something even more general like a b+tree would help.
It's possible that, because I'm not use to have them handy, I don't think about them when I encounter a problem for which they would be perfect.
But I never felt like I missed them.
Can you give me a few examples of problems you them for in the past year?
Was that with a high or low level language?
Also, sparse vectors. You don't have a value to store for each index so you use a BTreeMap. I've done this using sentinel values in an array, but that's gross depending on how sparse and how large the vector is.
In Python I would just use a Dataframe (pandas), but in Rust I would use BTreeMap. I wouldn't wish for all languages to have a dataframe type in them since they're such complicated beasts with tricky APIs (pandas and R are such acquired tastes) so I think people can get quite far with B(+)Trees. So that's what I wish was in every stdlib.
Technically you would be using a btree, but a higher level interface, like with a fs or hashmap. Which is kinda my point.
I dont say it's not a good DS, but having it in all languages stdlib seems overkill given the tool we have today.
I'm a python guy, and even without panda it has the heapq module which is a b-tree, yet I never really got a reason to use it.
> I dont say it's not a good DS, but having it in all languages stdlib seems overkill given the tool we have today.
C++ has map and Java has TreeMap. These are both red black trees (which are equivalent to btrees where k=4). So there's no question of whether there are ordered mapping types in these languages. IMO they'd be better as b(+)rees with a wider fanout. That's all.
Basically they are not appropriate for most programming use, except that they keep data ordered where a hash won't, and an ordered hash isn't often needed.
What do you do that you feel would benefit from cache locality that in-mem btrees give over other structures? How often have you needed an ordered map at all?
What do you regularly do that needs a data structure that maintains order consistently? A LUT for compiler symbols could be implemented as a binary (or n-ary) tree but that order is incidental; it's only used to get fast lookup. A hash would be faster. I think graph algos may be different but I've never used one, and they tend to use heaps to get an order, but don't need to maintain an ordered collection.
But also prefix lookup. You can do some sweet tricks with trees where lookup on strings can use a prefix and then you get an iterator. You can then use this iterator to read the items until you find one where the prefix doesn't match. I've used this in developing storage systems, but it seems like a useful trick that I might want to use elsewhere.
https://doc.rust-lang.org/std/collections/struct.BTreeMap.ht...
I have found to have btree/sets included very handy.
Suddenly some hacks around hash maps fade away. For example, sort for presentation or check for min/max, dedup data, etc.. Instead of hand code, pick the proper container and COLLECT:
https://doc.rust-lang.org/std/collections/
(ie: You `.collect` at the end of a iterator into your container of choice. Cool)
I think developers just adapt to whatever is provided not matter if is the real fit or not. So is important to provide a good set of types/structures.
I think all langs must give (at least):
- Int, Float, Decimal
- Bool
- Strings (unicode/utf8)
- Dates!
- Enums or better algebraic types
- Vectors, HashMap, Btree, Sets