Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/cranelift/entity/src/map.rs
3069 views
1
//! Densely numbered entity references as mapping keys.
2
3
use crate::EntityRef;
4
use crate::iter::{Iter, IterMut};
5
use crate::keys::Keys;
6
use alloc::vec::Vec;
7
use core::cmp::min;
8
use core::fmt;
9
use core::marker::PhantomData;
10
use core::ops::{Index, IndexMut};
11
use core::slice;
12
#[cfg(feature = "enable-serde")]
13
use serde::{
14
Deserialize, Serialize,
15
de::{Deserializer, SeqAccess, Visitor},
16
ser::{SerializeSeq, Serializer},
17
};
18
use wasmtime_core::{alloc::PanicOnOom as _, error::OutOfMemory};
19
20
/// A mapping `K -> V` for densely indexed entity references.
21
///
22
/// The `SecondaryMap` data structure uses the dense index space to implement a map with a vector.
23
/// Unlike `PrimaryMap`, an `SecondaryMap` can't be used to allocate entity references. It is used
24
/// to associate secondary information with entities.
25
///
26
/// The map does not track if an entry for a key has been inserted or not. Instead it behaves as if
27
/// all keys have a default entry from the beginning.
28
#[derive(Clone, Hash)]
29
pub struct SecondaryMap<K, V>
30
where
31
K: EntityRef,
32
V: Clone,
33
{
34
elems: Vec<V>,
35
default: V,
36
unused: PhantomData<K>,
37
}
38
39
/// Shared `SecondaryMap` implementation for all value types.
40
impl<K, V> SecondaryMap<K, V>
41
where
42
K: EntityRef,
43
V: Clone,
44
{
45
/// Create a new empty map.
46
pub fn new() -> Self
47
where
48
V: Default,
49
{
50
Self {
51
elems: Vec::new(),
52
default: Default::default(),
53
unused: PhantomData,
54
}
55
}
56
57
/// Create a new, empty map with the specified capacity.
58
///
59
/// The map will be able to hold exactly `capacity` elements without reallocating.
60
pub fn with_capacity(capacity: usize) -> Self
61
where
62
V: Default,
63
{
64
Self {
65
elems: Vec::with_capacity(capacity),
66
default: Default::default(),
67
unused: PhantomData,
68
}
69
}
70
71
/// Like `with_capacity` but returns an error on allocation failure.
72
pub fn try_with_capacity(capacity: usize) -> Result<Self, OutOfMemory>
73
where
74
V: Default,
75
{
76
let mut elems = Vec::new();
77
elems
78
.try_reserve(capacity)
79
.map_err(|_| OutOfMemory::new(core::mem::size_of::<V>().saturating_mul(capacity)))?;
80
Ok(Self {
81
elems,
82
default: Default::default(),
83
unused: PhantomData,
84
})
85
}
86
87
/// Create a new empty map with a specified default value.
88
///
89
/// This constructor does not require V to implement Default.
90
pub fn with_default(default: V) -> Self {
91
Self {
92
elems: Vec::new(),
93
default,
94
unused: PhantomData,
95
}
96
}
97
98
/// Returns the number of elements the map can hold without reallocating.
99
pub fn capacity(&self) -> usize {
100
self.elems.capacity()
101
}
102
103
/// Get the element at `k` if it exists.
104
#[inline(always)]
105
pub fn get(&self, k: K) -> Option<&V> {
106
self.elems.get(k.index())
107
}
108
109
/// Get the element at `k` mutably, if it exists.
110
pub fn get_mut(&mut self, k: K) -> Option<&mut V> {
111
self.elems.get_mut(k.index())
112
}
113
114
/// Insert the given key-value pair, returning the old value if it exists.
115
pub fn insert(&mut self, k: K, v: V) -> Option<V> {
116
self.try_insert(k, v).panic_on_oom()
117
}
118
119
/// Like `insert` but returns an error on allocation failure.
120
pub fn try_insert(&mut self, k: K, v: V) -> Result<Option<V>, OutOfMemory> {
121
let i = k.index();
122
if i < self.elems.len() {
123
Ok(Some(core::mem::replace(&mut self.elems[i], v)))
124
} else {
125
self.try_resize(i + 1)?;
126
self.elems[i] = v;
127
Ok(None)
128
}
129
}
130
131
/// Remove the element at `k`, if it exists, replacing it with the default
132
/// value.
133
pub fn remove(&mut self, k: K) -> Option<V> {
134
let i = k.index();
135
if i < self.elems.len() {
136
let default = self.default.clone();
137
Some(core::mem::replace(&mut self.elems[i], default))
138
} else {
139
None
140
}
141
}
142
143
/// Is this map completely empty?
144
#[inline(always)]
145
pub fn is_empty(&self) -> bool {
146
self.elems.is_empty()
147
}
148
149
/// Remove all entries from this map.
150
#[inline(always)]
151
pub fn clear(&mut self) {
152
self.elems.clear()
153
}
154
155
/// Iterate over all the keys and values in this map.
156
pub fn iter(&self) -> Iter<'_, K, V> {
157
Iter::new(self.elems.iter())
158
}
159
160
/// Iterate over all the keys and values in this map, mutable edition.
161
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
162
IterMut::new(self.elems.iter_mut())
163
}
164
165
/// Iterate over all the keys in this map.
166
pub fn keys(&self) -> Keys<K> {
167
Keys::with_len(self.elems.len())
168
}
169
170
/// Iterate over all the values in this map.
171
pub fn values(&self) -> slice::Iter<'_, V> {
172
self.elems.iter()
173
}
174
175
/// Iterate over all the values in this map, mutable edition.
176
pub fn values_mut(&mut self) -> slice::IterMut<'_, V> {
177
self.elems.iter_mut()
178
}
179
180
/// Resize the map to have `n` entries by adding default entries as needed.
181
pub fn resize(&mut self, n: usize) {
182
self.elems.resize(n, self.default.clone());
183
}
184
185
/// Like `resize` but returns an error on allocation failure.
186
pub fn try_resize(&mut self, n: usize) -> Result<(), OutOfMemory> {
187
if self.elems.capacity() < n {
188
self.elems
189
.try_reserve(n - self.elems.len())
190
.map_err(|_| OutOfMemory::new(core::mem::size_of::<V>().saturating_mul(n)))?;
191
}
192
debug_assert!(self.elems.capacity() >= n);
193
self.elems.resize(n, self.default.clone());
194
Ok(())
195
}
196
197
/// Slow path for `index_mut` which resizes the vector.
198
#[cold]
199
fn resize_for_index_mut(&mut self, i: usize) -> &mut V {
200
self.elems.resize(i + 1, self.default.clone());
201
&mut self.elems[i]
202
}
203
}
204
205
impl<K, V> Default for SecondaryMap<K, V>
206
where
207
K: EntityRef,
208
V: Clone + Default,
209
{
210
fn default() -> SecondaryMap<K, V> {
211
SecondaryMap::new()
212
}
213
}
214
215
impl<K, V> FromIterator<(K, V)> for SecondaryMap<K, V>
216
where
217
K: EntityRef,
218
V: Clone + Default,
219
{
220
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
221
let iter = iter.into_iter();
222
let (min, max) = iter.size_hint();
223
let cap = max.unwrap_or_else(|| 2 * min);
224
let mut map = Self::with_capacity(cap);
225
for (k, v) in iter {
226
map[k] = v;
227
}
228
map
229
}
230
}
231
232
/// Immutable indexing into an `SecondaryMap`.
233
///
234
/// All keys are permitted. Untouched entries have the default value.
235
impl<K, V> Index<K> for SecondaryMap<K, V>
236
where
237
K: EntityRef,
238
V: Clone,
239
{
240
type Output = V;
241
242
#[inline(always)]
243
fn index(&self, k: K) -> &V {
244
self.elems.get(k.index()).unwrap_or(&self.default)
245
}
246
}
247
248
/// Mutable indexing into an `SecondaryMap`.
249
///
250
/// The map grows as needed to accommodate new keys.
251
impl<K, V> IndexMut<K> for SecondaryMap<K, V>
252
where
253
K: EntityRef,
254
V: Clone,
255
{
256
#[inline(always)]
257
fn index_mut(&mut self, k: K) -> &mut V {
258
let i = k.index();
259
if i >= self.elems.len() {
260
return self.resize_for_index_mut(i);
261
}
262
&mut self.elems[i]
263
}
264
}
265
266
impl<K, V> PartialEq for SecondaryMap<K, V>
267
where
268
K: EntityRef,
269
V: Clone + PartialEq,
270
{
271
fn eq(&self, other: &Self) -> bool {
272
let min_size = min(self.elems.len(), other.elems.len());
273
self.default == other.default
274
&& self.elems[..min_size] == other.elems[..min_size]
275
&& self.elems[min_size..].iter().all(|e| *e == self.default)
276
&& other.elems[min_size..].iter().all(|e| *e == other.default)
277
}
278
}
279
280
impl<K, V> Eq for SecondaryMap<K, V>
281
where
282
K: EntityRef,
283
V: Clone + PartialEq + Eq,
284
{
285
}
286
287
#[cfg(feature = "enable-serde")]
288
impl<K, V> Serialize for SecondaryMap<K, V>
289
where
290
K: EntityRef,
291
V: Clone + PartialEq + Serialize,
292
{
293
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
294
where
295
S: Serializer,
296
{
297
// TODO: bincode encodes option as "byte for Some/None" and then optionally the content
298
// TODO: we can actually optimize it by encoding manually bitmask, then elements
299
let mut elems_cnt = self.elems.len();
300
while elems_cnt > 0 && self.elems[elems_cnt - 1] == self.default {
301
elems_cnt -= 1;
302
}
303
let mut seq = serializer.serialize_seq(Some(1 + elems_cnt))?;
304
seq.serialize_element(&Some(self.default.clone()))?;
305
for e in self.elems.iter().take(elems_cnt) {
306
let some_e = Some(e);
307
seq.serialize_element(if *e == self.default { &None } else { &some_e })?;
308
}
309
seq.end()
310
}
311
}
312
313
#[cfg(feature = "enable-serde")]
314
impl<'de, K, V> Deserialize<'de> for SecondaryMap<K, V>
315
where
316
K: EntityRef,
317
V: Clone + Deserialize<'de>,
318
{
319
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
320
where
321
D: Deserializer<'de>,
322
{
323
use alloc::fmt;
324
struct SecondaryMapVisitor<K, V> {
325
unused: PhantomData<fn(K) -> V>,
326
}
327
328
impl<'de, K, V> Visitor<'de> for SecondaryMapVisitor<K, V>
329
where
330
K: EntityRef,
331
V: Clone + Deserialize<'de>,
332
{
333
type Value = SecondaryMap<K, V>;
334
335
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
336
formatter.write_str("struct SecondaryMap")
337
}
338
339
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
340
where
341
A: SeqAccess<'de>,
342
{
343
match seq.next_element()? {
344
Some(Some(default_val)) => {
345
let default_val: V = default_val; // compiler can't infer the type
346
let mut m = SecondaryMap::with_default(default_val.clone());
347
let mut idx = 0;
348
while let Some(val) = seq.next_element()? {
349
let val: Option<_> = val; // compiler can't infer the type
350
m[K::new(idx)] = val.unwrap_or_else(|| default_val.clone());
351
idx += 1;
352
}
353
Ok(m)
354
}
355
_ => Err(serde::de::Error::custom("Default value required")),
356
}
357
}
358
}
359
360
deserializer.deserialize_seq(SecondaryMapVisitor {
361
unused: PhantomData {},
362
})
363
}
364
}
365
366
impl<K: EntityRef + fmt::Debug, V: fmt::Debug + Clone> fmt::Debug for SecondaryMap<K, V> {
367
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
368
f.debug_struct("SecondaryMap")
369
.field("elems", &self.elems)
370
.field("default", &self.default)
371
.finish()
372
}
373
}
374
375
#[cfg(test)]
376
mod tests {
377
use super::*;
378
379
// `EntityRef` impl for testing.
380
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
381
struct E(u32);
382
383
impl EntityRef for E {
384
fn new(i: usize) -> Self {
385
E(i as u32)
386
}
387
fn index(self) -> usize {
388
self.0 as usize
389
}
390
}
391
392
#[test]
393
fn basic() {
394
let r0 = E(0);
395
let r1 = E(1);
396
let r2 = E(2);
397
let r3 = E(3);
398
let mut m = SecondaryMap::new();
399
400
let v: Vec<E> = m.keys().collect();
401
assert_eq!(v, []);
402
403
m[r2] = 3;
404
m[r1] = 5;
405
406
assert_eq!(m[r1], 5);
407
assert_eq!(m[r2], 3);
408
409
assert!(m.get(r3).is_none());
410
assert!(m.get_mut(r3).is_none());
411
412
let old = m.insert(r3, 99);
413
assert!(old.is_none());
414
assert_eq!(m.get(r3), Some(&99));
415
assert_eq!(m[r3], 99);
416
417
*m.get_mut(r3).unwrap() += 1;
418
assert_eq!(m.get(r3), Some(&100));
419
assert_eq!(m[r3], 100);
420
421
let old = m.insert(r3, 42);
422
assert_eq!(old, Some(100));
423
assert_eq!(m.get(r3), Some(&42));
424
assert_eq!(m[r3], 42);
425
426
let old = m.remove(r3);
427
assert_eq!(old, Some(42));
428
assert_eq!(m[r3], 0);
429
let old = m.remove(r3);
430
assert_eq!(old, Some(0));
431
m.resize(3);
432
let old = m.remove(r3);
433
assert_eq!(old, None);
434
435
let v: Vec<E> = m.keys().collect();
436
assert_eq!(v, [r0, r1, r2]);
437
438
let shared = &m;
439
assert_eq!(shared[r0], 0);
440
assert_eq!(shared[r1], 5);
441
assert_eq!(shared[r2], 3);
442
}
443
}
444
445