use idr_ebr::{Config, EbrGuard, Idr, Key}; #[test] fn smoke() { let idr: Idr<_> = Idr::default(); assert_eq!(idr.iter(&EbrGuard::new()).count(), 0); // Insert values. let mut keys = (0..100) .map(|i| (idr.insert(i).unwrap(), i)) .collect::>(); // Check that the values are accessible. for (key, value) in &keys { assert_eq!(&*idr.get(*key, &EbrGuard::new()).unwrap(), value); } check_iter(&idr, keys.clone()); // Remove every other key. for (key, value) in &keys { if value % 2 == 0 { assert!(idr.remove(*key)); } } // Check that remaining values are accessible. keys.retain(|(key, value)| { let guard = EbrGuard::new(); let actual = idr.get(*key, &guard); if value % 2 == 0 { assert!(actual.is_none()); false } else { assert_eq!(actual.unwrap(), *value); true } }); check_iter(&idr, keys); fn check_iter(idr: &Idr, mut expected: Vec<(Key, i32)>) { let mut actual = idr .iter(&EbrGuard::new()) .map(|(key, entry)| (key, *entry)) .collect::>(); actual.sort(); expected.sort(); assert_eq!(actual, expected); } } #[test] fn extension() { struct TinyConfig; impl Config for TinyConfig { const INITIAL_PAGE_SIZE: u32 = 4; const MAX_PAGES: u32 = 5; const RESERVED_BITS: u32 = 32; } let idr: Idr<_, TinyConfig> = Idr::new(); assert_pages(&idr, 0); for expected_pages in 1..=TinyConfig::MAX_PAGES { let capacity = ((1 << (expected_pages - 1)) - 1) * TinyConfig::INITIAL_PAGE_SIZE; for i in 0..(2 << expected_pages) { idr.insert(capacity + i).unwrap(); } assert_pages(&idr, expected_pages); let len = idr .iter(&EbrGuard::new()) .enumerate() .inspect(|(i, (_, value))| assert_eq!(*value, u32::try_from(*i).unwrap())) .count(); assert_eq!( u32::try_from(len).unwrap(), capacity + (2 << expected_pages) ); } assert!(idr.insert(42).is_none()); fn assert_pages(idr: impl std::fmt::Debug, expected: u32) { assert!(format!("{idr:?}").contains(&format!("allocated_pages: {expected}"))); } } #[test] fn reuse() { struct TinyConfig; impl Config for TinyConfig { const INITIAL_PAGE_SIZE: u32 = 4; const MAX_PAGES: u32 = 29; const RESERVED_BITS: u32 = 32; } assert!(format!("{:?}", TinyConfig::debug()).contains("GENERATION_BITS: 1")); let idr: Idr<_, TinyConfig> = Idr::new(); let key = idr.insert(0).unwrap(); assert!(idr.remove(key)); let key2 = idr.insert(1).unwrap(); assert!(!idr.contains(key)); assert!(idr.remove(key2)); let key3 = idr.insert(2).unwrap(); assert_eq!(key3, key); assert_eq!(idr.get(key, &EbrGuard::new()).unwrap(), 2); assert!(idr.remove(key)); assert!(!idr.contains(key3)); } #[test] fn invalid_key() { let idr = Idr::::default(); let invalid_key = Key::try_from(1).unwrap(); // Shouldn't panic. idr.get(invalid_key, &EbrGuard::new()); } #[test] fn to_owned() { let idr = Idr::::default(); let key = idr.insert(42).unwrap(); let guard = EbrGuard::new(); let entry = idr.get(key, &guard).unwrap(); assert!(entry.to_owned().is_some()); assert!(idr.remove(key)); assert!(entry.to_owned().is_none()); }