1use super::{BiHashItem, BiHashMap, RefMut, entry_indexes::EntryIndexes};
2use crate::{
3 DefaultHashBuilder,
4 support::{
5 alloc::{Allocator, Global},
6 borrow::DormantMutRef,
7 map_hash::MapHash,
8 },
9};
10use alloc::vec::Vec;
11use core::{fmt, hash::BuildHasher};
12
13pub enum Entry<'a, T: BiHashItem, S = DefaultHashBuilder, A: Allocator = Global>
15{
16 Vacant(VacantEntry<'a, T, S, A>),
18 Occupied(OccupiedEntry<'a, T, S, A>),
20}
21
22impl<'a, T: BiHashItem, S, A: Allocator> fmt::Debug for Entry<'a, T, S, A> {
23 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24 match self {
25 Entry::Vacant(entry) => {
26 f.debug_tuple("Vacant").field(entry).finish()
27 }
28 Entry::Occupied(entry) => {
29 f.debug_tuple("Occupied").field(entry).finish()
30 }
31 }
32 }
33}
34
35impl<'a, T: BiHashItem, S: Clone + BuildHasher, A: Allocator>
36 Entry<'a, T, S, A>
37{
38 #[inline]
46 pub fn or_insert(self, default: T) -> OccupiedEntryMut<'a, T, S> {
47 match self {
48 Entry::Occupied(entry) => entry.into_mut(),
49 Entry::Vacant(entry) => {
50 OccupiedEntryMut::Unique(entry.insert(default))
51 }
52 }
53 }
54
55 #[inline]
64 pub fn or_insert_with<F: FnOnce() -> T>(
65 self,
66 default: F,
67 ) -> OccupiedEntryMut<'a, T, S> {
68 match self {
69 Entry::Occupied(entry) => entry.into_mut(),
70 Entry::Vacant(entry) => {
71 OccupiedEntryMut::Unique(entry.insert(default()))
72 }
73 }
74 }
75
76 #[inline]
81 pub fn and_modify<F>(self, f: F) -> Self
82 where
83 F: FnMut(RefMut<'_, T, S>),
84 {
85 match self {
86 Entry::Occupied(mut entry) => {
87 entry.get_mut().for_each(f);
88 Entry::Occupied(entry)
89 }
90 Entry::Vacant(entry) => Entry::Vacant(entry),
91 }
92 }
93}
94
95pub struct VacantEntry<
97 'a,
98 T: BiHashItem,
99 S = DefaultHashBuilder,
100 A: Allocator = Global,
101> {
102 map: DormantMutRef<'a, BiHashMap<T, S, A>>,
103 hashes: [MapHash<S>; 2],
104}
105
106impl<'a, T: BiHashItem, S, A: Allocator> fmt::Debug
107 for VacantEntry<'a, T, S, A>
108{
109 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110 f.debug_struct("VacantEntry")
111 .field("hashes", &self.hashes)
112 .finish_non_exhaustive()
113 }
114}
115
116impl<'a, T: BiHashItem, S: Clone + BuildHasher, A: Allocator>
117 VacantEntry<'a, T, S, A>
118{
119 pub(super) unsafe fn new(
120 map: DormantMutRef<'a, BiHashMap<T, S, A>>,
121 hashes: [MapHash<S>; 2],
122 ) -> Self {
123 VacantEntry { map, hashes }
124 }
125
126 pub fn insert(self, value: T) -> RefMut<'a, T, S> {
129 if !self.hashes[0].is_same_hash(value.key1()) {
130 panic!("key1 hashes do not match");
131 }
132 if !self.hashes[1].is_same_hash(value.key2()) {
133 panic!("key2 hashes do not match");
134 }
135
136 let map = unsafe { self.map.awaken() };
139 let Ok(index) = map.insert_unique_impl(value) else {
140 panic!("key already present in map");
141 };
142 map.get_by_index_mut(index).expect("index is known to be valid")
143 }
144
145 #[inline]
147 pub fn insert_entry(mut self, value: T) -> OccupiedEntry<'a, T, S, A> {
148 if !self.hashes[0].is_same_hash(value.key1()) {
149 panic!("key1 hashes do not match");
150 }
151 if !self.hashes[1].is_same_hash(value.key2()) {
152 panic!("key2 hashes do not match");
153 }
154
155 let index = {
156 let map = unsafe { self.map.reborrow() };
159 let Ok(index) = map.insert_unique_impl(value) else {
160 panic!("key already present in map");
161 };
162 index
163 };
164
165 unsafe { OccupiedEntry::new(self.map, EntryIndexes::Unique(index)) }
168 }
169}
170
171pub struct OccupiedEntry<
174 'a,
175 T: BiHashItem,
176 S = DefaultHashBuilder,
177 A: Allocator = Global,
178> {
179 map: DormantMutRef<'a, BiHashMap<T, S, A>>,
180 indexes: EntryIndexes,
181}
182
183impl<'a, T: BiHashItem, S, A: Allocator> fmt::Debug
184 for OccupiedEntry<'a, T, S, A>
185{
186 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
187 f.debug_struct("OccupiedEntry")
188 .field("indexes", &self.indexes)
189 .finish_non_exhaustive()
190 }
191}
192
193impl<'a, T: BiHashItem, S: Clone + BuildHasher, A: Allocator>
194 OccupiedEntry<'a, T, S, A>
195{
196 pub(super) unsafe fn new(
201 map: DormantMutRef<'a, BiHashMap<T, S, A>>,
202 indexes: EntryIndexes,
203 ) -> Self {
204 OccupiedEntry { map, indexes }
205 }
206
207 pub fn is_unique(&self) -> bool {
213 self.indexes.is_unique()
214 }
215
216 #[inline]
219 pub fn is_non_unique(&self) -> bool {
220 !self.is_unique()
221 }
222
223 pub fn get(&self) -> OccupiedEntryRef<'_, T> {
228 let map = unsafe { self.map.reborrow_shared() };
231 map.get_by_entry_index(self.indexes)
232 }
233
234 pub fn get_mut(&mut self) -> OccupiedEntryMut<'_, T, S> {
239 let map = unsafe { self.map.reborrow() };
242 map.get_by_entry_index_mut(self.indexes)
243 }
244
245 pub fn into_ref(self) -> OccupiedEntryRef<'a, T> {
251 let map = unsafe { self.map.awaken() };
254 map.get_by_entry_index(self.indexes)
255 }
256
257 pub fn into_mut(self) -> OccupiedEntryMut<'a, T, S> {
263 let map = unsafe { self.map.awaken() };
266 map.get_by_entry_index_mut(self.indexes)
267 }
268
269 pub fn insert(&mut self, value: T) -> Vec<T> {
275 let map = unsafe { self.map.reborrow() };
280 let (index, old_items) = map.replace_at_indexes(self.indexes, value);
281 self.indexes = EntryIndexes::Unique(index);
282 old_items
283 }
284
285 pub fn remove(mut self) -> Vec<T> {
287 let map = unsafe { self.map.reborrow() };
290 map.remove_by_entry_index(self.indexes)
291 }
292}
293
294#[derive(Debug)]
298pub enum OccupiedEntryRef<'a, T: BiHashItem> {
299 Unique(&'a T),
301
302 NonUnique {
306 by_key1: Option<&'a T>,
308
309 by_key2: Option<&'a T>,
311 },
312}
313
314impl<'a, T: BiHashItem> OccupiedEntryRef<'a, T> {
315 #[inline]
321 pub fn is_unique(&self) -> bool {
322 matches!(self, Self::Unique(_))
323 }
324
325 #[inline]
328 pub fn is_non_unique(&self) -> bool {
329 matches!(self, Self::NonUnique { .. })
330 }
331
332 #[inline]
334 pub fn as_unique(&self) -> Option<&'a T> {
335 match self {
336 Self::Unique(v) => Some(v),
337 Self::NonUnique { .. } => None,
338 }
339 }
340
341 #[inline]
343 pub fn by_key1(&self) -> Option<&'a T> {
344 match self {
345 Self::Unique(v) => Some(v),
346 Self::NonUnique { by_key1, .. } => *by_key1,
347 }
348 }
349
350 #[inline]
352 pub fn by_key2(&self) -> Option<&'a T> {
353 match self {
354 Self::Unique(v) => Some(v),
355 Self::NonUnique { by_key2, .. } => *by_key2,
356 }
357 }
358}
359
360pub enum OccupiedEntryMut<
364 'a,
365 T: BiHashItem,
366 S: Clone + BuildHasher = DefaultHashBuilder,
367> {
368 Unique(RefMut<'a, T, S>),
370
371 NonUnique {
373 by_key1: Option<RefMut<'a, T, S>>,
375
376 by_key2: Option<RefMut<'a, T, S>>,
378 },
379}
380
381impl<'a, T: BiHashItem + fmt::Debug, S: Clone + BuildHasher> fmt::Debug
382 for OccupiedEntryMut<'a, T, S>
383{
384 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
385 match self {
386 OccupiedEntryMut::Unique(ref_mut) => {
387 f.debug_tuple("Unique").field(ref_mut).finish()
388 }
389 OccupiedEntryMut::NonUnique { by_key1, by_key2 } => f
390 .debug_struct("NonUnique")
391 .field("by_key1", by_key1)
392 .field("by_key2", by_key2)
393 .finish(),
394 }
395 }
396}
397
398impl<'a, T: BiHashItem, S: Clone + BuildHasher> OccupiedEntryMut<'a, T, S> {
399 #[inline]
401 pub fn is_unique(&self) -> bool {
402 matches!(self, Self::Unique(_))
403 }
404
405 #[inline]
408 pub fn is_non_unique(&self) -> bool {
409 matches!(self, Self::NonUnique { .. })
410 }
411
412 #[inline]
414 pub fn as_unique(&mut self) -> Option<RefMut<'_, T, S>> {
415 match self {
416 Self::Unique(v) => Some(v.reborrow()),
417 Self::NonUnique { .. } => None,
418 }
419 }
420
421 #[inline]
423 pub fn by_key1(&mut self) -> Option<RefMut<'_, T, S>> {
424 match self {
425 Self::Unique(v) => Some(v.reborrow()),
426 Self::NonUnique { by_key1, .. } => {
427 by_key1.as_mut().map(|v| v.reborrow())
428 }
429 }
430 }
431
432 #[inline]
434 pub fn by_key2(&mut self) -> Option<RefMut<'_, T, S>> {
435 match self {
436 Self::Unique(v) => Some(v.reborrow()),
437 Self::NonUnique { by_key2, .. } => {
438 by_key2.as_mut().map(|v| v.reborrow())
439 }
440 }
441 }
442
443 pub fn for_each<F>(&mut self, mut f: F)
445 where
446 F: FnMut(RefMut<'_, T, S>),
447 {
448 match self {
449 Self::Unique(v) => f(v.reborrow()),
450 Self::NonUnique { by_key1, by_key2 } => {
451 if let Some(v) = by_key1 {
452 f(v.reborrow());
453 }
454 if let Some(v) = by_key2 {
455 f(v.reborrow());
456 }
457 }
458 }
459 }
460}