1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use super::TQueueLike;
use crate::test_queue_mod;
use crate::{retry, StmResult, TVar};
use std::{any::Any, collections::VecDeque};

#[derive(Clone)]
/// Unbounded queue backed by a single `VecDequeue`.
///
/// The drawback is that reads and writes both touch the same `TVar`.
pub struct TVecDequeue<T> {
    queue: TVar<VecDeque<T>>,
}

impl<T> TVecDequeue<T>
where
    T: Any + Sync + Send + Clone,
{
    /// Create an empty `TVecDequeue`.
    #[allow(dead_code)]
    pub fn new() -> TVecDequeue<T> {
        TVecDequeue {
            queue: TVar::new(VecDeque::new()),
        }
    }
}

impl<T: Any + Send + Sync + Clone> Default for TVecDequeue<T> {
    fn default() -> Self {
        Self::new()
    }
}

impl<T> TQueueLike<T> for TVecDequeue<T>
where
    T: Any + Sync + Send + Clone,
{
    fn write(&self, value: T) -> StmResult<()> {
        let mut queue = self.queue.read_clone()?;
        queue.push_back(value);
        self.queue.write(queue)
    }

    fn read(&self) -> StmResult<T> {
        let mut queue = self.queue.read_clone()?;
        match queue.pop_front() {
            None => retry(),
            Some(value) => {
                self.queue.write(queue)?;
                Ok(value)
            }
        }
    }

    fn is_empty(&self) -> StmResult<bool> {
        self.queue.read().map(|v| v.is_empty())
    }
}

test_queue_mod!(|| { crate::queues::tvecdequeue::TVecDequeue::<i32>::new() });