small_db/btree/
tuple.rs

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    /// get tuple size in bytes
251    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}