1c67d6573Sopenharmony_ciuse std::fmt; 2c67d6573Sopenharmony_ciuse std::ops::Deref; 3c67d6573Sopenharmony_ciuse std::slice; 4c67d6573Sopenharmony_ci 5c67d6573Sopenharmony_ci/// A sparse set used for representing ordered NFA states. 6c67d6573Sopenharmony_ci/// 7c67d6573Sopenharmony_ci/// This supports constant time addition and membership testing. Clearing an 8c67d6573Sopenharmony_ci/// entire set can also be done in constant time. Iteration yields elements 9c67d6573Sopenharmony_ci/// in the order in which they were inserted. 10c67d6573Sopenharmony_ci/// 11c67d6573Sopenharmony_ci/// The data structure is based on: https://research.swtch.com/sparse 12c67d6573Sopenharmony_ci/// Note though that we don't actually use uninitialized memory. We generally 13c67d6573Sopenharmony_ci/// reuse allocations, so the initial allocation cost is bareable. However, 14c67d6573Sopenharmony_ci/// its other properties listed above are extremely useful. 15c67d6573Sopenharmony_ci#[derive(Clone)] 16c67d6573Sopenharmony_cipub struct SparseSet { 17c67d6573Sopenharmony_ci /// Dense contains the instruction pointers in the order in which they 18c67d6573Sopenharmony_ci /// were inserted. 19c67d6573Sopenharmony_ci dense: Vec<usize>, 20c67d6573Sopenharmony_ci /// Sparse maps instruction pointers to their location in dense. 21c67d6573Sopenharmony_ci /// 22c67d6573Sopenharmony_ci /// An instruction pointer is in the set if and only if 23c67d6573Sopenharmony_ci /// sparse[ip] < dense.len() && ip == dense[sparse[ip]]. 24c67d6573Sopenharmony_ci sparse: Box<[usize]>, 25c67d6573Sopenharmony_ci} 26c67d6573Sopenharmony_ci 27c67d6573Sopenharmony_ciimpl SparseSet { 28c67d6573Sopenharmony_ci pub fn new(size: usize) -> SparseSet { 29c67d6573Sopenharmony_ci SparseSet { 30c67d6573Sopenharmony_ci dense: Vec::with_capacity(size), 31c67d6573Sopenharmony_ci sparse: vec![0; size].into_boxed_slice(), 32c67d6573Sopenharmony_ci } 33c67d6573Sopenharmony_ci } 34c67d6573Sopenharmony_ci 35c67d6573Sopenharmony_ci pub fn len(&self) -> usize { 36c67d6573Sopenharmony_ci self.dense.len() 37c67d6573Sopenharmony_ci } 38c67d6573Sopenharmony_ci 39c67d6573Sopenharmony_ci pub fn is_empty(&self) -> bool { 40c67d6573Sopenharmony_ci self.dense.is_empty() 41c67d6573Sopenharmony_ci } 42c67d6573Sopenharmony_ci 43c67d6573Sopenharmony_ci pub fn capacity(&self) -> usize { 44c67d6573Sopenharmony_ci self.dense.capacity() 45c67d6573Sopenharmony_ci } 46c67d6573Sopenharmony_ci 47c67d6573Sopenharmony_ci pub fn insert(&mut self, value: usize) { 48c67d6573Sopenharmony_ci let i = self.len(); 49c67d6573Sopenharmony_ci assert!(i < self.capacity()); 50c67d6573Sopenharmony_ci self.dense.push(value); 51c67d6573Sopenharmony_ci self.sparse[value] = i; 52c67d6573Sopenharmony_ci } 53c67d6573Sopenharmony_ci 54c67d6573Sopenharmony_ci pub fn contains(&self, value: usize) -> bool { 55c67d6573Sopenharmony_ci let i = self.sparse[value]; 56c67d6573Sopenharmony_ci self.dense.get(i) == Some(&value) 57c67d6573Sopenharmony_ci } 58c67d6573Sopenharmony_ci 59c67d6573Sopenharmony_ci pub fn clear(&mut self) { 60c67d6573Sopenharmony_ci self.dense.clear(); 61c67d6573Sopenharmony_ci } 62c67d6573Sopenharmony_ci} 63c67d6573Sopenharmony_ci 64c67d6573Sopenharmony_ciimpl fmt::Debug for SparseSet { 65c67d6573Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 66c67d6573Sopenharmony_ci write!(f, "SparseSet({:?})", self.dense) 67c67d6573Sopenharmony_ci } 68c67d6573Sopenharmony_ci} 69c67d6573Sopenharmony_ci 70c67d6573Sopenharmony_ciimpl Deref for SparseSet { 71c67d6573Sopenharmony_ci type Target = [usize]; 72c67d6573Sopenharmony_ci 73c67d6573Sopenharmony_ci fn deref(&self) -> &Self::Target { 74c67d6573Sopenharmony_ci &self.dense 75c67d6573Sopenharmony_ci } 76c67d6573Sopenharmony_ci} 77c67d6573Sopenharmony_ci 78c67d6573Sopenharmony_ciimpl<'a> IntoIterator for &'a SparseSet { 79c67d6573Sopenharmony_ci type Item = &'a usize; 80c67d6573Sopenharmony_ci type IntoIter = slice::Iter<'a, usize>; 81c67d6573Sopenharmony_ci fn into_iter(self) -> Self::IntoIter { 82c67d6573Sopenharmony_ci self.iter() 83c67d6573Sopenharmony_ci } 84c67d6573Sopenharmony_ci} 85