xref: /aosp_15_r20/external/crosvm/devices/src/virtio/fs/multikey.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2019 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker use std::borrow::Borrow;
6*bb4ee6a4SAndroid Build Coastguard Worker use std::collections::BTreeMap;
7*bb4ee6a4SAndroid Build Coastguard Worker 
8*bb4ee6a4SAndroid Build Coastguard Worker /// A BTreeMap that supports 2 types of keys per value. All the usual restrictions and warnings for
9*bb4ee6a4SAndroid Build Coastguard Worker /// `std::collections::BTreeMap` also apply to this struct. Additionally, there is a 1:1
10*bb4ee6a4SAndroid Build Coastguard Worker /// relationship between the 2 key types. In other words, for each `K1` in the map, there is exactly
11*bb4ee6a4SAndroid Build Coastguard Worker /// one `K2` in the map and vice versa.
12*bb4ee6a4SAndroid Build Coastguard Worker pub struct MultikeyBTreeMap<K1, K2, V> {
13*bb4ee6a4SAndroid Build Coastguard Worker     // We need to keep a copy of the second key in the main map so that we can remove entries using
14*bb4ee6a4SAndroid Build Coastguard Worker     // just the main key. Otherwise we would require the caller to provide both keys when calling
15*bb4ee6a4SAndroid Build Coastguard Worker     // `remove`.
16*bb4ee6a4SAndroid Build Coastguard Worker     main: BTreeMap<K1, (K2, V)>,
17*bb4ee6a4SAndroid Build Coastguard Worker     alt: BTreeMap<K2, K1>,
18*bb4ee6a4SAndroid Build Coastguard Worker }
19*bb4ee6a4SAndroid Build Coastguard Worker 
20*bb4ee6a4SAndroid Build Coastguard Worker impl<K1, K2, V> MultikeyBTreeMap<K1, K2, V>
21*bb4ee6a4SAndroid Build Coastguard Worker where
22*bb4ee6a4SAndroid Build Coastguard Worker     K1: Clone + Ord,
23*bb4ee6a4SAndroid Build Coastguard Worker     K2: Clone + Ord,
24*bb4ee6a4SAndroid Build Coastguard Worker {
25*bb4ee6a4SAndroid Build Coastguard Worker     /// Create a new empty MultikeyBTreeMap.
new() -> Self26*bb4ee6a4SAndroid Build Coastguard Worker     pub fn new() -> Self {
27*bb4ee6a4SAndroid Build Coastguard Worker         MultikeyBTreeMap {
28*bb4ee6a4SAndroid Build Coastguard Worker             main: BTreeMap::default(),
29*bb4ee6a4SAndroid Build Coastguard Worker             alt: BTreeMap::default(),
30*bb4ee6a4SAndroid Build Coastguard Worker         }
31*bb4ee6a4SAndroid Build Coastguard Worker     }
32*bb4ee6a4SAndroid Build Coastguard Worker 
33*bb4ee6a4SAndroid Build Coastguard Worker     /// Returns a reference to the value corresponding to the key.
34*bb4ee6a4SAndroid Build Coastguard Worker     ///
35*bb4ee6a4SAndroid Build Coastguard Worker     /// The key may be any borrowed form of `K1``, but the ordering on the borrowed form must match
36*bb4ee6a4SAndroid Build Coastguard Worker     /// the ordering on `K1`.
get<Q>(&self, key: &Q) -> Option<&V> where K1: Borrow<Q>, Q: Ord + ?Sized,37*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get<Q>(&self, key: &Q) -> Option<&V>
38*bb4ee6a4SAndroid Build Coastguard Worker     where
39*bb4ee6a4SAndroid Build Coastguard Worker         K1: Borrow<Q>,
40*bb4ee6a4SAndroid Build Coastguard Worker         Q: Ord + ?Sized,
41*bb4ee6a4SAndroid Build Coastguard Worker     {
42*bb4ee6a4SAndroid Build Coastguard Worker         self.main.get(key).map(|(_, v)| v)
43*bb4ee6a4SAndroid Build Coastguard Worker     }
44*bb4ee6a4SAndroid Build Coastguard Worker 
45*bb4ee6a4SAndroid Build Coastguard Worker     /// Returns a reference to the value corresponding to the alternate key.
46*bb4ee6a4SAndroid Build Coastguard Worker     ///
47*bb4ee6a4SAndroid Build Coastguard Worker     /// The key may be any borrowed form of the `K2``, but the ordering on the borrowed form must
48*bb4ee6a4SAndroid Build Coastguard Worker     /// match the ordering on `K2`.
49*bb4ee6a4SAndroid Build Coastguard Worker     ///
50*bb4ee6a4SAndroid Build Coastguard Worker     /// Note that this method performs 2 lookups: one to get the main key and another to get the
51*bb4ee6a4SAndroid Build Coastguard Worker     /// value associated with that key. For best performance callers should prefer the `get` method
52*bb4ee6a4SAndroid Build Coastguard Worker     /// over this method whenever possible as `get` only needs to perform one lookup.
get_alt<Q2>(&self, key: &Q2) -> Option<&V> where K2: Borrow<Q2>, Q2: Ord + ?Sized,53*bb4ee6a4SAndroid Build Coastguard Worker     pub fn get_alt<Q2>(&self, key: &Q2) -> Option<&V>
54*bb4ee6a4SAndroid Build Coastguard Worker     where
55*bb4ee6a4SAndroid Build Coastguard Worker         K2: Borrow<Q2>,
56*bb4ee6a4SAndroid Build Coastguard Worker         Q2: Ord + ?Sized,
57*bb4ee6a4SAndroid Build Coastguard Worker     {
58*bb4ee6a4SAndroid Build Coastguard Worker         if let Some(k) = self.alt.get(key) {
59*bb4ee6a4SAndroid Build Coastguard Worker             self.get(k)
60*bb4ee6a4SAndroid Build Coastguard Worker         } else {
61*bb4ee6a4SAndroid Build Coastguard Worker             None
62*bb4ee6a4SAndroid Build Coastguard Worker         }
63*bb4ee6a4SAndroid Build Coastguard Worker     }
64*bb4ee6a4SAndroid Build Coastguard Worker 
65*bb4ee6a4SAndroid Build Coastguard Worker     /// Inserts a new entry into the map with the given keys and value.
66*bb4ee6a4SAndroid Build Coastguard Worker     ///
67*bb4ee6a4SAndroid Build Coastguard Worker     /// Returns `None` if the map did not have an entry with `k1` or `k2` present. If exactly one
68*bb4ee6a4SAndroid Build Coastguard Worker     /// key was present, then the value associated with that key is updated, the other key is
69*bb4ee6a4SAndroid Build Coastguard Worker     /// removed, and the old value is returned. If **both** keys were present then the value
70*bb4ee6a4SAndroid Build Coastguard Worker     /// associated with the main key is updated, the value associated with the alternate key is
71*bb4ee6a4SAndroid Build Coastguard Worker     /// removed, and the old value associated with the main key is returned.
insert(&mut self, k1: K1, k2: K2, v: V) -> Option<V>72*bb4ee6a4SAndroid Build Coastguard Worker     pub fn insert(&mut self, k1: K1, k2: K2, v: V) -> Option<V> {
73*bb4ee6a4SAndroid Build Coastguard Worker         let oldval = if let Some(oldkey) = self.alt.insert(k2.clone(), k1.clone()) {
74*bb4ee6a4SAndroid Build Coastguard Worker             self.main.remove(&oldkey)
75*bb4ee6a4SAndroid Build Coastguard Worker         } else {
76*bb4ee6a4SAndroid Build Coastguard Worker             None
77*bb4ee6a4SAndroid Build Coastguard Worker         };
78*bb4ee6a4SAndroid Build Coastguard Worker         self.main
79*bb4ee6a4SAndroid Build Coastguard Worker             .insert(k1, (k2.clone(), v))
80*bb4ee6a4SAndroid Build Coastguard Worker             .or(oldval)
81*bb4ee6a4SAndroid Build Coastguard Worker             .map(|(oldk2, v)| {
82*bb4ee6a4SAndroid Build Coastguard Worker                 if oldk2 != k2 {
83*bb4ee6a4SAndroid Build Coastguard Worker                     self.alt.remove(&oldk2);
84*bb4ee6a4SAndroid Build Coastguard Worker                 }
85*bb4ee6a4SAndroid Build Coastguard Worker                 v
86*bb4ee6a4SAndroid Build Coastguard Worker             })
87*bb4ee6a4SAndroid Build Coastguard Worker     }
88*bb4ee6a4SAndroid Build Coastguard Worker 
89*bb4ee6a4SAndroid Build Coastguard Worker     /// Remove a key from the map, returning the value associated with that key if it was previously
90*bb4ee6a4SAndroid Build Coastguard Worker     /// in the map.
91*bb4ee6a4SAndroid Build Coastguard Worker     ///
92*bb4ee6a4SAndroid Build Coastguard Worker     /// The key may be any borrowed form of `K1``, but the ordering on the borrowed form must match
93*bb4ee6a4SAndroid Build Coastguard Worker     /// the ordering on `K1`.
remove<Q>(&mut self, key: &Q) -> Option<V> where K1: Borrow<Q>, Q: Ord + ?Sized,94*bb4ee6a4SAndroid Build Coastguard Worker     pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
95*bb4ee6a4SAndroid Build Coastguard Worker     where
96*bb4ee6a4SAndroid Build Coastguard Worker         K1: Borrow<Q>,
97*bb4ee6a4SAndroid Build Coastguard Worker         Q: Ord + ?Sized,
98*bb4ee6a4SAndroid Build Coastguard Worker     {
99*bb4ee6a4SAndroid Build Coastguard Worker         self.main.remove(key).map(|(k2, v)| {
100*bb4ee6a4SAndroid Build Coastguard Worker             self.alt.remove(&k2);
101*bb4ee6a4SAndroid Build Coastguard Worker             v
102*bb4ee6a4SAndroid Build Coastguard Worker         })
103*bb4ee6a4SAndroid Build Coastguard Worker     }
104*bb4ee6a4SAndroid Build Coastguard Worker 
105*bb4ee6a4SAndroid Build Coastguard Worker     /// Clears the map, removing all values.
clear(&mut self)106*bb4ee6a4SAndroid Build Coastguard Worker     pub fn clear(&mut self) {
107*bb4ee6a4SAndroid Build Coastguard Worker         self.alt.clear();
108*bb4ee6a4SAndroid Build Coastguard Worker         self.main.clear()
109*bb4ee6a4SAndroid Build Coastguard Worker     }
110*bb4ee6a4SAndroid Build Coastguard Worker }
111*bb4ee6a4SAndroid Build Coastguard Worker 
112*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(test)]
113*bb4ee6a4SAndroid Build Coastguard Worker mod test {
114*bb4ee6a4SAndroid Build Coastguard Worker     use super::*;
115*bb4ee6a4SAndroid Build Coastguard Worker 
116*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
get()117*bb4ee6a4SAndroid Build Coastguard Worker     fn get() {
118*bb4ee6a4SAndroid Build Coastguard Worker         let mut m = MultikeyBTreeMap::<u64, i64, u32>::new();
119*bb4ee6a4SAndroid Build Coastguard Worker 
120*bb4ee6a4SAndroid Build Coastguard Worker         let k1 = 0xc6c8_f5e0_b13e_ed40;
121*bb4ee6a4SAndroid Build Coastguard Worker         let k2 = 0x1a04_ce4b_8329_14fe;
122*bb4ee6a4SAndroid Build Coastguard Worker         let val = 0xf4e3_c360;
123*bb4ee6a4SAndroid Build Coastguard Worker         assert!(m.insert(k1, k2, val).is_none());
124*bb4ee6a4SAndroid Build Coastguard Worker 
125*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(*m.get(&k1).expect("failed to look up main key"), val);
126*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(*m.get_alt(&k2).expect("failed to look up alt key"), val);
127*bb4ee6a4SAndroid Build Coastguard Worker     }
128*bb4ee6a4SAndroid Build Coastguard Worker 
129*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
update_main_key()130*bb4ee6a4SAndroid Build Coastguard Worker     fn update_main_key() {
131*bb4ee6a4SAndroid Build Coastguard Worker         let mut m = MultikeyBTreeMap::<u64, i64, u32>::new();
132*bb4ee6a4SAndroid Build Coastguard Worker 
133*bb4ee6a4SAndroid Build Coastguard Worker         let k1 = 0xc6c8_f5e0_b13e_ed40;
134*bb4ee6a4SAndroid Build Coastguard Worker         let k2 = 0x1a04_ce4b_8329_14fe;
135*bb4ee6a4SAndroid Build Coastguard Worker         let val = 0xf4e3_c360;
136*bb4ee6a4SAndroid Build Coastguard Worker         assert!(m.insert(k1, k2, val).is_none());
137*bb4ee6a4SAndroid Build Coastguard Worker 
138*bb4ee6a4SAndroid Build Coastguard Worker         let new_k1 = 0x3add_f8f8_c7c5_df5e;
139*bb4ee6a4SAndroid Build Coastguard Worker         let val2 = 0x7389_f8a7;
140*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
141*bb4ee6a4SAndroid Build Coastguard Worker             m.insert(new_k1, k2, val2)
142*bb4ee6a4SAndroid Build Coastguard Worker                 .expect("failed to update main key"),
143*bb4ee6a4SAndroid Build Coastguard Worker             val
144*bb4ee6a4SAndroid Build Coastguard Worker         );
145*bb4ee6a4SAndroid Build Coastguard Worker 
146*bb4ee6a4SAndroid Build Coastguard Worker         assert!(m.get(&k1).is_none());
147*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(*m.get(&new_k1).expect("failed to look up main key"), val2);
148*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(*m.get_alt(&k2).expect("failed to look up alt key"), val2);
149*bb4ee6a4SAndroid Build Coastguard Worker     }
150*bb4ee6a4SAndroid Build Coastguard Worker 
151*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
update_alt_key()152*bb4ee6a4SAndroid Build Coastguard Worker     fn update_alt_key() {
153*bb4ee6a4SAndroid Build Coastguard Worker         let mut m = MultikeyBTreeMap::<u64, i64, u32>::new();
154*bb4ee6a4SAndroid Build Coastguard Worker 
155*bb4ee6a4SAndroid Build Coastguard Worker         let k1 = 0xc6c8_f5e0_b13e_ed40;
156*bb4ee6a4SAndroid Build Coastguard Worker         let k2 = 0x1a04_ce4b_8329_14fe;
157*bb4ee6a4SAndroid Build Coastguard Worker         let val = 0xf4e3_c360;
158*bb4ee6a4SAndroid Build Coastguard Worker         assert!(m.insert(k1, k2, val).is_none());
159*bb4ee6a4SAndroid Build Coastguard Worker 
160*bb4ee6a4SAndroid Build Coastguard Worker         let new_k2 = 0x6825_a60b_61ac_b333;
161*bb4ee6a4SAndroid Build Coastguard Worker         let val2 = 0xbb14_8f2c;
162*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
163*bb4ee6a4SAndroid Build Coastguard Worker             m.insert(k1, new_k2, val2)
164*bb4ee6a4SAndroid Build Coastguard Worker                 .expect("failed to update alt key"),
165*bb4ee6a4SAndroid Build Coastguard Worker             val
166*bb4ee6a4SAndroid Build Coastguard Worker         );
167*bb4ee6a4SAndroid Build Coastguard Worker 
168*bb4ee6a4SAndroid Build Coastguard Worker         assert!(m.get_alt(&k2).is_none());
169*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(*m.get(&k1).expect("failed to look up main key"), val2);
170*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
171*bb4ee6a4SAndroid Build Coastguard Worker             *m.get_alt(&new_k2).expect("failed to look up alt key"),
172*bb4ee6a4SAndroid Build Coastguard Worker             val2
173*bb4ee6a4SAndroid Build Coastguard Worker         );
174*bb4ee6a4SAndroid Build Coastguard Worker     }
175*bb4ee6a4SAndroid Build Coastguard Worker 
176*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
update_value()177*bb4ee6a4SAndroid Build Coastguard Worker     fn update_value() {
178*bb4ee6a4SAndroid Build Coastguard Worker         let mut m = MultikeyBTreeMap::<u64, i64, u32>::new();
179*bb4ee6a4SAndroid Build Coastguard Worker 
180*bb4ee6a4SAndroid Build Coastguard Worker         let k1 = 0xc6c8_f5e0_b13e_ed40;
181*bb4ee6a4SAndroid Build Coastguard Worker         let k2 = 0x1a04_ce4b_8329_14fe;
182*bb4ee6a4SAndroid Build Coastguard Worker         let val = 0xf4e3_c360;
183*bb4ee6a4SAndroid Build Coastguard Worker         assert!(m.insert(k1, k2, val).is_none());
184*bb4ee6a4SAndroid Build Coastguard Worker 
185*bb4ee6a4SAndroid Build Coastguard Worker         let val2 = 0xe42d_79ba;
186*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
187*bb4ee6a4SAndroid Build Coastguard Worker             m.insert(k1, k2, val2).expect("failed to update alt key"),
188*bb4ee6a4SAndroid Build Coastguard Worker             val
189*bb4ee6a4SAndroid Build Coastguard Worker         );
190*bb4ee6a4SAndroid Build Coastguard Worker 
191*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(*m.get(&k1).expect("failed to look up main key"), val2);
192*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(*m.get_alt(&k2).expect("failed to look up alt key"), val2);
193*bb4ee6a4SAndroid Build Coastguard Worker     }
194*bb4ee6a4SAndroid Build Coastguard Worker 
195*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
update_both_keys_main()196*bb4ee6a4SAndroid Build Coastguard Worker     fn update_both_keys_main() {
197*bb4ee6a4SAndroid Build Coastguard Worker         let mut m = MultikeyBTreeMap::<u64, i64, u32>::new();
198*bb4ee6a4SAndroid Build Coastguard Worker 
199*bb4ee6a4SAndroid Build Coastguard Worker         let k1 = 0xc6c8_f5e0_b13e_ed40;
200*bb4ee6a4SAndroid Build Coastguard Worker         let k2 = 0x1a04_ce4b_8329_14fe;
201*bb4ee6a4SAndroid Build Coastguard Worker         let val = 0xf4e3_c360;
202*bb4ee6a4SAndroid Build Coastguard Worker         assert!(m.insert(k1, k2, val).is_none());
203*bb4ee6a4SAndroid Build Coastguard Worker 
204*bb4ee6a4SAndroid Build Coastguard Worker         let new_k1 = 0xc980_587a_24b3_ae30;
205*bb4ee6a4SAndroid Build Coastguard Worker         let new_k2 = 0x2773_c5ee_8239_45a2;
206*bb4ee6a4SAndroid Build Coastguard Worker         let val2 = 0x31f4_33f9;
207*bb4ee6a4SAndroid Build Coastguard Worker         assert!(m.insert(new_k1, new_k2, val2).is_none());
208*bb4ee6a4SAndroid Build Coastguard Worker 
209*bb4ee6a4SAndroid Build Coastguard Worker         let val3 = 0x8da1_9cf7;
210*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
211*bb4ee6a4SAndroid Build Coastguard Worker             m.insert(k1, new_k2, val3)
212*bb4ee6a4SAndroid Build Coastguard Worker                 .expect("failed to update main key"),
213*bb4ee6a4SAndroid Build Coastguard Worker             val
214*bb4ee6a4SAndroid Build Coastguard Worker         );
215*bb4ee6a4SAndroid Build Coastguard Worker 
216*bb4ee6a4SAndroid Build Coastguard Worker         // Both new_k1 and k2 should now be gone from the map.
217*bb4ee6a4SAndroid Build Coastguard Worker         assert!(m.get(&new_k1).is_none());
218*bb4ee6a4SAndroid Build Coastguard Worker         assert!(m.get_alt(&k2).is_none());
219*bb4ee6a4SAndroid Build Coastguard Worker 
220*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(*m.get(&k1).expect("failed to look up main key"), val3);
221*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
222*bb4ee6a4SAndroid Build Coastguard Worker             *m.get_alt(&new_k2).expect("failed to look up alt key"),
223*bb4ee6a4SAndroid Build Coastguard Worker             val3
224*bb4ee6a4SAndroid Build Coastguard Worker         );
225*bb4ee6a4SAndroid Build Coastguard Worker     }
226*bb4ee6a4SAndroid Build Coastguard Worker 
227*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
update_both_keys_alt()228*bb4ee6a4SAndroid Build Coastguard Worker     fn update_both_keys_alt() {
229*bb4ee6a4SAndroid Build Coastguard Worker         let mut m = MultikeyBTreeMap::<u64, i64, u32>::new();
230*bb4ee6a4SAndroid Build Coastguard Worker 
231*bb4ee6a4SAndroid Build Coastguard Worker         let k1 = 0xc6c8_f5e0_b13e_ed40;
232*bb4ee6a4SAndroid Build Coastguard Worker         let k2 = 0x1a04_ce4b_8329_14fe;
233*bb4ee6a4SAndroid Build Coastguard Worker         let val = 0xf4e3_c360;
234*bb4ee6a4SAndroid Build Coastguard Worker         assert!(m.insert(k1, k2, val).is_none());
235*bb4ee6a4SAndroid Build Coastguard Worker 
236*bb4ee6a4SAndroid Build Coastguard Worker         let new_k1 = 0xc980_587a_24b3_ae30;
237*bb4ee6a4SAndroid Build Coastguard Worker         let new_k2 = 0x2773_c5ee_8239_45a2;
238*bb4ee6a4SAndroid Build Coastguard Worker         let val2 = 0x31f4_33f9;
239*bb4ee6a4SAndroid Build Coastguard Worker         assert!(m.insert(new_k1, new_k2, val2).is_none());
240*bb4ee6a4SAndroid Build Coastguard Worker 
241*bb4ee6a4SAndroid Build Coastguard Worker         let val3 = 0x8da1_9cf7;
242*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
243*bb4ee6a4SAndroid Build Coastguard Worker             m.insert(new_k1, k2, val3)
244*bb4ee6a4SAndroid Build Coastguard Worker                 .expect("failed to update main key"),
245*bb4ee6a4SAndroid Build Coastguard Worker             val2
246*bb4ee6a4SAndroid Build Coastguard Worker         );
247*bb4ee6a4SAndroid Build Coastguard Worker 
248*bb4ee6a4SAndroid Build Coastguard Worker         // Both k1 and new_k2 should now be gone from the map.
249*bb4ee6a4SAndroid Build Coastguard Worker         assert!(m.get(&k1).is_none());
250*bb4ee6a4SAndroid Build Coastguard Worker         assert!(m.get_alt(&new_k2).is_none());
251*bb4ee6a4SAndroid Build Coastguard Worker 
252*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(*m.get(&new_k1).expect("failed to look up main key"), val3);
253*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(*m.get_alt(&k2).expect("failed to look up alt key"), val3);
254*bb4ee6a4SAndroid Build Coastguard Worker     }
255*bb4ee6a4SAndroid Build Coastguard Worker 
256*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
remove()257*bb4ee6a4SAndroid Build Coastguard Worker     fn remove() {
258*bb4ee6a4SAndroid Build Coastguard Worker         let mut m = MultikeyBTreeMap::<u64, i64, u32>::new();
259*bb4ee6a4SAndroid Build Coastguard Worker 
260*bb4ee6a4SAndroid Build Coastguard Worker         let k1 = 0xc6c8_f5e0_b13e_ed40;
261*bb4ee6a4SAndroid Build Coastguard Worker         let k2 = 0x1a04_ce4b_8329_14fe;
262*bb4ee6a4SAndroid Build Coastguard Worker         let val = 0xf4e3_c360;
263*bb4ee6a4SAndroid Build Coastguard Worker         assert!(m.insert(k1, k2, val).is_none());
264*bb4ee6a4SAndroid Build Coastguard Worker 
265*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(m.remove(&k1).expect("failed to remove entry"), val);
266*bb4ee6a4SAndroid Build Coastguard Worker         assert!(m.get(&k1).is_none());
267*bb4ee6a4SAndroid Build Coastguard Worker         assert!(m.get_alt(&k2).is_none());
268*bb4ee6a4SAndroid Build Coastguard Worker     }
269*bb4ee6a4SAndroid Build Coastguard Worker }
270