3
votes

Just starting to (try to) learn Rust. How do I use "bytestrings" as keys in a std::collections::BTreeMap?

It seems like I can't use [u8] because the type requires a fixed size.

Using vectors, e.g.

BTreeMap<Vec<u8>, MyType>

...seems wasteful.

I could try concatting all the bytestrings into one Vec and use slices of that as the BTree keys, but is there a better way to do this?

1
What ultimately owns your bytestrings? - Shepmaster
Could you explain more why "using vectors seems wasteful"? - Shepmaster
I was just thinking of over-allocation and whatever bookkeeping overhead a vector has. But I suppose I could shrink the vectors to fit before putting them in map. - Matt Chaput
Vec by itself is pretty bare-bones, just a pointer, a length, and a capacity. Shrinking it could be useful, as could putting it all in one place and just using slices (which are just a pointer and a length). What's the ballpark number of keys and how long are they on average? Is it worth worrying about this level of minutia (a.k.a. have you benchmarked)? ^_^ - Shepmaster

1 Answers

1
votes
use std::collections::BTreeMap;

fn main() {
    let key1 = b"1234";
    let key2 = b"5678";

    let mut map = BTreeMap::new();

    map.insert(key1, true);
    map.insert(key2, false);

    println!("{}", map);
}

As you saw, [u8] is a type that doesn't have any size, which means you can't actually store one of them somewhere. Instead, you will want to store a "slice of u8s", written &[u8], as the key. In this example, I just created some throw-away slices, but yours will likely come from some owning object.