1use std::{collections::BTreeMap, fmt, sync::Arc};
2
3use crate::{
4 Expr, NumberBinaryOp, NumberReductionOp, NumberUnaryOp, PromotionRule, Symbol, Test, Value,
5 ValueNumberBinaryOp, ValueNumberReductionOp, ValueNumberUnaryOp, ValuePromotionRule,
6};
7
8#[derive(Clone, Debug, PartialEq, Eq)]
15pub struct CatalogRow {
16 pub table: Symbol,
18 pub key: Symbol,
20 pub epoch: u64,
22 pub data: BTreeMap<Symbol, Expr>,
24 pub(crate) live: BTreeMap<Symbol, CatalogLiveCell>,
25}
26
27impl CatalogRow {
28 pub fn new(table: Symbol, key: Symbol) -> Self {
30 Self {
31 table,
32 key,
33 epoch: 0,
34 data: BTreeMap::new(),
35 live: BTreeMap::new(),
36 }
37 }
38
39 pub fn with_data(mut self, field: Symbol, value: Expr) -> Self {
41 self.data.insert(field, value);
42 self
43 }
44
45 pub fn insert_live_value(&mut self, field: Symbol, value: Value) {
47 self.live.insert(field, CatalogLiveCell::Value(value));
48 }
49
50 pub fn live_value(&self, field: &Symbol) -> Option<&Value> {
52 match self.live.get(field) {
53 Some(CatalogLiveCell::Value(value)) => Some(value),
54 _ => None,
55 }
56 }
57
58 pub fn insert_live_test(&mut self, field: Symbol, test: Arc<dyn Test>) {
60 self.live.insert(field, CatalogLiveCell::Test(test));
61 }
62
63 pub fn live_test(&self, field: &Symbol) -> Option<&Arc<dyn Test>> {
65 match self.live.get(field) {
66 Some(CatalogLiveCell::Test(test)) => Some(test),
67 _ => None,
68 }
69 }
70
71 pub fn insert_live_number_unary_op(&mut self, field: Symbol, op: NumberUnaryOp) {
73 self.live.insert(field, CatalogLiveCell::NumberUnaryOp(op));
74 }
75
76 pub fn insert_live_number_reduction_op(&mut self, field: Symbol, op: NumberReductionOp) {
78 self.live
79 .insert(field, CatalogLiveCell::NumberReductionOp(op));
80 }
81
82 pub fn insert_live_number_binary_op(&mut self, field: Symbol, op: NumberBinaryOp) {
84 self.live.insert(field, CatalogLiveCell::NumberBinaryOp(op));
85 }
86
87 pub fn insert_live_value_number_unary_op(&mut self, field: Symbol, op: ValueNumberUnaryOp) {
89 self.live
90 .insert(field, CatalogLiveCell::ValueNumberUnaryOp(op));
91 }
92
93 pub fn insert_live_value_number_reduction_op(
95 &mut self,
96 field: Symbol,
97 op: ValueNumberReductionOp,
98 ) {
99 self.live
100 .insert(field, CatalogLiveCell::ValueNumberReductionOp(op));
101 }
102
103 pub fn insert_live_value_number_binary_op(&mut self, field: Symbol, op: ValueNumberBinaryOp) {
105 self.live
106 .insert(field, CatalogLiveCell::ValueNumberBinaryOp(op));
107 }
108
109 pub fn insert_live_promotion_rule(&mut self, field: Symbol, rule: PromotionRule) {
111 self.live
112 .insert(field, CatalogLiveCell::PromotionRule(rule));
113 }
114
115 pub fn insert_live_value_promotion_rule(&mut self, field: Symbol, rule: ValuePromotionRule) {
117 self.live
118 .insert(field, CatalogLiveCell::ValuePromotionRule(rule));
119 }
120
121 pub(crate) fn has_field(&self, field: &Symbol) -> bool {
122 self.data.contains_key(field) || self.live.contains_key(field)
123 }
124
125 pub(crate) fn set_epoch(&mut self, epoch: u64) {
126 self.epoch = epoch;
127 }
128}
129
130#[derive(Clone)]
131pub(crate) enum CatalogLiveCell {
132 Value(Value),
133 Test(Arc<dyn Test>),
134 NumberUnaryOp(NumberUnaryOp),
135 NumberReductionOp(NumberReductionOp),
136 NumberBinaryOp(NumberBinaryOp),
137 ValueNumberUnaryOp(ValueNumberUnaryOp),
138 ValueNumberReductionOp(ValueNumberReductionOp),
139 ValueNumberBinaryOp(ValueNumberBinaryOp),
140 PromotionRule(PromotionRule),
141 ValuePromotionRule(ValuePromotionRule),
142}
143
144impl fmt::Debug for CatalogLiveCell {
145 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
146 match self {
147 Self::Value(value) => f.debug_tuple("Value").field(value).finish(),
148 Self::Test(_) => f.write_str("Test(..)"),
149 Self::NumberUnaryOp(_) => f.write_str("NumberUnaryOp(..)"),
150 Self::NumberReductionOp(_) => f.write_str("NumberReductionOp(..)"),
151 Self::NumberBinaryOp(_) => f.write_str("NumberBinaryOp(..)"),
152 Self::ValueNumberUnaryOp(_) => f.write_str("ValueNumberUnaryOp(..)"),
153 Self::ValueNumberReductionOp(_) => f.write_str("ValueNumberReductionOp(..)"),
154 Self::ValueNumberBinaryOp(_) => f.write_str("ValueNumberBinaryOp(..)"),
155 Self::PromotionRule(_) => f.write_str("PromotionRule(..)"),
156 Self::ValuePromotionRule(_) => f.write_str("ValuePromotionRule(..)"),
157 }
158 }
159}
160
161impl PartialEq for CatalogLiveCell {
162 fn eq(&self, other: &Self) -> bool {
163 match (self, other) {
164 (Self::Value(left), Self::Value(right)) => left == right,
165 (Self::Test(left), Self::Test(right)) => Arc::ptr_eq(left, right),
166 (Self::NumberUnaryOp(left), Self::NumberUnaryOp(right)) => {
167 number_unary_op_eq(left, right)
168 }
169 (Self::NumberReductionOp(left), Self::NumberReductionOp(right)) => {
170 number_reduction_op_eq(left, right)
171 }
172 (Self::NumberBinaryOp(left), Self::NumberBinaryOp(right)) => {
173 number_binary_op_eq(left, right)
174 }
175 (Self::ValueNumberUnaryOp(left), Self::ValueNumberUnaryOp(right)) => {
176 value_number_unary_op_eq(left, right)
177 }
178 (Self::ValueNumberReductionOp(left), Self::ValueNumberReductionOp(right)) => {
179 value_number_reduction_op_eq(left, right)
180 }
181 (Self::ValueNumberBinaryOp(left), Self::ValueNumberBinaryOp(right)) => {
182 value_number_binary_op_eq(left, right)
183 }
184 (Self::PromotionRule(left), Self::PromotionRule(right)) => {
185 promotion_rule_eq(left, right)
186 }
187 (Self::ValuePromotionRule(left), Self::ValuePromotionRule(right)) => {
188 value_promotion_rule_eq(left, right)
189 }
190 _ => false,
191 }
192 }
193}
194
195impl Eq for CatalogLiveCell {}
196
197fn number_unary_op_eq(left: &NumberUnaryOp, right: &NumberUnaryOp) -> bool {
198 left.operator == right.operator
199 && left.operand_domain == right.operand_domain
200 && left.cost == right.cost
201}
202
203fn number_reduction_op_eq(left: &NumberReductionOp, right: &NumberReductionOp) -> bool {
204 left.operator == right.operator
205 && left.operand_domain == right.operand_domain
206 && left.cost == right.cost
207}
208
209fn number_binary_op_eq(left: &NumberBinaryOp, right: &NumberBinaryOp) -> bool {
210 left.operator == right.operator
211 && left.left_domain == right.left_domain
212 && left.right_domain == right.right_domain
213 && left.cost == right.cost
214}
215
216fn value_number_unary_op_eq(left: &ValueNumberUnaryOp, right: &ValueNumberUnaryOp) -> bool {
217 left.operator == right.operator
218 && left.operand_domain == right.operand_domain
219 && left.cost == right.cost
220}
221
222fn value_number_reduction_op_eq(
223 left: &ValueNumberReductionOp,
224 right: &ValueNumberReductionOp,
225) -> bool {
226 left.operator == right.operator
227 && left.operand_domain == right.operand_domain
228 && left.cost == right.cost
229}
230
231fn value_number_binary_op_eq(left: &ValueNumberBinaryOp, right: &ValueNumberBinaryOp) -> bool {
232 left.operator == right.operator
233 && left.left_domain == right.left_domain
234 && left.right_domain == right.right_domain
235 && left.cost == right.cost
236}
237
238fn promotion_rule_eq(left: &PromotionRule, right: &PromotionRule) -> bool {
239 left.from_domain == right.from_domain
240 && left.to_domain == right.to_domain
241 && left.cost == right.cost
242}
243
244fn value_promotion_rule_eq(left: &ValuePromotionRule, right: &ValuePromotionRule) -> bool {
245 left.from_domain == right.from_domain
246 && left.to_domain == right.to_domain
247 && left.cost == right.cost
248}