1use crate::base::{
2 drain::{DrainInner, HeaplessDrain},
3 entry::{Entry, HeaplessEntry, OccupiedEntry, VacantEntry},
4 iter::{IntoIterInner, IterInner, IterMutInner},
5};
6use std::borrow::Borrow;
7use std::collections::HashMap;
8use std::fmt::Display;
9use std::hash::Hash;
10use std::hint::unreachable_unchecked;
11use std::mem::ManuallyDrop;
12use std::ptr;
13
14pub(crate) mod drain;
15pub(crate) mod entry;
16#[cfg(feature = "extract_if")]
17pub(crate) mod extract_if;
18pub(crate) mod iter;
19
20pub(crate) enum MapImpl<K, V, const N: usize> {
21 Heapless(heapless::Vec<(K, V), N>),
22 Spilled(HashMap<K, V>),
23}
24
25impl<K, V, const N: usize> MapImpl<K, V, N> {
26 #[inline(always)]
27 pub const fn new() -> Self {
28 Self::Heapless(heapless::Vec::new())
29 }
30
31 #[inline(always)]
32 pub const fn spilled(&self) -> bool {
33 matches!(self, Self::Spilled(_))
34 }
35
36 #[inline(always)]
37 pub fn capacity(&self) -> usize {
38 match self {
39 Self::Heapless(_) => N,
40 Self::Spilled(m) => m.capacity(),
41 }
42 }
43
44 #[inline]
45 pub fn iter(&self) -> IterInner<'_, K, V, N> {
46 match self {
47 Self::Heapless(vec) => IterInner::Heapless { next: 0, vec },
48 Self::Spilled(map) => IterInner::Spilled(map.iter()),
49 }
50 }
51
52 #[inline]
53 pub fn iter_mut(&mut self) -> IterMutInner<'_, K, V, N> {
54 match self {
55 Self::Heapless(vec) => IterMutInner::Heapless(vec.iter_mut()),
56 Self::Spilled(map) => IterMutInner::Spilled(map.iter_mut()),
57 }
58 }
59
60 #[inline]
61 pub fn len(&self) -> usize {
62 match self {
63 Self::Heapless(vec) => vec.len(),
64 Self::Spilled(map) => map.len(),
65 }
66 }
67
68 #[inline]
69 pub fn is_empty(&self) -> bool {
70 match self {
71 Self::Heapless(vec) => vec.is_empty(),
72 Self::Spilled(m) => m.is_empty(),
73 }
74 }
75
76 #[inline]
77 pub fn drain(&mut self) -> DrainInner<'_, K, V, N> {
78 match self {
79 Self::Heapless(base) => DrainInner::Heapless(HeaplessDrain { base }),
80 Self::Spilled(map) => DrainInner::Spilled(map.drain()),
81 }
82 }
83
84 #[cfg(feature = "extract_if")]
85 #[inline]
86 pub fn extract_if<F>(&mut self, pred: F) -> extract_if::ExtractIfInner<'_, K, V, F, N>
87 where
88 F: FnMut(&K, &mut V) -> bool,
89 {
90 match self {
91 Self::Heapless(base) => extract_if::ExtractIfInner::Heapless {
92 base,
93 next: 0,
94 pred,
95 },
96 Self::Spilled(map) => extract_if::ExtractIfInner::Spilled(map.extract_if(pred)),
97 }
98 }
99
100 #[inline]
101 pub fn retain<F>(&mut self, mut f: F)
102 where
103 F: FnMut(&K, &mut V) -> bool,
104 {
105 match self {
106 Self::Heapless(vec) => {
107 vec.retain_mut(|(k, v)| f(k, v));
108 }
109 Self::Spilled(map) => {
110 map.retain(f);
111 }
112 }
113 }
114
115 #[inline]
116 pub fn clear(&mut self) {
117 match self {
118 Self::Heapless(vec) => vec.clear(),
119 Self::Spilled(m) => m.clear(),
120 }
121 }
122
123 #[inline]
127 unsafe fn into_heapless_unchecked(self) -> heapless::Vec<(K, V), N> {
128 match self {
129 Self::Heapless(v) => v,
130 _ => unsafe { unreachable_unchecked() },
131 }
132 }
133
134 #[inline]
138 unsafe fn into_spilled_unchecked(self) -> HashMap<K, V> {
139 match self {
140 Self::Spilled(m) => m,
141 _ => unsafe { unreachable_unchecked() },
142 }
143 }
144
145 #[inline]
149 unsafe fn as_heapless_unchecked(&self) -> &heapless::Vec<(K, V), N> {
150 match self {
151 Self::Heapless(m) => m,
152 _ => unsafe { unreachable_unchecked() },
153 }
154 }
155
156 #[inline]
160 unsafe fn as_heapless_mut_unchecked(&mut self) -> &mut heapless::Vec<(K, V), N> {
161 match self {
162 Self::Heapless(m) => m,
163 _ => unsafe { unreachable_unchecked() },
164 }
165 }
166
167 #[inline]
182 unsafe fn as_spilled_mut_unchecked(&mut self) -> &mut HashMap<K, V> {
183 match self {
184 Self::Spilled(m) => m,
185 _ => unsafe { unreachable_unchecked() },
186 }
187 }
188}
189
190impl<K, V, const N: usize> MapImpl<K, V, N>
191where
192 K: Eq + Hash,
193{
194 #[inline]
195 pub fn reserve(&mut self, additional: usize) {
196 if !self.spilled() && self.len() + additional > N {
197 unsafe { self.try_spill(additional) }.unwrap();
199 } else {
200 unsafe {
202 self.as_spilled_mut_unchecked().reserve(additional);
203 }
204 }
205 }
206
207 #[inline]
208 pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
209 if !self.spilled() {
210 if self.len() + additional > N {
211 unsafe { self.try_spill(additional) }?;
213 }
214 } else {
216 unsafe {
218 self.as_spilled_mut_unchecked().try_reserve(additional)?;
219 }
220 }
221 Ok(())
222 }
223
224 #[inline]
225 pub fn spill(&mut self) {
226 if !self.spilled() {
227 unsafe { self.try_spill(0) }.unwrap();
229 }
230 }
231
232 pub fn shrink_into_heapless<const M: usize>(
233 self,
234 ) -> Result<MapImpl<K, V, M>, MapImpl<K, V, N>> {
235 if self.len() > M {
236 return Err(self);
237 }
238
239 let heapless = match self {
240 MapImpl::Heapless(vec) => {
241 let vec = ManuallyDrop::new(vec);
242 let mut new = heapless::Vec::new();
243 unsafe {
244 ptr::copy_nonoverlapping(vec.as_ptr(), new.as_mut_ptr(), vec.len());
246 new.set_len(vec.len());
247 }
248 new
249 }
250 MapImpl::Spilled(map) => map.into_iter().collect::<heapless::Vec<(K, V), M>>(),
251 };
252
253 Ok(MapImpl::Heapless(heapless))
254 }
255
256 #[inline]
257 pub fn shrink_to_fit(&mut self) {
258 if let Self::Spilled(map) = self {
259 map.shrink_to_fit()
260 }
261 }
262
263 #[inline]
264 pub fn shrink_to(&mut self, min_capacity: usize) {
265 if let Self::Spilled(map) = self {
266 map.shrink_to(min_capacity)
267 }
268 }
269
270 #[inline]
271 pub fn entry(&mut self, key: K) -> Entry<'_, K, V, N> {
272 match self {
273 Self::Heapless(vec) => {
274 if vec.is_empty() {
275 Entry::Vacant(VacantEntry::Heapless(HeaplessEntry {
276 key: Some(key),
277 inner: self,
278 index: 0,
279 }))
280 } else if let Some(index) = vec.iter().position(|(k, _)| k == &key) {
281 Entry::Occupied(OccupiedEntry::Heapless(HeaplessEntry {
282 key: Some(key),
283 inner: self,
284 index,
285 }))
286 } else {
287 let len = vec.len();
288 Entry::Vacant(VacantEntry::Heapless(HeaplessEntry {
289 key: Some(key),
290 inner: self,
291 index: len,
292 }))
293 }
294 }
295 Self::Spilled(map) => match map.entry(key) {
296 std::collections::hash_map::Entry::Occupied(entry) => {
297 Entry::Occupied(OccupiedEntry::Spilled(entry))
298 }
299 std::collections::hash_map::Entry::Vacant(entry) => {
300 Entry::Vacant(VacantEntry::Spilled(entry))
301 }
302 },
303 }
304 }
305
306 #[inline]
307 pub fn get<Q>(&self, k: &Q) -> Option<&V>
308 where
309 K: Borrow<Q>,
310 Q: Hash + Eq + ?Sized,
311 {
312 match self.get_key_value(k) {
313 Some((_, value)) => Some(value),
314 None => None,
315 }
316 }
317
318 #[inline]
319 pub fn get_key_value<Q>(&self, k: &Q) -> Option<(&K, &V)>
320 where
321 K: Borrow<Q>,
322 Q: Hash + Eq + ?Sized,
323 {
324 match self {
325 Self::Heapless(vec) => {
326 if vec.is_empty() {
327 None
328 } else {
329 match vec.iter().find(|(key, _)| key.borrow() == k) {
330 Some((key, value)) => Some((key, value)),
331 None => None,
332 }
333 }
334 }
335 Self::Spilled(map) => map.get_key_value(k),
336 }
337 }
338
339 #[cfg(feature = "many_mut")]
340 #[inline]
341 pub fn get_many_mut<Q, const M: usize>(&mut self, ks: [&Q; M]) -> Option<[&'_ mut V; M]>
342 where
343 K: Borrow<Q>,
344 Q: Hash + Eq + ?Sized,
345 {
346 match self {
347 Self::Heapless(vec) => {
348 let is =
349 ks.map(|k| {
350 vec.iter().enumerate().find_map(|(i, (key, _))| {
351 if key.borrow() == k {
352 Some(i)
353 } else {
354 None
355 }
356 })
357 });
358 if is.iter().any(|i| i.is_none()) {
359 return None;
360 }
361 let is = is.map(|i| unsafe { i.unwrap_unchecked() });
362 Some(vec.get_many_mut(is).ok()?.map(|(_, v)| v))
363 }
364 Self::Spilled(map) => map.get_many_mut(ks),
365 }
366 }
367
368 #[cfg(feature = "many_mut")]
369 #[inline]
370 pub unsafe fn get_many_unchecked_mut<Q, const M: usize>(
371 &mut self,
372 ks: [&Q; M],
373 ) -> Option<[&'_ mut V; M]>
374 where
375 K: Borrow<Q>,
376 Q: Hash + Eq + ?Sized,
377 {
378 match self {
379 Self::Heapless(vec) => {
380 let is =
381 ks.map(|k| {
382 vec.iter().enumerate().find_map(|(i, (key, _))| {
383 if key.borrow() == k {
384 Some(i)
385 } else {
386 None
387 }
388 })
389 });
390 if is.iter().any(|i| i.is_none()) {
391 return None;
392 }
393 let is = is.map(|i| unsafe { i.unwrap_unchecked() });
394 let es = unsafe { vec.get_many_unchecked_mut(is) };
395 Some(es.map(|(_, v)| v))
396 }
397 Self::Spilled(map) => unsafe { map.get_many_unchecked_mut(ks) },
398 }
399 }
400
401 #[inline]
402 pub fn contains_key<Q>(&self, k: &Q) -> bool
403 where
404 K: Borrow<Q>,
405 Q: Hash + Eq + ?Sized,
406 {
407 self.get(k).is_some()
408 }
409
410 #[inline]
411 pub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
412 where
413 K: Borrow<Q>,
414 Q: Hash + Eq + ?Sized,
415 {
416 match self {
417 Self::Heapless(vec) => {
418 if vec.is_empty() {
419 None
420 } else {
421 match vec.iter_mut().find(|(key, _)| key.borrow() == k) {
422 Some((_, value)) => Some(value),
423 None => None,
424 }
425 }
426 }
427 Self::Spilled(map) => map.get_mut(k),
428 }
429 }
430
431 pub fn insert(&mut self, k: K, v: V) -> Option<V> {
432 match self {
433 Self::Heapless(vec) => {
434 for (key, value) in vec.iter_mut() {
436 if key == &k {
437 return Some(std::mem::replace(value, v));
438 }
439 }
440 match vec.push((k, v)) {
443 Ok(()) => None,
444 Err((k, v)) => {
445 let map = unsafe { self.try_spill(1) };
448 map.unwrap().insert(k, v);
449 None
450 }
451 }
452 }
453 Self::Spilled(m) => m.insert(k, v),
454 }
455 }
456
457 #[inline]
458 pub fn remove<Q>(&mut self, k: &Q) -> Option<V>
459 where
460 K: Borrow<Q>,
461 Q: Hash + Eq + ?Sized,
462 {
463 match self.remove_entry(k) {
464 Some((_, value)) => Some(value),
465 None => None,
466 }
467 }
468
469 #[inline]
470 pub fn remove_entry<Q>(&mut self, k: &Q) -> Option<(K, V)>
471 where
472 K: Borrow<Q>,
473 Q: Hash + Eq + ?Sized,
474 {
475 match self {
476 Self::Heapless(vec) => {
477 let index = vec.iter().position(|(key, _)| key.borrow() == k)?;
479 Some(unsafe { vec.swap_remove_unchecked(index) })
481 }
482 Self::Spilled(m) => m.remove_entry(k),
483 }
484 }
485
486 #[inline]
487 pub fn into_hashmap(mut self) -> HashMap<K, V> {
488 if !self.spilled() {
489 unsafe { self.try_spill(0) }.unwrap();
491 }
492 unsafe { self.into_spilled_unchecked() }
494 }
495
496 #[inline]
500 unsafe fn try_spill(
501 &mut self,
502 additional: usize,
503 ) -> Result<&mut HashMap<K, V>, TryReserveError> {
504 let cap_needed = N
505 .checked_add(additional)
506 .ok_or(TryReserveError { kind: () })?;
507 let mut map = HashMap::new();
508 map.try_reserve(cap_needed)?;
509 let vec = std::mem::replace(self, Self::Spilled(map));
510 let (vec, map) = unsafe {
511 (
513 vec.into_heapless_unchecked(),
514 self.as_spilled_mut_unchecked(),
515 )
516 };
517 map.extend(vec);
518 Ok(map)
519 }
520
521 pub fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
522 if let MapImpl::Spilled(map) = self {
523 map.extend(iter);
524 return;
525 }
526 for (k, v) in iter {
527 self.insert(k, v);
528 }
529 }
530}
531
532impl<K, V, const N: usize> IntoIterator for MapImpl<K, V, N> {
533 type Item = (K, V);
534 type IntoIter = IntoIterInner<K, V, N>;
535
536 #[inline]
537 fn into_iter(self) -> IntoIterInner<K, V, N> {
538 match self {
539 MapImpl::Heapless(vec) => IntoIterInner::Heapless(vec),
540 MapImpl::Spilled(map) => IntoIterInner::Spilled(map.into_iter()),
541 }
542 }
543}
544
545impl<K, V, const N: usize, const M: usize> From<[(K, V); N]> for MapImpl<K, V, M>
546where
547 K: Eq + Hash,
548{
549 fn from(arr: [(K, V); N]) -> Self {
550 if N <= M {
551 Self::Heapless(heapless::Vec::from_iter(arr))
552 } else {
553 Self::Spilled(HashMap::from(arr))
554 }
555 }
556}
557
558#[derive(Clone, PartialEq, Eq, Debug)]
560pub struct TryReserveError {
561 kind: (),
562}
563
564impl From<std::collections::TryReserveError> for TryReserveError {
565 fn from(_: std::collections::TryReserveError) -> Self {
566 Self { kind: () }
567 }
568}
569
570impl Display for TryReserveError {
571 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
572 fmt.write_str("memory allocation failed")
573 }
574}
575
576impl std::error::Error for TryReserveError {}