@@ -3,6 +3,7 @@ use std::collections::HashMap;
33use std:: sync:: { Arc , Mutex } ;
44
55use super :: page:: PhysicalPage ;
6+ use super :: database:: { Record , RecordAddress } ;
67
78#[ derive( Clone ) ]
89pub 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}
0 commit comments