Skip to content

Commit f931d8e

Browse files
Merge pull request #38 from JakeRoggenbuck/fix-main
Add tail and base containers
2 parents 89f2d56 + 0e15122 commit f931d8e

File tree

2 files changed

+260
-0
lines changed

2 files changed

+260
-0
lines changed

src/container.rs

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
use pyo3::prelude::*;
2+
use std::collections::HashMap;
3+
use std::sync::{Arc, Mutex};
4+
5+
use super::page::PhysicalPage;
6+
7+
pub struct BaseContainer {
8+
// pages
9+
pub physical_pages: Vec<Arc<Mutex<PhysicalPage>>>,
10+
11+
// number of additional columns
12+
pub num_cols: u64,
13+
14+
// reserved columns
15+
pub RID_COLUMN: u64,
16+
pub SCHEMA_ENCODING_COLUMN: u64,
17+
pub INDIRECTION_COLUMN: u64,
18+
}
19+
20+
/// A container that manages physical pages for storing data in columns
21+
///
22+
/// The `BaseContainer` maintains a collection of physical pages where each page represents
23+
/// a column of data. It reserves the first three columns for special purposes:
24+
///
25+
/// - RID_COLUMN (0): Record IDs
26+
/// - SCHEMA_ENCODING_COLUMN (1): Schema encoding information
27+
/// - INDIRECTION_COLUMN (2): Indirection records
28+
///
29+
/// # Fields
30+
///
31+
/// - `physical_pages`: A vector of physical pages
32+
/// - `num_cols`: The number of additional columns
33+
/// - `RID_COLUMN`: The index of the RID column
34+
/// - `SCHEMA_ENCODING_COLUMN`: The index of the schema encoding column
35+
/// - `INDIRECTION_COLUMN`: The index of the indirection column
36+
impl BaseContainer {
37+
38+
/// Creates a new `BaseContainer` with the specified number of columns
39+
///
40+
/// # Arguments
41+
///
42+
/// - `num_cols`: The number of additional columns
43+
///
44+
/// # Returns
45+
///
46+
/// A new `BaseContainer` instance
47+
pub fn new(num_cols: u64) -> Self {
48+
BaseContainer {
49+
physical_pages: Vec::new(),
50+
num_cols,
51+
RID_COLUMN: 0,
52+
SCHEMA_ENCODING_COLUMN: 1,
53+
INDIRECTION_COLUMN: 2,
54+
}
55+
}
56+
57+
/// Initializes the container by creating physical pages for each column
58+
///
59+
/// The `initialize` method creates physical pages for each column in the container.
60+
/// It reserves the first three columns for special purposes and initializes the rest
61+
/// of the columns with empty pages.
62+
///
63+
/// # Example
64+
///
65+
/// ```
66+
/// let mut container = BaseContainer::new(5);
67+
/// container.initialize();
68+
/// ```
69+
///
70+
pub fn initialize(&mut self) {
71+
// 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();
75+
76+
self.physical_pages.push(Arc::new(Mutex::new(rid_page)));
77+
self.physical_pages.push(Arc::new(Mutex::new(schema_encoding_page)));
78+
self.physical_pages.push(Arc::new(Mutex::new(indirection_page)));
79+
80+
// initialize the rest of the columns
81+
for _ in 0..self.num_cols {
82+
let mut new_page = PhysicalPage::new();
83+
self.physical_pages.push(Arc::new(Mutex::new(new_page)));
84+
}
85+
}
86+
87+
/// Returns a reference to the RID column page
88+
pub fn rid_page(&self) -> Arc<Mutex<PhysicalPage>> {
89+
self.physical_pages[self.RID_COLUMN as usize].clone()
90+
}
91+
92+
/// Returns a reference to the schema encoding column page
93+
pub fn schema_encoding_page(&self) -> Arc<Mutex<PhysicalPage>> {
94+
self.physical_pages[self.SCHEMA_ENCODING_COLUMN as usize].clone()
95+
}
96+
97+
/// Returns a reference to the indirection column page
98+
pub fn indirection_page(&self) -> Arc<Mutex<PhysicalPage>> {
99+
self.physical_pages[self.INDIRECTION_COLUMN as usize].clone()
100+
}
101+
102+
/// Returns a reference to the specified column page
103+
pub fn column_page(&self, col_idx: u64) -> Arc<Mutex<PhysicalPage>> {
104+
self.physical_pages[(col_idx + 3) as usize].clone()
105+
}
106+
}
107+
108+
pub struct TailContainer {
109+
// pages
110+
pub physical_pages: Vec<Arc<Mutex<PhysicalPage>>>,
111+
112+
// number of additional columns
113+
pub num_cols: u64,
114+
115+
// reserved columns
116+
pub RID_COLUMN: u64,
117+
pub SCHEMA_ENCODING_COLUMN: u64,
118+
pub INDIRECTION_COLUMN: u64,
119+
}
120+
121+
/// A container that manages physical pages for storing data in columns
122+
///
123+
/// The `TailContainer` maintains a collection of physical pages where each page represents
124+
/// a column of data. It reserves the first three columns for special purposes:
125+
///
126+
/// - RID_COLUMN (0): Record IDs
127+
/// - SCHEMA_ENCODING_COLUMN (1): Schema encoding information
128+
/// - INDIRECTION_COLUMN (2): Indirection records
129+
///
130+
/// # Fields
131+
///
132+
/// - `physical_pages`: A vector of physical pages
133+
/// - `num_cols`: The number of additional columns
134+
/// - `RID_COLUMN`: The index of the RID column
135+
/// - `SCHEMA_ENCODING_COLUMN`: The index of the schema encoding column
136+
/// - `INDIRECTION_COLUMN`: The index of the indirection column
137+
impl TailContainer {
138+
139+
/// Creates a new `TailContainer` with the specified number of columns
140+
///
141+
/// # Arguments
142+
///
143+
/// - `num_cols`: The number of additional columns
144+
///
145+
/// # Returns
146+
///
147+
/// A new `TailContainer` instance
148+
pub fn new(num_cols: u64) -> Self {
149+
TailContainer {
150+
physical_pages: Vec::new(),
151+
num_cols,
152+
RID_COLUMN: 0,
153+
SCHEMA_ENCODING_COLUMN: 1,
154+
INDIRECTION_COLUMN: 2,
155+
}
156+
}
157+
158+
/// Initializes the container by creating physical pages for each column
159+
///
160+
/// The `initialize` method creates physical pages for each column in the container.
161+
/// It reserves the first three columns for special purposes and initializes the rest
162+
/// of the columns with empty pages.
163+
///
164+
/// # Example
165+
///
166+
/// ```
167+
/// let mut container = TailContainer::new(5);
168+
/// container.initialize();
169+
/// ```
170+
pub fn initialize(&mut self) {
171+
// initialize the three reserved columns
172+
let mut rid_page = PhysicalPage::new();
173+
let mut schema_encoding_page = PhysicalPage::new();
174+
let mut indirection_page = PhysicalPage::new();
175+
176+
self.physical_pages.push(Arc::new(Mutex::new(rid_page)));
177+
self.physical_pages.push(Arc::new(Mutex::new(schema_encoding_page)));
178+
self.physical_pages.push(Arc::new(Mutex::new(indirection_page)));
179+
180+
// initialize the rest of the columns
181+
for _ in 0..self.num_cols {
182+
let mut new_page = PhysicalPage::new();
183+
self.physical_pages.push(Arc::new(Mutex::new(new_page)));
184+
}
185+
186+
}
187+
188+
/// Returns a reference to the RID column page
189+
pub fn rid_page(&self) -> Arc<Mutex<PhysicalPage>> {
190+
self.physical_pages[self.RID_COLUMN as usize].clone()
191+
}
192+
193+
/// Returns a reference to the schema encoding column page
194+
pub fn schema_encoding_page(&self) -> Arc<Mutex<PhysicalPage>> {
195+
self.physical_pages[self.SCHEMA_ENCODING_COLUMN as usize].clone()
196+
}
197+
198+
/// Returns a reference to the indirection column page
199+
pub fn indirection_page(&self) -> Arc<Mutex<PhysicalPage>> {
200+
self.physical_pages[self.INDIRECTION_COLUMN as usize].clone()
201+
}
202+
203+
/// Returns a reference to the specified column page
204+
pub fn column_page(&self, col_idx: u64) -> Arc<Mutex<PhysicalPage>> {
205+
self.physical_pages[(col_idx + 3) as usize].clone()
206+
}
207+
208+
}
209+
210+
#[cfg(test)]
211+
mod tests {
212+
use super::*;
213+
214+
#[test]
215+
fn test_base_container_creation() {
216+
let container = BaseContainer::new(5);
217+
assert_eq!(container.num_cols, 5);
218+
assert_eq!(container.RID_COLUMN, 0);
219+
assert_eq!(container.SCHEMA_ENCODING_COLUMN, 1);
220+
assert_eq!(container.INDIRECTION_COLUMN, 2);
221+
assert!(container.physical_pages.is_empty());
222+
}
223+
224+
#[test]
225+
fn test_base_container_initialization() {
226+
let mut container = BaseContainer::new(5);
227+
container.initialize();
228+
assert_eq!(container.physical_pages.len(), 8); // 3 reserved + 5 data columns
229+
}
230+
231+
#[test]
232+
fn test_tail_container_creation() {
233+
let container = TailContainer::new(5);
234+
assert_eq!(container.num_cols, 5);
235+
assert_eq!(container.RID_COLUMN, 0);
236+
assert_eq!(container.SCHEMA_ENCODING_COLUMN, 1);
237+
assert_eq!(container.INDIRECTION_COLUMN, 2);
238+
assert!(container.physical_pages.is_empty());
239+
}
240+
241+
#[test]
242+
fn test_tail_container_initialization() {
243+
let mut container = TailContainer::new(5);
244+
container.initialize();
245+
assert_eq!(container.physical_pages.len(), 8); // 3 reserved + 5 data columns
246+
}
247+
248+
#[test]
249+
fn test_container_page_getters() {
250+
let mut container = BaseContainer::new(2);
251+
container.initialize();
252+
253+
assert!(Arc::ptr_eq(&container.rid_page(), &container.physical_pages[0]));
254+
assert!(Arc::ptr_eq(&container.schema_encoding_page(), &container.physical_pages[1]));
255+
assert!(Arc::ptr_eq(&container.indirection_page(), &container.physical_pages[2]));
256+
assert!(Arc::ptr_eq(&container.column_page(0), &container.physical_pages[3]));
257+
assert!(Arc::ptr_eq(&container.column_page(1), &container.physical_pages[4]));
258+
}
259+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub mod index;
77
pub mod page;
88
pub mod query;
99
pub mod system;
10+
mod container;
1011

1112
/// Blazingly fast hello
1213
#[pyfunction]

0 commit comments

Comments
 (0)