1use std::{
2 fmt::{self},
3 usize,
4};
5
6use super::page::BTreePageID;
7use crate::{
8 field::*,
9 io::{Condensable, Vaporizable},
10};
11
12#[derive(Default)]
13pub struct Tuple {
14 pub scheme: Schema,
15 pub fields: Vec<IntField>,
16}
17
18impl Tuple {
19 pub fn new(scheme: Schema, bytes: &[u8]) -> Tuple {
20 let mut cells: Vec<IntField> = Vec::new();
21 let mut start: usize = 0;
22 let mut end: usize = 0;
23 for field in &scheme.fields {
24 match field.field_type {
25 Type::INT => {
26 end += get_type_length(field.field_type);
27 let cell_bytes = &bytes[start..end];
28
29 let mut bytes_array = [0; 4];
30 for i in 0..4 {
31 bytes_array[i] = cell_bytes[i];
32 }
33 let value = i32::from_be_bytes(bytes_array);
34
35 cells.push(IntField::new(value));
36
37 start = end;
38 }
39 }
40 }
41 Tuple {
42 scheme,
43 fields: cells,
44 }
45 }
46
47 pub fn new_default_tuple(scheme: Schema, _width: usize) -> Tuple {
48 let mut cells: Vec<IntField> = Vec::new();
49 for field in &scheme.fields {
50 match field.field_type {
51 Type::INT => {
52 cells.push(IntField::new(0));
53 }
54 }
55 }
56 Tuple {
57 scheme,
58 fields: cells,
59 }
60 }
61
62 pub fn new_btree_tuple(value: i32, width: usize) -> Tuple {
63 let scheme = small_int_schema(width, "");
64 let _bytes = [0];
65 let mut tuple = Tuple::new_default_tuple(scheme, width);
66 for i in 0..tuple.fields.len() {
67 tuple.set_field(i, IntField::new(value));
68 }
69 tuple
70 }
71
72 pub fn set_field(&mut self, i: usize, c: IntField) {
73 self.fields[i] = c;
74 }
75
76 pub fn get_field(&self, i: usize) -> IntField {
77 self.fields[i]
78 }
79
80 pub fn clone(&self) -> Tuple {
81 Tuple {
82 scheme: self.scheme.clone(),
83 fields: self.fields.to_vec(),
84 }
85 }
86
87 pub fn read_from(
88 reader: &mut crate::io::SmallReader,
89 tuple_scheme: &Schema,
90 ) -> Self {
91 let mut cells: Vec<IntField> = Vec::new();
92 for field in &tuple_scheme.fields {
93 match field.field_type {
94 Type::INT => {
95 cells.push(IntField::read_from(reader));
96 }
97 }
98 }
99 Tuple {
100 scheme: tuple_scheme.clone(),
101 fields: cells,
102 }
103 }
104}
105
106impl Condensable for Tuple {
107 fn to_bytes(&self) -> Vec<u8> {
108 let mut bytes = Vec::new();
109 for cell in &self.fields {
110 let mut cell_bytes = cell.to_bytes();
111 bytes.append(&mut cell_bytes);
112 }
113 bytes
114 }
115}
116
117impl PartialEq for Tuple {
118 fn eq(&self, other: &Self) -> bool {
119 if self.scheme != other.scheme {
120 return false;
121 }
122
123 for (i, field) in self.fields.iter().enumerate() {
124 if field != &other.fields[i] {
125 return false;
126 }
127 }
128
129 return true;
130 }
131}
132
133impl Eq for Tuple {}
134
135impl fmt::Display for Tuple {
136 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
137 let mut content: String = "{".to_owned();
138 for cell in &self.fields {
139 let cell_str = format!("{}, ", cell.value);
140 content.push_str(&cell_str);
141 }
142 content = content[..content.len() - 2].to_string();
143 content.push_str(&"}");
144 write!(f, "{}", content,)
145 }
146}
147
148impl fmt::Debug for Tuple {
149 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
150 write!(f, "{}", self)
151 }
152}
153
154#[derive(PartialEq)]
155pub struct WrappedTuple {
156 internal: Tuple,
157 slot_number: usize,
158 pid: BTreePageID,
159}
160
161impl std::ops::Deref for WrappedTuple {
162 type Target = Tuple;
163 fn deref(&self) -> &Self::Target {
164 &self.internal
165 }
166}
167
168impl std::ops::DerefMut for WrappedTuple {
169 fn deref_mut(&mut self) -> &mut Self::Target {
170 &mut self.internal
171 }
172}
173
174impl WrappedTuple {
175 pub fn new(
176 internal: Tuple,
177 slot_number: usize,
178 pid: BTreePageID,
179 ) -> WrappedTuple {
180 WrappedTuple {
181 internal,
182 slot_number,
183 pid,
184 }
185 }
186
187 pub fn get_slot_number(&self) -> usize {
188 self.slot_number
189 }
190
191 pub fn get_pid(&self) -> BTreePageID {
192 self.pid
193 }
194}
195
196impl Eq for WrappedTuple {}
197
198impl fmt::Display for WrappedTuple {
199 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
200 let mut content: String = "{".to_owned();
201 for cell in &self.fields {
202 let cell_str = format!("{}, ", cell.value);
203 content.push_str(&cell_str);
204 }
205 content = content[..content.len() - 2].to_string();
206 content.push_str(&"}");
207 write!(f, "{}", content,)
208 }
209}
210
211impl fmt::Debug for WrappedTuple {
212 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
213 write!(f, "{}", self)
214 }
215}
216
217#[derive(Debug)]
218pub struct Schema {
219 pub fields: Vec<FieldItem>,
220}
221
222impl PartialEq for Schema {
223 fn eq(&self, other: &Self) -> bool {
224 let matching = self
225 .fields
226 .iter()
227 .zip(&other.fields)
228 .filter(|&(a, b)| a == b)
229 .count();
230 self.fields.len() == matching
231 }
232}
233
234impl Schema {
235 pub fn merge(scheme1: Schema, scheme2: Schema) -> Schema {
236 let mut new_scheme = Schema {
237 ..Default::default()
238 };
239
240 for f in scheme1.fields {
241 new_scheme.fields.push(f);
242 }
243 for f in scheme2.fields {
244 new_scheme.fields.push(f);
245 }
246
247 new_scheme
248 }
249
250 pub fn get_size(&self) -> usize {
252 self.fields.len() * 4
253 }
254}
255
256impl Clone for Schema {
257 fn clone(&self) -> Self {
258 Self {
259 fields: self.fields.to_vec(),
260 }
261 }
262}
263
264impl Default for Schema {
265 fn default() -> Schema {
266 Schema { fields: Vec::new() }
267 }
268}
269
270pub fn small_int_schema(width: usize, name_prefix: &str) -> Schema {
271 let mut fields: Vec<FieldItem> = Vec::new();
272 for i in 0..width {
273 let field = FieldItem {
274 field_name: format!("{}-{}", name_prefix, i),
275 field_type: Type::INT,
276 };
277 fields.push(field);
278 }
279
280 Schema { fields: fields }
281}
282
283#[cfg(test)]
284mod tests {
285 use log::debug;
286
287 use super::*;
288 use crate::utils::init_log;
289
290 #[test]
291 fn test_tuple_clone() {
292 init_log();
293
294 let tuple = Tuple::new_btree_tuple(35, 2);
295 debug!("tuple: {}", tuple);
296 let new_tuple = tuple.clone();
297 debug!("new tuple: {}", new_tuple);
298 }
299}