1#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
16pub struct GroupId(usize);
17
18impl GroupId {
19 pub fn new(index: usize) -> Self {
20 Self(index)
21 }
22
23 pub fn index(self) -> usize {
24 self.0
25 }
26}
27
28#[derive(Debug, Clone, PartialEq, Eq)]
29pub struct MemoGroup<E> {
30 expressions: Vec<E>,
31}
32
33impl<E> MemoGroup<E> {
34 pub fn new(expression: E) -> Self {
35 Self {
36 expressions: vec![expression],
37 }
38 }
39
40 pub fn expressions(&self) -> &[E] {
41 &self.expressions
42 }
43
44 pub fn first_expression(&self) -> Option<&E> {
45 self.expressions.first()
46 }
47
48 pub fn expression_count(&self) -> usize {
49 self.expressions.len()
50 }
51
52 pub fn push(&mut self, expression: E) {
53 self.expressions.push(expression);
54 }
55}
56
57#[derive(Debug, Clone, PartialEq, Eq)]
58pub struct Memo<E> {
59 groups: Vec<MemoGroup<E>>,
60}
61
62impl<E> Default for Memo<E> {
63 fn default() -> Self {
64 Self { groups: Vec::new() }
65 }
66}
67
68impl<E> Memo<E> {
69 pub fn insert_group(&mut self, expression: E) -> GroupId {
70 let id = GroupId::new(self.groups.len());
71 self.groups.push(MemoGroup::new(expression));
72 id
73 }
74
75 pub fn group(&self, id: GroupId) -> Option<&MemoGroup<E>> {
76 self.groups.get(id.index())
77 }
78
79 pub fn group_mut(&mut self, id: GroupId) -> Option<&mut MemoGroup<E>> {
80 self.groups.get_mut(id.index())
81 }
82
83 pub fn group_count(&self) -> usize {
84 self.groups.len()
85 }
86
87 pub fn is_empty(&self) -> bool {
88 self.groups.is_empty()
89 }
90
91 pub fn groups(&self) -> &[MemoGroup<E>] {
92 &self.groups
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::Memo;
99
100 #[test]
101 fn memo_interns_group_ids_by_insertion_order() {
102 let mut memo = Memo::default();
103
104 let first = memo.insert_group("scan");
105 let second = memo.insert_group("filter");
106
107 assert_eq!(first.index(), 0);
108 assert_eq!(second.index(), 1);
109 assert_eq!(memo.group_count(), 2);
110 assert!(!memo.is_empty());
111 assert_eq!(memo.group(first).unwrap().expressions(), &["scan"]);
112 assert_eq!(memo.group(first).unwrap().first_expression(), Some(&"scan"));
113 }
114
115 #[test]
116 fn memo_group_can_hold_equivalent_expressions() {
117 let mut memo = Memo::default();
118 let group = memo.insert_group("seq_scan");
119
120 memo.group_mut(group).unwrap().push("index_scan");
121
122 assert_eq!(
123 memo.group(group).unwrap().expressions(),
124 &["seq_scan", "index_scan"]
125 );
126 assert_eq!(memo.group(group).unwrap().expression_count(), 2);
127 }
128}