Skip to content

Commit bb48ff5

Browse files
Implement index from BTreeMap
1 parent 1a10a8c commit bb48ff5

File tree

2 files changed

+43
-105
lines changed

2 files changed

+43
-105
lines changed

src/database.rs

Lines changed: 38 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -5,105 +5,25 @@ use std::collections::BTreeMap;
55
use std::collections::HashMap;
66
use std::sync::{Arc, Mutex};
77

8-
/* A data strucutre holding indices for various columns of a table.
9-
Key column should be indexd by default, other columns can be indexed through this object.
10-
Indices are usually B-Trees, but other data structures can be used as well. */
11-
128
#[pyclass]
139
#[derive(Clone)]
1410
pub struct RIndex {
15-
/* EXPLANATION OF BTree, NOT TOO SURE ABOUT THIS.
16-
17-
A vector of BTreeMaps, can be either Some::BTreeMap or None as its elements.
18-
19-
BTreeMap<i64, Vec<[usize; 3]>>:
20-
-- BTreeMap: A balanced binary search tree (B-Tree), for maintaining sorted key-value pairs. --
21-
22-
Map primary key to RID
23-
*/
24-
indices: Vec<Option<BTreeMap<u64, Vec<u64>>>>,
11+
index: BTreeMap<u64, u64>,
2512
}
2613

2714
impl RIndex {
28-
// Mandatory: One index for each table. All our empty initially.
29-
pub fn new(primary_key_column: u64, num_columns: usize) -> RIndex {
30-
let mut indices = vec![None; num_columns]; // table.columns.len()
31-
indices[primary_key_column as usize] = Some(BTreeMap::new());
32-
RIndex { indices }
33-
}
34-
35-
/// Returns the location of all records with the given value on column "column"
36-
pub fn locate(&self, column: usize, value: u64) -> Option<&Vec<u64>> {
37-
if let Some(tree) = &self.indices[column] {
38-
return tree.get(&value);
15+
pub fn new() -> RIndex {
16+
RIndex {
17+
index: BTreeMap::new(),
3918
}
40-
None
4119
}
4220

43-
/// Returns the RIDs of all records with values in column "column" between "begin" and "end"
44-
pub fn locate_range(&self, begin: u64, end: u64, column: usize) -> Vec<u64> {
45-
if let Some(tree) = &self.indices[column] {
46-
// Gets all entries where the key is between begin and end
47-
let keys = tree.range(begin..=end);
48-
49-
let all_records: Vec<u64> = keys.flat_map(|(_, rids)| rids.clone()).collect();
50-
return all_records;
51-
}
52-
Vec::new()
21+
pub fn add(&mut self, primary_key: u64, rid: u64) {
22+
self.index.insert(primary_key, rid);
5323
}
5424

55-
/// Create index on specific column
56-
pub fn create_index(&mut self, column: usize) {
57-
// Create BTree for column
58-
if self.indices[column].is_none() {
59-
self.indices[column] = Some(BTreeMap::new());
60-
// Populate new index with existing records
61-
62-
// let table = self.table.lock().unwrap();
63-
// for rid in table.page_directory.keys() {
64-
// let row = table.fetch_row(*rid);
65-
// let value = row[column];
66-
67-
// // Add RID to index
68-
// self.update_index(value, [*rid as usize, column, 0], column).unwrap();
69-
// }
70-
}
71-
}
72-
73-
/// Insert or update index for a specific column
74-
pub fn update_index(&mut self, key: u64, rid: u64, column: usize) -> Result<(), String> {
75-
if column >= self.indices.len() {
76-
return Err(format!("Column {} does not exist'", column));
77-
}
78-
// Gets column Some::BTreeMap, creates one if None
79-
let tree = self.indices[column].get_or_insert_with(BTreeMap::new);
80-
81-
// Insert or update key
82-
// Searches for the given key in the BTree, If the key exists, it returns a mutable reference to the corresponding value,
83-
// If the key does not exist, it creates a new entry in the BTree for the key, If the key does not exist, this initializes an empty vector (Vec::new) as the value for the key.
84-
// Appends the provided RID to the vector associated with the key
85-
tree.entry(key).or_insert_with(Vec::new).push(rid);
86-
Ok(())
87-
}
88-
89-
pub fn delete_from_index(&mut self, column: usize, key: u64, rid: u64) {
90-
if let Some(tree) = &mut self.indices[column] {
91-
if let Some(rids) = tree.get_mut(&key) {
92-
// Find the position of the RID to remove
93-
if let Some(pos) = rids.iter().position(|&p| p == rid) {
94-
rids.remove(pos);
95-
}
96-
// If no more RID's exist for this key, remove the key
97-
if rids.is_empty() {
98-
tree.remove(&key);
99-
}
100-
}
101-
}
102-
}
103-
104-
/// Drop index of specific column
105-
pub fn drop_index(&mut self, column: usize) {
106-
self.indices[column] = None;
25+
pub fn get(&self, primary_key: u64) -> Option<&u64> {
26+
self.index.get(&primary_key)
10727
}
10828
}
10929

@@ -201,28 +121,45 @@ impl RTable {
201121
return rec;
202122
}
203123

204-
pub fn read(&self, rid: u64) -> Option<Vec<u64>> {
205-
let rec = self.page_directory.get(&rid);
124+
pub fn read(&self, primary_key: u64) -> Option<Vec<u64>> {
125+
// Lookup RID from primary_key
126+
let rid = self.index.get(primary_key);
127+
128+
if let Some(r) = rid {
129+
let rec = self.page_directory.get(&r);
206130

207-
// If the rec exists in the page_directory, return the read values
208-
match rec {
209-
Some(r) => self.page_range.read(r.clone()),
210-
None => None,
131+
// If the rec exists in the page_directory, return the read values
132+
match rec {
133+
Some(r) => return self.page_range.read(r.clone()),
134+
None => return None,
135+
}
211136
}
137+
138+
None
212139
}
213140

214-
pub fn delete(&mut self, rid: u64) {
215-
self.page_directory.remove(&rid);
141+
pub fn delete(&mut self, primary_key: u64) {
142+
// Lookup RID from primary_key
143+
let rid = self.index.get(primary_key);
144+
145+
if let Some(r) = rid {
146+
self.page_directory.remove(&r);
147+
}
216148
}
217149

218-
pub fn sum(&mut self, start: u64, end: u64, col_index: u64) -> i64 {
150+
pub fn sum(&mut self, start_primary_key: u64, end_primary_key: u64, col_index: u64) -> i64 {
219151
let mut agg = 0i64;
220152

221153
// Make sum range inclusive
222154
// TODO: Validate this assumption if it should actually be inclusive
223-
for rid in start..end + 1 {
224-
if let Some(v) = self.read(rid) {
225-
agg += v[col_index as usize] as i64;
155+
for primary_key in start_primary_key..end_primary_key + 1 {
156+
// Lookup RID from primary_key
157+
let rid = self.index.get(primary_key);
158+
159+
if let Some(r) = rid {
160+
if let Some(v) = self.read(*r) {
161+
agg += v[col_index as usize] as i64;
162+
}
226163
}
227164
}
228165

@@ -267,7 +204,7 @@ impl RDatabase {
267204
page_directory: HashMap::new(),
268205
num_columns: num_columns as usize,
269206
num_records: 0,
270-
index: RIndex::new(primary_key_column, num_columns as usize),
207+
index: RIndex::new(),
271208
};
272209

273210
let i = self.tables.len();

src/query.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,20 @@ impl RQuery {
2323

2424
fn select(
2525
&mut self,
26-
search_key: i64,
26+
primary_key: i64,
2727
_search_key_index: i64,
2828
_projected_columns_index: Vec<i64>,
2929
) -> Option<Vec<u64>> {
30-
self.table.read(search_key as u64)
30+
self.table.read(primary_key as u64)
3131
}
3232

3333
fn select_version(&mut self) {}
3434

3535
fn update(&mut self) {}
3636

37-
fn sum(&mut self, start: u64, end: u64, col_index: u64) -> i64 {
38-
self.table.sum(start, end, col_index)
37+
fn sum(&mut self, start_primary_key: u64, end_primary_key: u64, col_index: u64) -> i64 {
38+
self.table
39+
.sum(start_primary_key, end_primary_key, col_index)
3940
}
4041

4142
fn sum_version(&mut self) {}

0 commit comments

Comments
 (0)