clock_zones/
storage.rs

1//! Different [storage layouts][Layout] for DBMs.
2
3use super::*;
4
5/// Represents a storage layout for [Dbm].
6pub trait Layout<B: Bound> {
7    /// Initializes the storage for `num_variables` clock variables using
8    /// `init` as initial bound for all differences.
9    fn new(num_variables: usize, init: B) -> Self;
10
11    /// Sets the bound for the clock difference `left - right`.
12    fn set(&mut self, left: impl AnyClock, right: impl AnyClock, bound: B);
13
14    /// Retrieves the bound for the clock difference `left - right`.
15    fn get(&self, left: impl AnyClock, right: impl AnyClock) -> &B;
16}
17
18/// A [storage layout](Layout) using a one-dimensional array.
19#[derive(Eq, PartialEq, Hash, Clone, Debug)]
20pub struct LinearLayout<B: Bound> {
21    dimension: usize,
22    bounds: Box<[B]>,
23}
24
25impl<B: Bound> LinearLayout<B> {
26    /// Computes the index where the bound for `left - right` is stored.
27    #[inline(always)]
28    fn index_of(&self, left: impl AnyClock, right: impl AnyClock) -> usize {
29        left.into_index() * self.dimension + right.into_index()
30    }
31}
32
33impl<B: Bound> Layout<B> for LinearLayout<B> {
34    #[inline(always)]
35    fn new(num_variables: usize, default: B) -> Self {
36        let dimension = num_variables + 1;
37        LinearLayout {
38            dimension,
39            bounds: vec![default; dimension * dimension].into(),
40        }
41    }
42
43    #[inline(always)]
44    fn set(&mut self, left: impl AnyClock, right: impl AnyClock, bound: B) {
45        let index = self.index_of(left, right);
46        self.bounds[index] = bound;
47    }
48
49    #[inline(always)]
50    fn get(&self, left: impl AnyClock, right: impl AnyClock) -> &B {
51        &self.bounds[self.index_of(left, right)]
52    }
53}
54
55/// A [storage layout](Layout) using a two-dimensional array.
56#[derive(Eq, PartialEq, Hash, Clone, Debug)]
57#[repr(transparent)]
58pub struct MatrixLayout<B: Bound> {
59    matrix: Box<[Box<[B]>]>,
60}
61
62impl<B: Bound> Layout<B> for MatrixLayout<B> {
63    #[inline(always)]
64    fn new(num_variables: usize, default: B) -> Self {
65        let dimension = num_variables + 1;
66        MatrixLayout {
67            matrix: vec![vec![default; dimension].into(); dimension].into(),
68        }
69    }
70
71    #[inline(always)]
72    fn set(&mut self, left: impl AnyClock, right: impl AnyClock, bound: B) {
73        self.matrix[left.into_index()][right.into_index()] = bound;
74    }
75
76    #[inline(always)]
77    fn get(&self, left: impl AnyClock, right: impl AnyClock) -> &B {
78        &self.matrix[left.into_index()][right.into_index()]
79    }
80}