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
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
use crate::kvs::KeyValueStore;
use crate::task::{Existence, Method, Seconds, Task, TaskResult};
use std::time::Instant;
use std::vec;

#[derive(Debug, Serialize, Deserialize)]
pub struct Workload(Vec<Task>);
impl Workload {
    pub fn len(&self) -> usize {
        self.0.len()
    }

    pub fn is_empty(&self) -> bool {
        self.0.is_empty()
    }
}

#[derive(Debug)]
pub struct WorkloadExecutor<T> {
    kvs: T,
    workload: vec::IntoIter<Task>,
    start_time: Instant,
    seqno: usize,
}
impl<T: KeyValueStore> WorkloadExecutor<T> {
    pub fn new(kvs: T, workload: Workload) -> Self {
        WorkloadExecutor {
            kvs,
            workload: workload.0.into_iter(),
            start_time: Instant::now(),
            seqno: 0,
        }
    }
}
impl<T: KeyValueStore> Iterator for WorkloadExecutor<T> {
    type Item = TaskResult;

    fn next(&mut self) -> Option<Self::Item> {
        let seqno = self.seqno;
        self.seqno += 1;
        match self.workload.next() {
            Some(Task::Put { key, value, .. }) => {
                let value = value.generate();
                let start_time = self.start_time.elapsed();
                let result = self.kvs.put(key.as_ref(), &value);
                let end_time = self.start_time.elapsed();
                let result = TaskResult {
                    seqno,
                    key,
                    method: Method::Put,
                    start_time: Seconds::new(start_time),
                    elapsed: Seconds::new(end_time - start_time),
                    exists: result
                        .as_ref()
                        .ok()
                        .cloned()
                        .unwrap_or_else(Existence::unknown),
                    error: result.err(),
                };
                Some(result)
            }
            Some(Task::Get { key, .. }) => {
                let start_time = self.start_time.elapsed();
                let result = self.kvs.get(key.as_ref());
                let end_time = self.start_time.elapsed();
                let result = TaskResult {
                    seqno,
                    key,
                    method: Method::Get,
                    start_time: Seconds::new(start_time),
                    elapsed: Seconds::new(end_time - start_time),
                    exists: result
                        .as_ref()
                        .ok()
                        .map(|v| Existence::new(v.is_some()))
                        .unwrap_or_else(Existence::unknown),
                    error: result.err(),
                };
                Some(result)
            }
            Some(Task::Delete { key, .. }) => {
                let start_time = self.start_time.elapsed();
                let result = self.kvs.delete(key.as_ref());
                let end_time = self.start_time.elapsed();
                let result = TaskResult {
                    seqno,
                    key,
                    method: Method::Delete,
                    start_time: Seconds::new(start_time),
                    elapsed: Seconds::new(end_time - start_time),
                    exists: result
                        .as_ref()
                        .ok()
                        .cloned()
                        .unwrap_or_else(Existence::unknown),
                    error: result.err(),
                };
                Some(result)
            }
            None => None,
        }
    }
}