pfds/
queue.rs

1//
2// Copyright 2021-Present (c) Raja Lehtihet & Wael El Oraiby
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are met:
6//
7// 1. Redistributions of source code must retain the above copyright notice,
8// this list of conditions and the following disclaimer.
9//
10// 2. Redistributions in binary form must reproduce the above copyright notice,
11// this list of conditions and the following disclaimer in the documentation
12// and/or other materials provided with the distribution.
13//
14// 3. Neither the name of the copyright holder nor the names of its contributors
15// may be used to endorse or promote products derived from this software without
16// specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28// POSSIBILITY OF SUCH DAMAGE.
29//
30use std::sync::Arc;
31use std::marker::PhantomData;
32
33use crate::list::*;
34
35enum QueueNode<E: Clone> {
36    Empty,
37    Node { back: L<E>, front: L<E> },
38}
39
40use QueueNode::*;
41
42type N<E> = Arc<QueueNode<E>>;
43type L<E> = List<E>;
44
45fn empty<E: Clone>() -> N<E> {
46    Arc::new(Empty)
47}
48fn node<E: Clone>(back: L<E>, front: L<E>) -> N<E> {
49    match (back.len(), front.len()) {
50        (0, 0) => empty(),
51        _ => Arc::new(Node { back, front }),
52    }
53}
54
55fn enqueue<E: Clone>(q: &N<E>, e: E) -> N<E> {
56    match q.as_ref() {
57        Empty => node(L::empty().push(e), L::empty()),
58        Node { back: b, front: f } => node(b.push(e), f.clone()),
59    }
60}
61
62fn dequeue<E: Clone>(q: &N<E>) -> (E, N<E>) {
63    match q.as_ref() {
64        Empty => panic!("queue is empty"),
65        Node { back: b, front: f } => match (b.len(), f.len()) {
66            (0, 0) => unreachable!("node() invariant violated: Node should never have both lists empty"),
67            (_, 0) => {
68                let l = b.rev();
69                let p = l.pop();
70                (l.top().clone(), node(L::empty(), p))
71            }
72            (_, _) => {
73                let p = f.pop();
74                (f.top().clone(), node(b.clone(), p))
75            }
76        },
77    }
78}
79
80fn len<E: Clone>(q: &N<E>) -> usize {
81    match q.as_ref() {
82        Empty => 0,
83        Node { back: b, front: f } => b.len() + f.len(),
84    }
85}
86
87fn to_vec<E: Clone>(l: &N<E>) -> Vec<E> {
88    let mut v = Vec::new();
89    let mut n = l.clone();
90    loop {
91        match n.as_ref() {
92            Empty => return v,
93            _ => {
94                let (e, nn) = dequeue(&n);
95                v.push(e.clone());
96                n = nn;
97            }
98        }
99    }
100}
101
102/// A persistent (immutable) FIFO queue data structure.
103/// 
104/// `Queue` is implemented using two lists (front and back) to achieve
105/// amortized O(1) enqueue and dequeue operations. All operations return
106/// a new queue, leaving the original unchanged.
107/// 
108/// # Performance
109/// 
110/// - `enqueue`: O(1)
111/// - `dequeue`: O(1) amortized, O(n) worst case when reversing back list
112/// - `is_empty`: O(1)
113/// - `len`: O(1) - length is cached
114/// - `to_vec`: O(n)
115#[derive(Clone)]
116pub struct Queue<E: Clone> {
117    n: N<E>,
118}
119
120impl<E: Clone> Queue<E> {
121    /// Creates a new empty queue.
122    /// 
123    /// # Examples
124    /// 
125    /// ```
126    /// use pfds::Queue;
127    /// 
128    /// let queue: Queue<i32> = Queue::empty();
129    /// assert!(queue.is_empty());
130    /// assert_eq!(queue.len(), 0);
131    /// ```
132    pub fn empty() -> Self {
133        Self { n: empty() }
134    }
135
136    /// Creates a new queue with the given element added to the back.
137    /// 
138    /// This operation is O(1) and shares structure with the original queue.
139    /// 
140    /// # Arguments
141    /// 
142    /// * `e` - The element to add to the back of the queue
143    /// 
144    /// # Examples
145    /// 
146    /// ```
147    /// use pfds::Queue;
148    /// 
149    /// let queue = Queue::empty().enqueue(1).enqueue(2).enqueue(3);
150    /// assert_eq!(queue.len(), 3);
151    /// ```
152    pub fn enqueue(&self, e: E) -> Self {
153        Self {
154            n: enqueue(&self.n, e),
155        }
156    }
157
158    /// Removes and returns the front element and a new queue without that element.
159    /// 
160    /// This operation is O(1) amortized. When the front list is empty,
161    /// it reverses the back list which takes O(n) time.
162    /// 
163    /// # Returns
164    /// 
165    /// A tuple containing:
166    /// - The front element
167    /// - A new queue without the front element
168    /// 
169    /// # Panics
170    /// 
171    /// Panics if the queue is empty.
172    /// 
173    /// # Examples
174    /// 
175    /// ```
176    /// use pfds::Queue;
177    /// 
178    /// let queue = Queue::empty().enqueue(1).enqueue(2);
179    /// let (first, queue2) = queue.dequeue();
180    /// assert_eq!(first, 1);
181    /// assert_eq!(queue.len(), 2);  // Original unchanged
182    /// assert_eq!(queue2.len(), 1);
183    /// ```
184    pub fn dequeue(&self) -> (E, Self) {
185        let (e, n) = dequeue(&self.n);
186        (e, Self { n })
187    }
188
189    /// Returns true if the queue is empty.
190    /// 
191    /// This operation is O(1).
192    /// 
193    /// # Examples
194    /// 
195    /// ```
196    /// use pfds::Queue;
197    /// 
198    /// let empty = Queue::<i32>::empty();
199    /// assert!(empty.is_empty());
200    /// 
201    /// let non_empty = empty.enqueue(1);
202    /// assert!(!non_empty.is_empty());
203    /// ```
204    pub fn is_empty(&self) -> bool {
205        len(&self.n) == 0
206    }
207
208    /// Returns the number of elements in the queue.
209    /// 
210    /// This operation is O(1) as the length is cached.
211    /// 
212    /// # Examples
213    /// 
214    /// ```
215    /// use pfds::Queue;
216    /// 
217    /// let queue = Queue::empty().enqueue(1).enqueue(2).enqueue(3);
218    /// assert_eq!(queue.len(), 3);
219    /// ```
220    pub fn len(&self) -> usize {
221        len(&self.n)
222    }
223
224    /// Converts the queue to a vector.
225    /// 
226    /// Elements are returned in FIFO order (oldest elements first).
227    /// This operation is O(n).
228    /// 
229    /// # Examples
230    /// 
231    /// ```
232    /// use pfds::Queue;
233    /// 
234    /// let queue = Queue::empty().enqueue(1).enqueue(2).enqueue(3);
235    /// let vec = queue.to_vec();
236    /// assert_eq!(vec, vec![1, 2, 3]); // FIFO order
237    /// ```
238    pub fn to_vec(&self) -> Vec<E> {
239        to_vec(&self.n)
240    }
241
242    /// Returns an iterator over the queue elements.
243    /// 
244    /// The iterator yields elements in FIFO order (oldest first).
245    /// 
246    /// # Examples
247    /// 
248    /// ```
249    /// use pfds::Queue;
250    /// 
251    /// let queue = Queue::empty().enqueue(1).enqueue(2).enqueue(3);
252    /// let collected: Vec<_> = queue.iter().collect();
253    /// assert_eq!(collected, vec![1, 2, 3]);
254    /// ```
255    pub fn iter(&self) -> QueueIter<E> {
256        QueueIter {
257            queue: self.n.clone(),
258            _phantom: PhantomData::default(),
259        }
260    }
261}
262
263/// An iterator over the elements of a `Queue`.
264/// 
265/// This struct is created by the [`Queue::iter`] method.
266/// The iterator yields elements in FIFO order.
267pub struct QueueIter<'a, E: Clone> {
268    queue: N<E>,
269    _phantom: PhantomData<&'a E>,
270}
271
272impl<'a, E: Clone> std::iter::Iterator for QueueIter<'a, E> {
273    type Item = E;
274
275    fn next(&mut self) -> Option<Self::Item> {
276        match self.queue.as_ref() {
277            Empty => None,
278            _ => {
279                let (elem, new_queue) = dequeue(&self.queue);
280                self.queue = new_queue;
281                Some(elem)
282            }
283        }
284    }
285}
286
287#[cfg(test)]
288mod tests {
289    use crate::queue::*;
290
291    static mut SEED: i64 = 777;
292
293    fn rand() -> i32 {
294        unsafe {
295            SEED = SEED.wrapping_mul(1664525).wrapping_add(1013904223);
296            (SEED >> 24) as i32
297        }
298    }
299
300    #[test]
301    fn enqueue() {
302        let mut elements = Vec::new();
303        let mut l = Queue::empty();
304        for _ in 0..1000 {
305            let e = rand();
306            elements.push(e);
307            l = l.enqueue(e);
308        }
309
310        assert_eq!(elements.len(), 1000);
311        assert_eq!(elements.len(), l.len());
312
313        let queue_elems = l.to_vec();
314        for i in 0..1000 {
315            assert_eq!(queue_elems[i], elements[i]);
316        }
317    }
318
319    #[test]
320    fn dequeue() {
321        let mut elements = Vec::new();
322        let mut l = Queue::empty();
323        for _ in 0..100000 {
324            let e = rand();
325            elements.push(e);
326            l = l.enqueue(e);
327        }
328
329        assert_eq!(elements.len(), 100000);
330        assert_eq!(elements.len(), l.len());
331
332        let list_elems = l.to_vec();
333        for i in 0..100000 {
334            assert_eq!(list_elems[i], elements[i]);
335        }
336
337        for i in 0..50000 {
338            let (e, n) = l.dequeue();
339            let e2 = elements[i];
340            assert_eq!(e, e2);
341            l = n;
342        }
343
344        assert_eq!(l.len(), 50000);
345
346        let queue_elems = l.to_vec();
347        for i in 0..50000 {
348            assert_eq!(queue_elems[i], elements[i + 50000]);
349        }
350    }
351
352    #[test]
353    fn iter() {
354        let mut elements = Vec::new();
355        let mut q = Queue::empty();
356        for _ in 0..1000 {
357            let e = rand();
358            elements.push(e);
359            q = q.enqueue(e);
360        }
361
362        assert_eq!(elements.len(), 1000);
363        assert_eq!(elements.len(), q.len());
364
365        // Test iterator yields elements in FIFO order
366        let mut count = 0;
367        for elem in q.iter() {
368            assert_eq!(elem, elements[count]);
369            count += 1;
370        }
371        assert_eq!(count, 1000);
372
373        // Test that we can iterate multiple times (persistent data structure)
374        let collected: Vec<i32> = q.iter().collect();
375        assert_eq!(collected, elements);
376    }
377}