]>
git.proxmox.com Git - rustc.git/blob - vendor/elsa/src/map.rs
1 use std
::borrow
::Borrow
;
2 use std
::cell
::{Cell, UnsafeCell}
;
3 use std
::collections
::hash_map
::RandomState
;
4 use std
::collections
::BTreeMap
;
5 use std
::collections
::HashMap
;
6 use std
::hash
::{BuildHasher, Hash}
;
7 use std
::iter
::FromIterator
;
10 use stable_deref_trait
::StableDeref
;
12 /// Append-only version of `std::collections::HashMap` where
13 /// insertion does not require mutable access
14 pub struct FrozenMap
<K
, V
, S
= RandomState
> {
15 map
: UnsafeCell
<HashMap
<K
, V
, S
>>,
16 /// Eq/Hash implementations can have side-effects, and using Rc it is possible
17 /// for FrozenMap::insert to be called on a key that itself contains the same
18 /// `FrozenMap`, whose `eq` implementation also calls FrozenMap::insert
20 /// We use this `in_use` flag to guard against any reentrancy.
24 // safety: UnsafeCell implies !Sync
26 impl<K
: Eq
+ Hash
, V
> FrozenMap
<K
, V
> {
27 pub fn new() -> Self {
29 map
: UnsafeCell
::new(Default
::default()),
30 in_use
: Cell
::new(false),
37 /// use elsa::FrozenMap;
39 /// let map = FrozenMap::new();
40 /// assert_eq!(map.len(), 0);
41 /// map.insert(1, Box::new("a"));
42 /// assert_eq!(map.len(), 1);
44 pub fn len(&self) -> usize {
45 assert
!(!self.in_use
.get());
46 self.in_use
.set(true);
48 let map
= self.map
.get();
51 self.in_use
.set(false);
58 /// use elsa::FrozenMap;
60 /// let map = FrozenMap::new();
61 /// assert_eq!(map.is_empty(), true);
62 /// map.insert(1, Box::new("a"));
63 /// assert_eq!(map.is_empty(), false);
65 pub fn is_empty(&self) -> bool
{
70 impl<K
: Eq
+ Hash
, V
: StableDeref
, S
: BuildHasher
> FrozenMap
<K
, V
, S
> {
71 // these should never return &K or &V
72 // these should never delete any entries
73 pub fn insert(&self, k
: K
, v
: V
) -> &V
::Target
{
74 assert
!(!self.in_use
.get());
75 self.in_use
.set(true);
77 let map
= self.map
.get();
78 &*(*map
).entry(k
).or_insert(v
)
80 self.in_use
.set(false);
84 /// Returns a reference to the value corresponding to the key.
86 /// The key may be any borrowed form of the map's key type, but
87 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
93 /// use elsa::FrozenMap;
95 /// let map = FrozenMap::new();
96 /// map.insert(1, Box::new("a"));
97 /// assert_eq!(map.get(&1), Some(&"a"));
98 /// assert_eq!(map.get(&2), None);
100 pub fn get
<Q
: ?Sized
>(&self, k
: &Q
) -> Option
<&V
::Target
>
105 assert
!(!self.in_use
.get());
106 self.in_use
.set(true);
108 let map
= self.map
.get();
109 (*map
).get(k
).map(|x
| &**x
)
111 self.in_use
.set(false);
115 /// Applies a function to the owner of the value corresponding to the key (if any).
117 /// The key may be any borrowed form of the map's key type, but
118 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
124 /// use elsa::FrozenMap;
126 /// let map = FrozenMap::new();
127 /// map.insert(1, Box::new("a"));
128 /// assert_eq!(map.map_get(&1, Clone::clone), Some(Box::new("a")));
129 /// assert_eq!(map.map_get(&2, Clone::clone), None);
131 pub fn map_get
<Q
: ?Sized
, T
, F
>(&self, k
: &Q
, f
: F
) -> Option
<T
>
137 assert
!(!self.in_use
.get());
138 self.in_use
.set(true);
140 let map
= self.map
.get();
143 self.in_use
.set(false);
147 pub fn into_map(self) -> HashMap
<K
, V
, S
> {
148 self.map
.into_inner()
154 impl<K
: Eq
+ Hash
+ StableDeref
, V
: StableDeref
, S
: BuildHasher
> FrozenMap
<K
, V
, S
> {
155 /// Returns a reference to the key and value matching a borrowed
158 /// The key argument may be any borrowed form of the map's key type,
159 /// but [`Hash`] and [`Eq`] on the borrowed form *must* match those
160 /// for the key type.
165 /// use elsa::FrozenMap;
167 /// let map = FrozenMap::new();
168 /// map.insert(Box::new("1"), Box::new("a"));
169 /// assert_eq!(map.get_key_value(&"1"), Some((&"1", &"a")));
170 /// assert_eq!(map.get_key_value(&"2"), None);
172 pub fn get_key_value
<Q
: ?Sized
>(&self, k
: &Q
) -> Option
<(&K
::Target
, &V
::Target
)>
177 assert
!(!self.in_use
.get());
178 self.in_use
.set(true);
180 let map
= self.map
.get();
181 (*map
).get_key_value(k
).map(|(k
, v
)| (&**k
, &**v
))
183 self.in_use
.set(false);
188 impl<K
, V
, S
> std
::convert
::AsMut
<HashMap
<K
, V
, S
>> for FrozenMap
<K
, V
, S
> {
189 /// Get mutable access to the underlying [`HashMap`].
191 /// This is safe, as it requires a `&mut self`, ensuring nothing is using
192 /// the 'frozen' contents.
193 fn as_mut(&mut self) -> &mut HashMap
<K
, V
, S
> {
194 unsafe { &mut *self.map.get() }
198 impl<K
, V
, S
> From
<HashMap
<K
, V
, S
>> for FrozenMap
<K
, V
, S
> {
199 fn from(map
: HashMap
<K
, V
, S
>) -> Self {
201 map
: UnsafeCell
::new(map
),
202 in_use
: Cell
::new(false),
207 impl<Q
: ?Sized
, K
, V
, S
> Index
<&Q
> for FrozenMap
<K
, V
, S
>
210 K
: Eq
+ Hash
+ Borrow
<Q
>,
214 type Output
= V
::Target
;
219 /// use elsa::FrozenMap;
221 /// let map = FrozenMap::new();
222 /// map.insert(1, Box::new("a"));
223 /// assert_eq!(map[&1], "a");
225 fn index(&self, idx
: &Q
) -> &V
::Target
{
227 .expect("attempted to index FrozenMap with unknown key")
231 impl<K
: Eq
+ Hash
, V
, S
: BuildHasher
+ Default
> FromIterator
<(K
, V
)> for FrozenMap
<K
, V
, S
> {
232 fn from_iter
<T
>(iter
: T
) -> Self
234 T
: IntoIterator
<Item
= (K
, V
)>,
236 let map
: HashMap
<_
, _
, _
> = iter
.into_iter().collect();
241 impl<K
: Eq
+ Hash
, V
, S
: Default
> Default
for FrozenMap
<K
, V
, S
> {
242 fn default() -> Self {
244 map
: UnsafeCell
::new(Default
::default()),
245 in_use
: Cell
::new(false),
250 /// Append-only version of `std::collections::BTreeMap` where
251 /// insertion does not require mutable access
252 pub struct FrozenBTreeMap
<K
, V
> {
253 map
: UnsafeCell
<BTreeMap
<K
, V
>>,
254 /// Eq/Hash implementations can have side-effects, and using Rc it is possible
255 /// for FrozenBTreeMap::insert to be called on a key that itself contains the same
256 /// `FrozenBTreeMap`, whose `eq` implementation also calls FrozenBTreeMap::insert
258 /// We use this `in_use` flag to guard against any reentrancy.
262 // safety: UnsafeCell implies !Sync
264 impl<K
: Clone
+ Ord
, V
: StableDeref
> FrozenBTreeMap
<K
, V
> {
265 pub fn new() -> Self {
267 map
: UnsafeCell
::new(Default
::default()),
268 in_use
: Cell
::new(false),
275 /// use elsa::FrozenBTreeMap;
277 /// let map = FrozenBTreeMap::new();
278 /// assert_eq!(map.len(), 0);
279 /// map.insert(1, Box::new("a"));
280 /// assert_eq!(map.len(), 1);
282 pub fn len(&self) -> usize {
283 assert
!(!self.in_use
.get());
284 self.in_use
.set(true);
286 let map
= self.map
.get();
289 self.in_use
.set(false);
296 /// use elsa::FrozenBTreeMap;
298 /// let map = FrozenBTreeMap::new();
299 /// assert_eq!(map.is_empty(), true);
300 /// map.insert(1, Box::new("a"));
301 /// assert_eq!(map.is_empty(), false);
303 pub fn is_empty(&self) -> bool
{
308 impl<K
: Clone
+ Ord
, V
: StableDeref
> FrozenBTreeMap
<K
, V
> {
309 // these should never return &K or &V
310 // these should never delete any entries
311 pub fn insert(&self, k
: K
, v
: V
) -> &V
::Target
{
312 assert
!(!self.in_use
.get());
313 self.in_use
.set(true);
315 let map
= self.map
.get();
316 &*(*map
).entry(k
).or_insert(v
)
318 self.in_use
.set(false);
322 /// Returns a reference to the value corresponding to the key.
324 /// The key may be any borrowed form of the map's key type, but
325 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
331 /// use elsa::FrozenBTreeMap;
333 /// let map = FrozenBTreeMap::new();
334 /// map.insert(1, Box::new("a"));
335 /// assert_eq!(map.get(&1), Some(&"a"));
336 /// assert_eq!(map.get(&2), None);
338 pub fn get
<Q
: ?Sized
>(&self, k
: &Q
) -> Option
<&V
::Target
>
343 assert
!(!self.in_use
.get());
344 self.in_use
.set(true);
346 let map
= self.map
.get();
347 (*map
).get(k
).map(|x
| &**x
)
349 self.in_use
.set(false);
353 /// Applies a function to the owner of the value corresponding to the key (if any).
355 /// The key may be any borrowed form of the map's key type, but
356 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
362 /// use elsa::FrozenBTreeMap;
364 /// let map = FrozenBTreeMap::new();
365 /// map.insert(1, Box::new("a"));
366 /// assert_eq!(map.map_get(&1, Clone::clone), Some(Box::new("a")));
367 /// assert_eq!(map.map_get(&2, Clone::clone), None);
369 pub fn map_get
<Q
: ?Sized
, T
, F
>(&self, k
: &Q
, f
: F
) -> Option
<T
>
375 assert
!(!self.in_use
.get());
376 self.in_use
.set(true);
378 let map
= self.map
.get();
381 self.in_use
.set(false);
385 pub fn into_map(self) -> BTreeMap
<K
, V
> {
386 self.map
.into_inner()
392 impl<K
, V
> std
::convert
::AsMut
<BTreeMap
<K
, V
>> for FrozenBTreeMap
<K
, V
> {
393 /// Get mutable access to the underlying [`HashMap`].
395 /// This is safe, as it requires a `&mut self`, ensuring nothing is using
396 /// the 'frozen' contents.
397 fn as_mut(&mut self) -> &mut BTreeMap
<K
, V
> {
398 unsafe { &mut *self.map.get() }
402 impl<K
: Clone
+ Ord
, V
: StableDeref
> From
<BTreeMap
<K
, V
>> for FrozenBTreeMap
<K
, V
> {
403 fn from(map
: BTreeMap
<K
, V
>) -> Self {
405 map
: UnsafeCell
::new(map
),
406 in_use
: Cell
::new(false),
411 impl<Q
: ?Sized
, K
, V
> Index
<&Q
> for FrozenBTreeMap
<K
, V
>
414 K
: Clone
+ Ord
+ Borrow
<Q
>,
417 type Output
= V
::Target
;
422 /// use elsa::FrozenBTreeMap;
424 /// let map = FrozenBTreeMap::new();
425 /// map.insert(1, Box::new("a"));
426 /// assert_eq!(map[&1], "a");
428 fn index(&self, idx
: &Q
) -> &V
::Target
{
430 .expect("attempted to index FrozenBTreeMap with unknown key")
434 impl<K
: Clone
+ Ord
, V
: StableDeref
> FromIterator
<(K
, V
)> for FrozenBTreeMap
<K
, V
> {
435 fn from_iter
<T
>(iter
: T
) -> Self
437 T
: IntoIterator
<Item
= (K
, V
)>,
439 let map
: BTreeMap
<_
, _
> = iter
.into_iter().collect();
444 impl<K
: Clone
+ Ord
, V
: StableDeref
> Default
for FrozenBTreeMap
<K
, V
> {
445 fn default() -> Self {
447 map
: UnsafeCell
::new(Default
::default()),
448 in_use
: Cell
::new(false),