Path: blob/main/cranelift/entity/src/primary.rs
3068 views
//! Densely numbered entity references as mapping keys.1use crate::EntityRef;2use crate::boxed_slice::BoxedSlice;3use crate::iter::{IntoIter, Iter, IterMut};4use crate::keys::Keys;5use alloc::boxed::Box;6use alloc::vec::Vec;7use core::fmt;8use core::marker::PhantomData;9use core::ops::{Index, IndexMut};10use core::slice;11#[cfg(feature = "enable-serde")]12use serde_derive::{Deserialize, Serialize};13use wasmtime_core::error::OutOfMemory;1415/// A primary mapping `K -> V` allocating dense entity references.16///17/// The `PrimaryMap` data structure uses the dense index space to implement a map with a vector.18///19/// A primary map contains the main definition of an entity, and it can be used to allocate new20/// entity references with the `push` method.21///22/// There should only be a single `PrimaryMap` instance for a given `EntityRef` type, otherwise23/// conflicting references will be created. Using unknown keys for indexing will cause a panic.24///25/// Note that `PrimaryMap` doesn't implement `Deref` or `DerefMut`, which would allow26/// `&PrimaryMap<K, V>` to convert to `&[V]`. One of the main advantages of `PrimaryMap` is27/// that it only allows indexing with the distinct `EntityRef` key type, so converting to a28/// plain slice would make it easier to use incorrectly. To make a slice of a `PrimaryMap`, use29/// `into_boxed_slice`.30#[derive(Clone, Hash, PartialEq, Eq)]31#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]32pub struct PrimaryMap<K, V>33where34K: EntityRef,35{36elems: Vec<V>,37unused: PhantomData<K>,38}3940impl<K, V> PrimaryMap<K, V>41where42K: EntityRef,43{44/// Create a new empty map.45pub fn new() -> Self {46Self {47elems: Vec::new(),48unused: PhantomData,49}50}5152/// Create a new empty map with the given capacity.53pub fn with_capacity(capacity: usize) -> Self {54Self {55elems: Vec::with_capacity(capacity),56unused: PhantomData,57}58}5960/// Like `with_capacity` but returns an error on allocation failure.61pub fn try_with_capacity(capacity: usize) -> Result<Self, OutOfMemory> {62let mut map = Self::new();63map.try_reserve(capacity)?;64Ok(map)65}6667/// Check if `k` is a valid key in the map.68pub fn is_valid(&self, k: K) -> bool {69k.index() < self.elems.len()70}7172/// Get the element at `k` if it exists.73pub fn get(&self, k: K) -> Option<&V> {74self.elems.get(k.index())75}7677/// Get the slice of values associated with the given range of keys, if any.78pub fn get_range(&self, range: core::ops::Range<K>) -> Option<&[V]> {79self.elems.get(range.start.index()..range.end.index())80}8182/// Get the element at `k` if it exists, mutable version.83pub fn get_mut(&mut self, k: K) -> Option<&mut V> {84self.elems.get_mut(k.index())85}8687/// Is this map completely empty?88pub fn is_empty(&self) -> bool {89self.elems.is_empty()90}9192/// Get the total number of entity references created.93pub fn len(&self) -> usize {94self.elems.len()95}9697/// Iterate over all the keys in this map.98pub fn keys(&self) -> Keys<K> {99Keys::with_len(self.elems.len())100}101102/// Iterate over all the values in this map.103pub fn values(&self) -> slice::Iter<'_, V> {104self.elems.iter()105}106107/// Iterate over all the values in this map, mutable edition.108pub fn values_mut(&mut self) -> slice::IterMut<'_, V> {109self.elems.iter_mut()110}111112/// Get this map's underlying values as a slice.113pub fn as_values_slice(&self) -> &[V] {114&self.elems115}116117/// Iterate over all the keys and values in this map.118pub fn iter(&self) -> Iter<'_, K, V> {119Iter::new(self.elems.iter())120}121122/// Iterate over all the keys and values in this map, mutable edition.123pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {124IterMut::new(self.elems.iter_mut())125}126127/// Remove all entries from this map.128pub fn clear(&mut self) {129self.elems.clear()130}131132/// Get the key that will be assigned to the next pushed value.133pub fn next_key(&self) -> K {134K::new(self.elems.len())135}136137/// Append `v` to the mapping, assigning a new key which is returned.138pub fn push(&mut self, v: V) -> K {139let k = self.next_key();140self.elems.push(v);141k142}143144/// Returns the last element that was inserted in the map.145pub fn last(&self) -> Option<(K, &V)> {146let len = self.elems.len();147let last = self.elems.last()?;148Some((K::new(len - 1), last))149}150151/// Returns the last element that was inserted in the map.152pub fn last_mut(&mut self) -> Option<(K, &mut V)> {153let len = self.elems.len();154let last = self.elems.last_mut()?;155Some((K::new(len - 1), last))156}157158/// Reserves capacity for at least `additional` more elements to be inserted.159pub fn reserve(&mut self, additional: usize) {160self.elems.reserve(additional)161}162163/// Like `reserve` but returns an error on allocation failure.164pub fn try_reserve(&mut self, additional: usize) -> Result<(), OutOfMemory> {165self.elems166.try_reserve(additional)167.map_err(|_| OutOfMemory::new(self.len().saturating_add(additional)))168}169170/// Reserves the minimum capacity for exactly `additional` more elements to be inserted.171pub fn reserve_exact(&mut self, additional: usize) {172self.elems.reserve_exact(additional)173}174175/// Like `reserve_exact` but returns an error on allocation failure.176pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), OutOfMemory> {177self.elems178.try_reserve_exact(additional)179.map_err(|_| OutOfMemory::new(self.len().saturating_add(additional)))180}181182/// Shrinks the capacity of the `PrimaryMap` as much as possible.183pub fn shrink_to_fit(&mut self) {184self.elems.shrink_to_fit()185}186187/// Consumes this `PrimaryMap` and produces a `BoxedSlice`.188pub fn into_boxed_slice(self) -> BoxedSlice<K, V> {189unsafe { BoxedSlice::<K, V>::from_raw(Box::<[V]>::into_raw(self.elems.into_boxed_slice())) }190}191192/// Returns mutable references to many elements at once.193///194/// Returns an error if an element does not exist, or if the same key was passed more than195/// once.196pub fn get_disjoint_mut<const N: usize>(197&mut self,198indices: [K; N],199) -> Result<[&mut V; N], slice::GetDisjointMutError> {200self.elems.get_disjoint_mut(indices.map(|k| k.index()))201}202203/// Performs a binary search on the values with a key extraction function.204///205/// Assumes that the values are sorted by the key extracted by the function.206///207/// If the value is found then `Ok(K)` is returned, containing the entity key208/// of the matching value.209///210/// If there are multiple matches, then any one of the matches could be returned.211///212/// If the value is not found then Err(K) is returned, containing the entity key213/// where a matching element could be inserted while maintaining sorted order.214pub fn binary_search_values_by_key<'a, B, F>(&'a self, b: &B, f: F) -> Result<K, K>215where216F: FnMut(&'a V) -> B,217B: Ord,218{219self.elems220.binary_search_by_key(b, f)221.map(|i| K::new(i))222.map_err(|i| K::new(i))223}224225/// Analog of `get_raw` except that a raw pointer is returned rather than a226/// mutable reference.227///228/// The default accessors of items in [`PrimaryMap`] will invalidate all229/// previous borrows obtained from the map according to miri. This function230/// can be used to acquire a pointer and then subsequently acquire a second231/// pointer later on without invalidating the first one. In other words232/// this is only here to help borrow two elements simultaneously with miri.233pub fn get_raw_mut(&mut self, k: K) -> Option<*mut V> {234if k.index() < self.elems.len() {235// SAFETY: the `add` function requires that the index is in-bounds236// with respect to the allocation which is satisfied here due to237// the bounds-check above.238unsafe { Some(self.elems.as_mut_ptr().add(k.index())) }239} else {240None241}242}243}244245impl<K, V> Default for PrimaryMap<K, V>246where247K: EntityRef,248{249fn default() -> PrimaryMap<K, V> {250PrimaryMap::new()251}252}253254/// Immutable indexing into an `PrimaryMap`.255/// The indexed value must be in the map.256impl<K, V> Index<K> for PrimaryMap<K, V>257where258K: EntityRef,259{260type Output = V;261262fn index(&self, k: K) -> &V {263&self.elems[k.index()]264}265}266267/// Mutable indexing into an `PrimaryMap`.268impl<K, V> IndexMut<K> for PrimaryMap<K, V>269where270K: EntityRef,271{272fn index_mut(&mut self, k: K) -> &mut V {273&mut self.elems[k.index()]274}275}276277impl<K, V> IntoIterator for PrimaryMap<K, V>278where279K: EntityRef,280{281type Item = (K, V);282type IntoIter = IntoIter<K, V>;283284fn into_iter(self) -> Self::IntoIter {285IntoIter::new(self.elems.into_iter())286}287}288289impl<'a, K, V> IntoIterator for &'a PrimaryMap<K, V>290where291K: EntityRef,292{293type Item = (K, &'a V);294type IntoIter = Iter<'a, K, V>;295296fn into_iter(self) -> Self::IntoIter {297Iter::new(self.elems.iter())298}299}300301impl<'a, K, V> IntoIterator for &'a mut PrimaryMap<K, V>302where303K: EntityRef,304{305type Item = (K, &'a mut V);306type IntoIter = IterMut<'a, K, V>;307308fn into_iter(self) -> Self::IntoIter {309IterMut::new(self.elems.iter_mut())310}311}312313impl<K, V> FromIterator<V> for PrimaryMap<K, V>314where315K: EntityRef,316{317fn from_iter<T>(iter: T) -> Self318where319T: IntoIterator<Item = V>,320{321Self {322elems: Vec::from_iter(iter),323unused: PhantomData,324}325}326}327328impl<K, V> Extend<V> for PrimaryMap<K, V>329where330K: EntityRef,331{332fn extend<T>(&mut self, iter: T)333where334T: IntoIterator<Item = V>,335{336self.elems.extend(iter);337}338}339340impl<K, V> From<Vec<V>> for PrimaryMap<K, V>341where342K: EntityRef,343{344fn from(elems: Vec<V>) -> Self {345Self {346elems,347unused: PhantomData,348}349}350}351352impl<K, V> From<PrimaryMap<K, V>> for Vec<V>353where354K: EntityRef,355{356fn from(map: PrimaryMap<K, V>) -> Self {357map.elems358}359}360361impl<K: EntityRef + fmt::Debug, V: fmt::Debug> fmt::Debug for PrimaryMap<K, V> {362fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {363let mut struct_ = f.debug_struct("PrimaryMap");364for (k, v) in self {365struct_.field(&alloc::format!("{k:?}"), v);366}367struct_.finish()368}369}370371#[cfg(test)]372mod tests {373use super::*;374375// `EntityRef` impl for testing.376#[derive(Clone, Copy, Debug, PartialEq, Eq)]377struct E(u32);378379impl EntityRef for E {380fn new(i: usize) -> Self {381E(i as u32)382}383fn index(self) -> usize {384self.0 as usize385}386}387388#[test]389fn basic() {390let r0 = E(0);391let r1 = E(1);392let m = PrimaryMap::<E, isize>::new();393394let v: Vec<E> = m.keys().collect();395assert_eq!(v, []);396397assert!(!m.is_valid(r0));398assert!(!m.is_valid(r1));399}400401#[test]402fn push() {403let mut m = PrimaryMap::new();404let k0: E = m.push(12);405let k1 = m.push(33);406407assert_eq!(m[k0], 12);408assert_eq!(m[k1], 33);409410let v: Vec<E> = m.keys().collect();411assert_eq!(v, [k0, k1]);412}413414#[test]415fn iter() {416let mut m: PrimaryMap<E, usize> = PrimaryMap::new();417m.push(12);418m.push(33);419420let mut i = 0;421for (key, value) in &m {422assert_eq!(key.index(), i);423match i {4240 => assert_eq!(*value, 12),4251 => assert_eq!(*value, 33),426_ => panic!(),427}428i += 1;429}430i = 0;431for (key_mut, value_mut) in m.iter_mut() {432assert_eq!(key_mut.index(), i);433match i {4340 => assert_eq!(*value_mut, 12),4351 => assert_eq!(*value_mut, 33),436_ => panic!(),437}438i += 1;439}440}441442#[test]443fn iter_rev() {444let mut m: PrimaryMap<E, usize> = PrimaryMap::new();445m.push(12);446m.push(33);447448let mut i = 2;449for (key, value) in m.iter().rev() {450i -= 1;451assert_eq!(key.index(), i);452match i {4530 => assert_eq!(*value, 12),4541 => assert_eq!(*value, 33),455_ => panic!(),456}457}458459i = 2;460for (key, value) in m.iter_mut().rev() {461i -= 1;462assert_eq!(key.index(), i);463match i {4640 => assert_eq!(*value, 12),4651 => assert_eq!(*value, 33),466_ => panic!(),467}468}469}470#[test]471fn keys() {472let mut m: PrimaryMap<E, usize> = PrimaryMap::new();473m.push(12);474m.push(33);475476let mut i = 0;477for key in m.keys() {478assert_eq!(key.index(), i);479i += 1;480}481}482483#[test]484fn keys_rev() {485let mut m: PrimaryMap<E, usize> = PrimaryMap::new();486m.push(12);487m.push(33);488489let mut i = 2;490for key in m.keys().rev() {491i -= 1;492assert_eq!(key.index(), i);493}494}495496#[test]497fn values() {498let mut m: PrimaryMap<E, usize> = PrimaryMap::new();499m.push(12);500m.push(33);501502let mut i = 0;503for value in m.values() {504match i {5050 => assert_eq!(*value, 12),5061 => assert_eq!(*value, 33),507_ => panic!(),508}509i += 1;510}511i = 0;512for value_mut in m.values_mut() {513match i {5140 => assert_eq!(*value_mut, 12),5151 => assert_eq!(*value_mut, 33),516_ => panic!(),517}518i += 1;519}520}521522#[test]523fn values_rev() {524let mut m: PrimaryMap<E, usize> = PrimaryMap::new();525m.push(12);526m.push(33);527528let mut i = 2;529for value in m.values().rev() {530i -= 1;531match i {5320 => assert_eq!(*value, 12),5331 => assert_eq!(*value, 33),534_ => panic!(),535}536}537i = 2;538for value_mut in m.values_mut().rev() {539i -= 1;540match i {5410 => assert_eq!(*value_mut, 12),5421 => assert_eq!(*value_mut, 33),543_ => panic!(),544}545}546}547548#[test]549fn from_iter() {550let mut m: PrimaryMap<E, usize> = PrimaryMap::new();551m.push(12);552m.push(33);553554let n = m.values().collect::<PrimaryMap<E, _>>();555assert!(m.len() == n.len());556for (me, ne) in m.values().zip(n.values()) {557assert!(*me == **ne);558}559}560561#[test]562fn from_vec() {563let mut m: PrimaryMap<E, usize> = PrimaryMap::new();564m.push(12);565m.push(33);566567let n = PrimaryMap::<E, &usize>::from(m.values().collect::<Vec<_>>());568assert!(m.len() == n.len());569for (me, ne) in m.values().zip(n.values()) {570assert!(*me == **ne);571}572}573574#[test]575fn get_many_mut() {576let mut m: PrimaryMap<E, usize> = PrimaryMap::new();577let _0 = m.push(0);578let _1 = m.push(1);579let _2 = m.push(2);580581assert_eq!([&mut 0, &mut 2], m.get_disjoint_mut([_0, _2]).unwrap());582assert_eq!(583m.get_disjoint_mut([_0, _0]),584Err(slice::GetDisjointMutError::OverlappingIndices)585);586assert_eq!(587m.get_disjoint_mut([E(4)]),588Err(slice::GetDisjointMutError::IndexOutOfBounds)589);590}591}592593594