Add crate for creating heterogeneous allocations
apasel422 opened this issue · comments
HashMap
(and BTreeMap
in its current form) allocates a single chunk of memory to store three contiguous arrays of equal length, effectively creating something like
struct Chunk<usize N, K, V> {
hashes: [u64; N],
keys: [K; N],
vals: [V; N],
}
with some fairly fragile size/alignment calculations (BTreeMap
) that are ultimately used to determine what values to pass to alloc::heap::allocate
. In other words, changing the calculations to add an additional fourth array (see contain-rs/linked-hash-map#30) is a bit tricky.
contain-rs
could provide a macro-exporting library that offers something like
macro_rules! offsets {
($capacity:expr, $($t:ty),+) => { ... }
}
which could be used like
impl<K, V, A> RawTable<K, V, A> {
fn new(capacity: usize) -> Self {
let (key_off, val_off, aug_off, overflowed) = offsets!(cap, u64, K, V, A);
...
}
}
to simplify this process.
This is actually an aspect of the @pnkfelix's allocator API designs, last I talked with 'im.
I think one possibility was a builder sort of thing:
alloc_builder().push::<K>(cap).push::<V>(cap).push::<u64>(cap).allocate()
Or summat.
Note that btree nodes require us to be heterogeneous in len
. it's got cap + 1
edges.
Ooh, that's nifty. I may experiment with something along those lines.
Having the allocation API understand this stuff was a necessary aspect for tracing hooks in some earlier designs. I can't remember if the current design for those hooks necessitates them.
I'm very close to posting a new draft with a (IMO) very nice high level API.