Skip to content

Commit fa45b52

Browse files
committed
feat: insert record
1 parent 31dbd85 commit fa45b52

File tree

4 files changed

+183
-50
lines changed

4 files changed

+183
-50
lines changed

src/container.rs

Lines changed: 173 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::collections::HashMap;
33
use std::sync::{Arc, Mutex};
44

55
use super::page::PhysicalPage;
6+
use super::database::{Record, RecordAddress};
67

78
#[derive(Clone)]
89
pub struct BaseContainer {
@@ -69,9 +70,9 @@ impl BaseContainer {
6970
///
7071
pub fn initialize(&mut self) {
7172
// initialize the three reserved columns
72-
let mut rid_page = PhysicalPage::new();
73-
let mut schema_encoding_page = PhysicalPage::new();
74-
let mut indirection_page = PhysicalPage::new();
73+
let rid_page = PhysicalPage::new();
74+
let schema_encoding_page = PhysicalPage::new();
75+
let indirection_page = PhysicalPage::new();
7576

7677
self.physical_pages.push(Arc::new(Mutex::new(rid_page)));
7778
self.physical_pages
@@ -81,7 +82,7 @@ impl BaseContainer {
8182

8283
// initialize the rest of the columns
8384
for _ in 0..self.num_cols {
84-
let mut new_page = PhysicalPage::new();
85+
let new_page = PhysicalPage::new();
8586
self.physical_pages.push(Arc::new(Mutex::new(new_page)));
8687
}
8788
}
@@ -102,9 +103,71 @@ impl BaseContainer {
102103
}
103104

104105
/// Returns a reference to the specified column page
106+
///
107+
/// ### Arguments
108+
///
109+
/// - `col_idx`: The index of the column
105110
pub fn column_page(&self, col_idx: u64) -> Arc<Mutex<PhysicalPage>> {
106111
self.physical_pages[(col_idx + 3) as usize].clone()
107112
}
113+
114+
pub fn insert_record(&mut self, rid: u64, values: Vec<u64>) -> Record {
115+
if values.len() != self.num_cols as usize {
116+
panic!("Number of values does not match number of columns");
117+
}
118+
119+
let rid_page = self.rid_page();
120+
let mut rp = rid_page.lock().unwrap();
121+
122+
rp.write(rid);
123+
124+
let schema_encoding_page = self.schema_encoding_page();
125+
let mut sep = schema_encoding_page.lock().unwrap();
126+
sep.write(0);
127+
128+
let indirection_page = self.indirection_page();
129+
let mut ip = indirection_page.lock().unwrap();
130+
131+
ip.write(rid);
132+
133+
for i in 0..self.num_cols {
134+
let col_page = self.column_page(i);
135+
let mut col_page = col_page.lock().unwrap();
136+
col_page.write(values[i as usize]);
137+
}
138+
139+
let addresses: Arc<Mutex<Vec<RecordAddress>>> = Arc::new(Mutex::new(Vec::new()));
140+
let mut a = addresses.lock().unwrap();
141+
142+
a.push(RecordAddress {
143+
page: rid_page.clone(),
144+
offset: rp.num_records - 1,
145+
});
146+
147+
a.push(RecordAddress {
148+
page: schema_encoding_page.clone(),
149+
offset: sep.num_records - 1,
150+
});
151+
152+
a.push(RecordAddress {
153+
page: indirection_page.clone(),
154+
offset: ip.num_records - 1,
155+
});
156+
157+
for i in 0..self.num_cols {
158+
let col_page = self.column_page(i);
159+
let cp = col_page.lock().unwrap();
160+
a.push(RecordAddress {
161+
page: col_page.clone(),
162+
offset: cp.num_records - 1,
163+
});
164+
}
165+
166+
Record {
167+
rid,
168+
addresses: addresses.clone(),
169+
}
170+
}
108171
}
109172

110173
#[derive(Clone)]
@@ -171,9 +234,9 @@ impl TailContainer {
171234
/// ```
172235
pub fn initialize(&mut self) {
173236
// initialize the three reserved columns
174-
let mut rid_page = PhysicalPage::new();
175-
let mut schema_encoding_page = PhysicalPage::new();
176-
let mut indirection_page = PhysicalPage::new();
237+
let rid_page = PhysicalPage::new();
238+
let schema_encoding_page = PhysicalPage::new();
239+
let indirection_page = PhysicalPage::new();
177240

178241
self.physical_pages.push(Arc::new(Mutex::new(rid_page)));
179242
self.physical_pages
@@ -183,7 +246,7 @@ impl TailContainer {
183246

184247
// initialize the rest of the columns
185248
for _ in 0..self.num_cols {
186-
let mut new_page = PhysicalPage::new();
249+
let new_page = PhysicalPage::new();
187250
self.physical_pages.push(Arc::new(Mutex::new(new_page)));
188251
}
189252
}
@@ -207,6 +270,64 @@ impl TailContainer {
207270
pub fn column_page(&self, col_idx: u64) -> Arc<Mutex<PhysicalPage>> {
208271
self.physical_pages[(col_idx + 3) as usize].clone()
209272
}
273+
274+
pub fn insert_record(&mut self, rid: u64, values: Vec<u64>) -> Record {
275+
if values.len() != self.num_cols as usize {
276+
panic!("Number of values does not match number of columns");
277+
}
278+
279+
let rid_page = self.rid_page();
280+
let mut rp = rid_page.lock().unwrap();
281+
282+
rp.write(rid);
283+
284+
let schema_encoding_page = self.schema_encoding_page();
285+
let mut sep = schema_encoding_page.lock().unwrap();
286+
sep.write(0);
287+
288+
let indirection_page = self.indirection_page();
289+
let mut ip = indirection_page.lock().unwrap();
290+
291+
ip.write(rid);
292+
293+
for i in 0..self.num_cols {
294+
let col_page = self.column_page(i);
295+
let mut col_page = col_page.lock().unwrap();
296+
col_page.write(values[i as usize]);
297+
}
298+
299+
let addresses: Arc<Mutex<Vec<RecordAddress>>> = Arc::new(Mutex::new(Vec::new()));
300+
let mut a = addresses.lock().unwrap();
301+
302+
a.push(RecordAddress {
303+
page: rid_page.clone(),
304+
offset: rp.num_records - 1,
305+
});
306+
307+
a.push(RecordAddress {
308+
page: schema_encoding_page.clone(),
309+
offset: sep.num_records - 1,
310+
});
311+
312+
a.push(RecordAddress {
313+
page: indirection_page.clone(),
314+
offset: ip.num_records - 1,
315+
});
316+
317+
for i in 0..self.num_cols {
318+
let col_page = self.column_page(i);
319+
let cp = col_page.lock().unwrap();
320+
a.push(RecordAddress {
321+
page: col_page.clone(),
322+
offset: cp.num_records - 1,
323+
});
324+
}
325+
326+
Record {
327+
rid,
328+
addresses: addresses.clone(),
329+
}
330+
}
210331
}
211332

212333
#[cfg(test)]
@@ -217,60 +338,71 @@ mod tests {
217338
fn test_base_container_creation() {
218339
let container = BaseContainer::new(5);
219340
assert_eq!(container.num_cols, 5);
220-
assert_eq!(container.RID_COLUMN, 0);
221-
assert_eq!(container.SCHEMA_ENCODING_COLUMN, 1);
222-
assert_eq!(container.INDIRECTION_COLUMN, 2);
223-
assert!(container.physical_pages.is_empty());
341+
assert_eq!(container.physical_pages.len(), 0);
224342
}
225343

226344
#[test]
227-
fn test_base_container_initialization() {
228-
let mut container = BaseContainer::new(5);
345+
fn test_base_container_initialize() {
346+
let mut container = BaseContainer::new(5);
229347
container.initialize();
230348
assert_eq!(container.physical_pages.len(), 8); // 3 reserved + 5 data columns
231349
}
232350

351+
#[test]
352+
fn test_base_container_insert() {
353+
let mut container = BaseContainer::new(2);
354+
container.initialize();
355+
356+
let values = vec![42, 43];
357+
let record = container.insert_record(1, values);
358+
359+
assert_eq!(record.rid, 1);
360+
let addresses = record.addresses.lock().unwrap();
361+
assert_eq!(addresses.len(), 5); // 3 reserved + 2 data columns
362+
}
363+
364+
#[test]
365+
#[should_panic(expected = "Number of values does not match number of columns")]
366+
fn test_base_container_insert_wrong_columns() {
367+
let mut container = BaseContainer::new(2);
368+
container.initialize();
369+
let values = vec![42];
370+
container.insert_record(1, values);
371+
}
372+
233373
#[test]
234374
fn test_tail_container_creation() {
235375
let container = TailContainer::new(5);
236376
assert_eq!(container.num_cols, 5);
237-
assert_eq!(container.RID_COLUMN, 0);
238-
assert_eq!(container.SCHEMA_ENCODING_COLUMN, 1);
239-
assert_eq!(container.INDIRECTION_COLUMN, 2);
240-
assert!(container.physical_pages.is_empty());
377+
assert_eq!(container.physical_pages.len(), 0);
241378
}
242379

243380
#[test]
244-
fn test_tail_container_initialization() {
381+
fn test_tail_container_initialize() {
245382
let mut container = TailContainer::new(5);
246383
container.initialize();
247384
assert_eq!(container.physical_pages.len(), 8); // 3 reserved + 5 data columns
248385
}
249386

250387
#[test]
251-
fn test_container_page_getters() {
252-
let mut container = BaseContainer::new(2);
388+
fn test_tail_container_insert() {
389+
let mut container = TailContainer::new(2);
253390
container.initialize();
391+
392+
let values = vec![42, 43];
393+
let record = container.insert_record(1, values);
394+
395+
assert_eq!(record.rid, 1);
396+
let addresses = record.addresses.lock().unwrap();
397+
assert_eq!(addresses.len(), 5); // 3 reserved + 2 data columns
398+
}
254399

255-
assert!(Arc::ptr_eq(
256-
&container.rid_page(),
257-
&container.physical_pages[0]
258-
));
259-
assert!(Arc::ptr_eq(
260-
&container.schema_encoding_page(),
261-
&container.physical_pages[1]
262-
));
263-
assert!(Arc::ptr_eq(
264-
&container.indirection_page(),
265-
&container.physical_pages[2]
266-
));
267-
assert!(Arc::ptr_eq(
268-
&container.column_page(0),
269-
&container.physical_pages[3]
270-
));
271-
assert!(Arc::ptr_eq(
272-
&container.column_page(1),
273-
&container.physical_pages[4]
274-
));
400+
#[test]
401+
#[should_panic(expected = "Number of values does not match number of columns")]
402+
fn test_tail_container_insert_wrong_columns() {
403+
let mut container = TailContainer::new(2);
404+
container.initialize();
405+
let values = vec![42];
406+
container.insert_record(1, values);
275407
}
276408
}

src/database.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,14 @@ impl PageRange {
4545
}
4646
}
4747

48-
struct RecordAddress<'a> {
49-
page: &'a PhysicalPage,
50-
offset: u64,
48+
pub struct RecordAddress {
49+
pub page: Arc<Mutex<PhysicalPage>>,
50+
pub offset: u64,
5151
}
5252

53-
struct Record<'a> {
54-
rid: u64,
55-
addresses: Vec<&'a RecordAddress<'a>>,
53+
pub struct Record {
54+
pub rid: u64,
55+
pub addresses: Arc<Mutex<Vec<RecordAddress>>>,
5656
}
5757

5858
#[derive(Debug)]

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use database::{RDatabase, RTable};
22
use pyo3::prelude::*;
33
use query::Query;
44

5-
mod container;
5+
pub mod container;
66
pub mod database;
77
pub mod index;
88
pub mod page;

src/page.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ use pyo3::prelude::*;
33
static MAX_SIZE_RECORD: u64 = 512;
44

55
#[pyclass]
6+
#[derive(Clone)]
67
pub struct PhysicalPage {
7-
data: [u64; 512],
8-
num_records: u64,
8+
pub data: [u64; 512],
9+
pub num_records: u64,
910
}
1011

1112
impl PhysicalPage {

0 commit comments

Comments
 (0)