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