123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698 |
- #![warn(rust_2018_idioms)]
- use slab::*;
- use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe};
- #[test]
- fn insert_get_remove_one() {
- let mut slab = Slab::new();
- assert!(slab.is_empty());
- let key = slab.insert(10);
- assert_eq!(slab[key], 10);
- assert_eq!(slab.get(key), Some(&10));
- assert!(!slab.is_empty());
- assert!(slab.contains(key));
- assert_eq!(slab.remove(key), 10);
- assert!(!slab.contains(key));
- assert!(slab.get(key).is_none());
- }
- #[test]
- fn insert_get_many() {
- let mut slab = Slab::with_capacity(10);
- for i in 0..10 {
- let key = slab.insert(i + 10);
- assert_eq!(slab[key], i + 10);
- }
- assert_eq!(slab.capacity(), 10);
- // Storing another one grows the slab
- let key = slab.insert(20);
- assert_eq!(slab[key], 20);
- // Capacity grows by 2x
- assert_eq!(slab.capacity(), 20);
- }
- #[test]
- fn insert_get_remove_many() {
- let mut slab = Slab::with_capacity(10);
- let mut keys = vec![];
- for i in 0..10 {
- for j in 0..10 {
- let val = (i * 10) + j;
- let key = slab.insert(val);
- keys.push((key, val));
- assert_eq!(slab[key], val);
- }
- for (key, val) in keys.drain(..) {
- assert_eq!(val, slab.remove(key));
- }
- }
- assert_eq!(10, slab.capacity());
- }
- #[test]
- fn insert_with_vacant_entry() {
- let mut slab = Slab::with_capacity(1);
- let key;
- {
- let entry = slab.vacant_entry();
- key = entry.key();
- entry.insert(123);
- }
- assert_eq!(123, slab[key]);
- }
- #[test]
- fn get_vacant_entry_without_using() {
- let mut slab = Slab::<usize>::with_capacity(1);
- let key = slab.vacant_entry().key();
- assert_eq!(key, slab.vacant_entry().key());
- }
- #[test]
- #[should_panic(expected = "invalid key")]
- fn invalid_get_panics() {
- let slab = Slab::<usize>::with_capacity(1);
- let _ = &slab[0];
- }
- #[test]
- #[should_panic(expected = "invalid key")]
- fn invalid_get_mut_panics() {
- let mut slab = Slab::<usize>::new();
- let _ = &mut slab[0];
- }
- #[test]
- #[should_panic(expected = "invalid key")]
- fn double_remove_panics() {
- let mut slab = Slab::<usize>::with_capacity(1);
- let key = slab.insert(123);
- slab.remove(key);
- slab.remove(key);
- }
- #[test]
- #[should_panic(expected = "invalid key")]
- fn invalid_remove_panics() {
- let mut slab = Slab::<usize>::with_capacity(1);
- slab.remove(0);
- }
- #[test]
- fn slab_get_mut() {
- let mut slab = Slab::new();
- let key = slab.insert(1);
- slab[key] = 2;
- assert_eq!(slab[key], 2);
- *slab.get_mut(key).unwrap() = 3;
- assert_eq!(slab[key], 3);
- }
- #[test]
- fn key_of_tagged() {
- let mut slab = Slab::new();
- slab.insert(0);
- assert_eq!(slab.key_of(&slab[0]), 0);
- }
- #[test]
- fn key_of_layout_optimizable() {
- // Entry<&str> doesn't need a discriminant tag because it can use the
- // nonzero-ness of ptr and store Vacant's next at the same offset as len
- let mut slab = Slab::new();
- slab.insert("foo");
- slab.insert("bar");
- let third = slab.insert("baz");
- slab.insert("quux");
- assert_eq!(slab.key_of(&slab[third]), third);
- }
- #[test]
- fn key_of_zst() {
- let mut slab = Slab::new();
- slab.insert(());
- let second = slab.insert(());
- slab.insert(());
- assert_eq!(slab.key_of(&slab[second]), second);
- }
- #[test]
- fn reserve_does_not_allocate_if_available() {
- let mut slab = Slab::with_capacity(10);
- let mut keys = vec![];
- for i in 0..6 {
- keys.push(slab.insert(i));
- }
- for key in 0..4 {
- slab.remove(key);
- }
- assert!(slab.capacity() - slab.len() == 8);
- slab.reserve(8);
- assert_eq!(10, slab.capacity());
- }
- #[test]
- fn reserve_exact_does_not_allocate_if_available() {
- let mut slab = Slab::with_capacity(10);
- let mut keys = vec![];
- for i in 0..6 {
- keys.push(slab.insert(i));
- }
- for key in 0..4 {
- slab.remove(key);
- }
- assert!(slab.capacity() - slab.len() == 8);
- slab.reserve_exact(8);
- assert_eq!(10, slab.capacity());
- }
- #[test]
- #[should_panic(expected = "capacity overflow")]
- fn reserve_does_panic_with_capacity_overflow() {
- let mut slab = Slab::with_capacity(10);
- slab.insert(true);
- slab.reserve(std::usize::MAX);
- }
- #[test]
- #[should_panic(expected = "capacity overflow")]
- fn reserve_exact_does_panic_with_capacity_overflow() {
- let mut slab = Slab::with_capacity(10);
- slab.insert(true);
- slab.reserve_exact(std::usize::MAX);
- }
- #[test]
- fn retain() {
- let mut slab = Slab::with_capacity(2);
- let key1 = slab.insert(0);
- let key2 = slab.insert(1);
- slab.retain(|key, x| {
- assert_eq!(key, *x);
- *x % 2 == 0
- });
- assert_eq!(slab.len(), 1);
- assert_eq!(slab[key1], 0);
- assert!(!slab.contains(key2));
- // Ensure consistency is retained
- let key = slab.insert(123);
- assert_eq!(key, key2);
- assert_eq!(2, slab.len());
- assert_eq!(2, slab.capacity());
- // Inserting another element grows
- let key = slab.insert(345);
- assert_eq!(key, 2);
- assert_eq!(4, slab.capacity());
- }
- #[test]
- fn into_iter() {
- let mut slab = Slab::new();
- for i in 0..8 {
- slab.insert(i);
- }
- slab.remove(0);
- slab.remove(4);
- slab.remove(5);
- slab.remove(7);
- let vals: Vec<_> = slab
- .into_iter()
- .inspect(|&(key, val)| assert_eq!(key, val))
- .map(|(_, val)| val)
- .collect();
- assert_eq!(vals, vec![1, 2, 3, 6]);
- }
- #[test]
- fn into_iter_rev() {
- let mut slab = Slab::new();
- for i in 0..4 {
- slab.insert(i);
- }
- let mut iter = slab.into_iter();
- assert_eq!(iter.next_back(), Some((3, 3)));
- assert_eq!(iter.next_back(), Some((2, 2)));
- assert_eq!(iter.next(), Some((0, 0)));
- assert_eq!(iter.next_back(), Some((1, 1)));
- assert_eq!(iter.next_back(), None);
- assert_eq!(iter.next(), None);
- }
- #[test]
- fn iter() {
- let mut slab = Slab::new();
- for i in 0..4 {
- slab.insert(i);
- }
- let vals: Vec<_> = slab
- .iter()
- .enumerate()
- .map(|(i, (key, val))| {
- assert_eq!(i, key);
- *val
- })
- .collect();
- assert_eq!(vals, vec![0, 1, 2, 3]);
- slab.remove(1);
- let vals: Vec<_> = slab.iter().map(|(_, r)| *r).collect();
- assert_eq!(vals, vec![0, 2, 3]);
- }
- #[test]
- fn iter_rev() {
- let mut slab = Slab::new();
- for i in 0..4 {
- slab.insert(i);
- }
- slab.remove(0);
- let vals = slab.iter().rev().collect::<Vec<_>>();
- assert_eq!(vals, vec![(3, &3), (2, &2), (1, &1)]);
- }
- #[test]
- fn iter_mut() {
- let mut slab = Slab::new();
- for i in 0..4 {
- slab.insert(i);
- }
- for (i, (key, e)) in slab.iter_mut().enumerate() {
- assert_eq!(i, key);
- *e += 1;
- }
- let vals: Vec<_> = slab.iter().map(|(_, r)| *r).collect();
- assert_eq!(vals, vec![1, 2, 3, 4]);
- slab.remove(2);
- for (_, e) in slab.iter_mut() {
- *e += 1;
- }
- let vals: Vec<_> = slab.iter().map(|(_, r)| *r).collect();
- assert_eq!(vals, vec![2, 3, 5]);
- }
- #[test]
- fn iter_mut_rev() {
- let mut slab = Slab::new();
- for i in 0..4 {
- slab.insert(i);
- }
- slab.remove(2);
- {
- let mut iter = slab.iter_mut();
- assert_eq!(iter.next(), Some((0, &mut 0)));
- let mut prev_key = !0;
- for (key, e) in iter.rev() {
- *e += 10;
- assert!(prev_key > key);
- prev_key = key;
- }
- }
- assert_eq!(slab[0], 0);
- assert_eq!(slab[1], 11);
- assert_eq!(slab[3], 13);
- assert!(!slab.contains(2));
- }
- #[test]
- fn from_iterator_sorted() {
- let mut slab = (0..5).map(|i| (i, i)).collect::<Slab<_>>();
- assert_eq!(slab.len(), 5);
- assert_eq!(slab[0], 0);
- assert_eq!(slab[2], 2);
- assert_eq!(slab[4], 4);
- assert_eq!(slab.vacant_entry().key(), 5);
- }
- #[test]
- fn from_iterator_new_in_order() {
- // all new keys come in increasing order, but existing keys are overwritten
- let mut slab = [(0, 'a'), (1, 'a'), (1, 'b'), (0, 'b'), (9, 'a'), (0, 'c')]
- .iter()
- .cloned()
- .collect::<Slab<_>>();
- assert_eq!(slab.len(), 3);
- assert_eq!(slab[0], 'c');
- assert_eq!(slab[1], 'b');
- assert_eq!(slab[9], 'a');
- assert_eq!(slab.get(5), None);
- assert_eq!(slab.vacant_entry().key(), 8);
- }
- #[test]
- fn from_iterator_unordered() {
- let mut slab = vec![(1, "one"), (50, "fifty"), (3, "three"), (20, "twenty")]
- .into_iter()
- .collect::<Slab<_>>();
- assert_eq!(slab.len(), 4);
- assert_eq!(slab.vacant_entry().key(), 0);
- let mut iter = slab.iter();
- assert_eq!(iter.next(), Some((1, &"one")));
- assert_eq!(iter.next(), Some((3, &"three")));
- assert_eq!(iter.next(), Some((20, &"twenty")));
- assert_eq!(iter.next(), Some((50, &"fifty")));
- assert_eq!(iter.next(), None);
- }
- // https://github.com/tokio-rs/slab/issues/100
- #[test]
- fn from_iterator_issue_100() {
- let mut slab: slab::Slab<()> = vec![(1, ())].into_iter().collect();
- assert_eq!(slab.len(), 1);
- assert_eq!(slab.insert(()), 0);
- assert_eq!(slab.insert(()), 2);
- assert_eq!(slab.insert(()), 3);
- let mut slab: slab::Slab<()> = vec![(1, ()), (2, ())].into_iter().collect();
- assert_eq!(slab.len(), 2);
- assert_eq!(slab.insert(()), 0);
- assert_eq!(slab.insert(()), 3);
- assert_eq!(slab.insert(()), 4);
- let mut slab: slab::Slab<()> = vec![(1, ()), (3, ())].into_iter().collect();
- assert_eq!(slab.len(), 2);
- assert_eq!(slab.insert(()), 2);
- assert_eq!(slab.insert(()), 0);
- assert_eq!(slab.insert(()), 4);
- let mut slab: slab::Slab<()> = vec![(0, ()), (2, ()), (3, ()), (5, ())]
- .into_iter()
- .collect();
- assert_eq!(slab.len(), 4);
- assert_eq!(slab.insert(()), 4);
- assert_eq!(slab.insert(()), 1);
- assert_eq!(slab.insert(()), 6);
- }
- #[test]
- fn clear() {
- let mut slab = Slab::new();
- for i in 0..4 {
- slab.insert(i);
- }
- // clear full
- slab.clear();
- assert!(slab.is_empty());
- assert_eq!(0, slab.len());
- assert_eq!(4, slab.capacity());
- for i in 0..2 {
- slab.insert(i);
- }
- let vals: Vec<_> = slab.iter().map(|(_, r)| *r).collect();
- assert_eq!(vals, vec![0, 1]);
- // clear half-filled
- slab.clear();
- assert!(slab.is_empty());
- }
- #[test]
- fn shrink_to_fit_empty() {
- let mut slab = Slab::<bool>::with_capacity(20);
- slab.shrink_to_fit();
- assert_eq!(slab.capacity(), 0);
- }
- #[test]
- fn shrink_to_fit_no_vacant() {
- let mut slab = Slab::with_capacity(20);
- slab.insert(String::new());
- slab.shrink_to_fit();
- assert!(slab.capacity() < 10);
- }
- #[test]
- fn shrink_to_fit_doesnt_move() {
- let mut slab = Slab::with_capacity(8);
- slab.insert("foo");
- let bar = slab.insert("bar");
- slab.insert("baz");
- let quux = slab.insert("quux");
- slab.remove(quux);
- slab.remove(bar);
- slab.shrink_to_fit();
- assert_eq!(slab.len(), 2);
- assert!(slab.capacity() >= 3);
- assert_eq!(slab.get(0), Some(&"foo"));
- assert_eq!(slab.get(2), Some(&"baz"));
- assert_eq!(slab.vacant_entry().key(), bar);
- }
- #[test]
- fn shrink_to_fit_doesnt_recreate_list_when_nothing_can_be_done() {
- let mut slab = Slab::with_capacity(16);
- for i in 0..4 {
- slab.insert(Box::new(i));
- }
- slab.remove(0);
- slab.remove(2);
- slab.remove(1);
- assert_eq!(slab.vacant_entry().key(), 1);
- slab.shrink_to_fit();
- assert_eq!(slab.len(), 1);
- assert!(slab.capacity() >= 4);
- assert_eq!(slab.vacant_entry().key(), 1);
- }
- #[test]
- fn compact_empty() {
- let mut slab = Slab::new();
- slab.compact(|_, _, _| panic!());
- assert_eq!(slab.len(), 0);
- assert_eq!(slab.capacity(), 0);
- slab.reserve(20);
- slab.compact(|_, _, _| panic!());
- assert_eq!(slab.len(), 0);
- assert_eq!(slab.capacity(), 0);
- slab.insert(0);
- slab.insert(1);
- slab.insert(2);
- slab.remove(1);
- slab.remove(2);
- slab.remove(0);
- slab.compact(|_, _, _| panic!());
- assert_eq!(slab.len(), 0);
- assert_eq!(slab.capacity(), 0);
- }
- #[test]
- fn compact_no_moves_needed() {
- let mut slab = Slab::new();
- for i in 0..10 {
- slab.insert(i);
- }
- slab.remove(8);
- slab.remove(9);
- slab.remove(6);
- slab.remove(7);
- slab.compact(|_, _, _| panic!());
- assert_eq!(slab.len(), 6);
- for ((index, &value), want) in slab.iter().zip(0..6) {
- assert!(index == value);
- assert_eq!(index, want);
- }
- assert!(slab.capacity() >= 6 && slab.capacity() < 10);
- }
- #[test]
- fn compact_moves_successfully() {
- let mut slab = Slab::with_capacity(20);
- for i in 0..10 {
- slab.insert(i);
- }
- for &i in &[0, 5, 9, 6, 3] {
- slab.remove(i);
- }
- let mut moved = 0;
- slab.compact(|&mut v, from, to| {
- assert!(from > to);
- assert!(from >= 5);
- assert!(to < 5);
- assert_eq!(from, v);
- moved += 1;
- true
- });
- assert_eq!(slab.len(), 5);
- assert_eq!(moved, 2);
- assert_eq!(slab.vacant_entry().key(), 5);
- assert!(slab.capacity() >= 5 && slab.capacity() < 20);
- let mut iter = slab.iter();
- assert_eq!(iter.next(), Some((0, &8)));
- assert_eq!(iter.next(), Some((1, &1)));
- assert_eq!(iter.next(), Some((2, &2)));
- assert_eq!(iter.next(), Some((3, &7)));
- assert_eq!(iter.next(), Some((4, &4)));
- assert_eq!(iter.next(), None);
- }
- #[test]
- fn compact_doesnt_move_if_closure_errors() {
- let mut slab = Slab::with_capacity(20);
- for i in 0..10 {
- slab.insert(i);
- }
- for &i in &[9, 3, 1, 4, 0] {
- slab.remove(i);
- }
- slab.compact(|&mut v, from, to| {
- assert!(from > to);
- assert_eq!(from, v);
- v != 6
- });
- assert_eq!(slab.len(), 5);
- assert!(slab.capacity() >= 7 && slab.capacity() < 20);
- assert_eq!(slab.vacant_entry().key(), 3);
- let mut iter = slab.iter();
- assert_eq!(iter.next(), Some((0, &8)));
- assert_eq!(iter.next(), Some((1, &7)));
- assert_eq!(iter.next(), Some((2, &2)));
- assert_eq!(iter.next(), Some((5, &5)));
- assert_eq!(iter.next(), Some((6, &6)));
- assert_eq!(iter.next(), None);
- }
- #[test]
- fn compact_handles_closure_panic() {
- let mut slab = Slab::new();
- for i in 0..10 {
- slab.insert(i);
- }
- for i in 1..6 {
- slab.remove(i);
- }
- let result = catch_unwind(AssertUnwindSafe(|| {
- slab.compact(|&mut v, from, to| {
- assert!(from > to);
- assert_eq!(from, v);
- if v == 7 {
- panic!("test");
- }
- true
- })
- }));
- match result {
- Err(ref payload) if payload.downcast_ref() == Some(&"test") => {}
- Err(bug) => resume_unwind(bug),
- Ok(()) => unreachable!(),
- }
- assert_eq!(slab.len(), 5 - 1);
- assert_eq!(slab.vacant_entry().key(), 3);
- let mut iter = slab.iter();
- assert_eq!(iter.next(), Some((0, &0)));
- assert_eq!(iter.next(), Some((1, &9)));
- assert_eq!(iter.next(), Some((2, &8)));
- assert_eq!(iter.next(), Some((6, &6)));
- assert_eq!(iter.next(), None);
- }
- #[test]
- fn fully_consumed_drain() {
- let mut slab = Slab::new();
- for i in 0..3 {
- slab.insert(i);
- }
- {
- let mut drain = slab.drain();
- assert_eq!(Some(0), drain.next());
- assert_eq!(Some(1), drain.next());
- assert_eq!(Some(2), drain.next());
- assert_eq!(None, drain.next());
- }
- assert!(slab.is_empty());
- }
- #[test]
- fn partially_consumed_drain() {
- let mut slab = Slab::new();
- for i in 0..3 {
- slab.insert(i);
- }
- {
- let mut drain = slab.drain();
- assert_eq!(Some(0), drain.next());
- }
- assert!(slab.is_empty())
- }
- #[test]
- fn drain_rev() {
- let mut slab = Slab::new();
- for i in 0..10 {
- slab.insert(i);
- }
- slab.remove(9);
- let vals: Vec<u64> = slab.drain().rev().collect();
- assert_eq!(vals, (0..9).rev().collect::<Vec<u64>>());
- }
- #[test]
- fn try_remove() {
- let mut slab = Slab::new();
- let key = slab.insert(1);
- assert_eq!(slab.try_remove(key), Some(1));
- assert_eq!(slab.try_remove(key), None);
- assert_eq!(slab.get(key), None);
- }
|