The Entry API for BTreeMap returns an Entry struct. Currently I have this:
pub enum Entry<'a, K, V> {
/// Vacant entry - map doesn't yet contain key.
Vacant(VacantEntry<'a, K, V>),
/// Occupied entry - map already contains key.
Occupied(OccupiedEntry<'a, K, V>),
}
and
pub struct OccupiedEntry<'a, K, V> {
map: &'a mut BTreeMap<K, V>,
key: OccupiedEntryKey,
}
and
enum OccupiedEntryKey {
First,
Last,
Some(Position),
}
and
struct Position {
key_found: bool,
leaf_full: bool,
ix: PosVec,
and
type PosVec = smallvec::SmallVec<[u8; 8]>;
( All taken from lib.rs - source)
So here PosVec is used to relatively quickly find a place in the BTree using indexes. However it would be more efficient to store some kind of pointer to the Leaf. However I cannot store both a mutable reference to the whole BTreeMap and a mutable reference to the Leaf in the Entry, Rust's rules do not permit it ( correct me if I am wrong ). So what could I do instead, and still have sound code?
Maybe I can use two raw pointers, and use those to get mutable references as required. For example if OccupiedEntry::Remove is called, I can (efficiently) remove the (K,V) pair from the Leaf and then decrement the len field in BTreeMap, and the operation is complete. Would that be correct?
[ There are actually two cases, some (K,V) pairs are stored in non-Leaf structs, but I will ignore that here for simplicity ]
Note: the whole point here is to better understand what is allowed with raw pointers and what is not, how they can be used correctly.