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