diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index 6ebb98c42cd4f..0eea8b39c9fd4 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -45,6 +45,8 @@ pub const MIN_LEN: usize = B - 1; pub const CAPACITY: usize = 2 * B - 1; /// The underlying representation of leaf nodes. +// The layout is fixed so that we have tighter control over field ordering. +// We're okay with wasting some memory in trade-off for better cache locality. #[repr(C)] struct LeafNode { /// We use `*const` as opposed to `*mut` so as to be covariant in `K` and `V`. @@ -56,16 +58,19 @@ struct LeafNode { /// This is only guaranteed to be initialized when `parent` is non-null. parent_idx: MaybeUninit, + /// The arrays storing the values of the node. Only the first `len` elements of each + /// array are initialized and valid. + vals: [MaybeUninit; CAPACITY], + /// The number of keys and values this node stores. - /// - /// This next to `parent_idx` to encourage the compiler to join `len` and - /// `parent_idx` into the same 32-bit word, reducing space overhead. + // This is right before the keys because we frequently access both. len: u16, /// The arrays storing the actual data of the node. Only the first `len` elements of each /// array are initialized and valid. + // This is intentionally last so as to both be a) close to `len` and b) + // close to the edges in the internal node case. keys: [MaybeUninit; CAPACITY], - vals: [MaybeUninit; CAPACITY], } impl LeafNode {