mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-20 23:45:18 +01:00
core: implement exists
This commit is contained in:
@@ -232,20 +232,9 @@ impl BTreeCursor {
|
||||
OwnedValue::Integer(i) => *i as u64,
|
||||
_ => unreachable!("btree tables are indexed by integers!"),
|
||||
};
|
||||
let mut cell_idx = 0;
|
||||
for cell in &page.cells {
|
||||
match cell {
|
||||
BTreeCell::TableLeafCell(cell) => {
|
||||
if int_key <= cell._rowid {
|
||||
break;
|
||||
}
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
cell_idx += 1;
|
||||
}
|
||||
let cell_idx = find_cell(page, int_key);
|
||||
|
||||
// if overwrite drop cell
|
||||
// TODO: if overwrite drop cell
|
||||
|
||||
// insert cell
|
||||
let mut payload: Vec<u8> = Vec::new();
|
||||
@@ -571,7 +560,60 @@ impl Cursor for BTreeCursor {
|
||||
self.null_flag
|
||||
}
|
||||
|
||||
fn exists(&mut self, key: &OwnedValue) -> Result<bool> {
|
||||
Ok(false)
|
||||
fn exists(&mut self, key: &OwnedValue) -> Result<CursorResult<bool>> {
|
||||
let int_key = match key {
|
||||
OwnedValue::Integer(i) => i,
|
||||
_ => unreachable!("btree tables are indexed by integers!"),
|
||||
};
|
||||
match self.move_to(*int_key as u64)? {
|
||||
CursorResult::Ok(_) => {}
|
||||
CursorResult::IO => return Ok(CursorResult::IO),
|
||||
};
|
||||
let mem_page = {
|
||||
let mem_page = self.page.borrow();
|
||||
let mem_page = mem_page.as_ref().unwrap();
|
||||
mem_page.clone()
|
||||
};
|
||||
let page_idx = mem_page.page_idx;
|
||||
let page_ref = self.pager.read_page(page_idx)?;
|
||||
let page = page_ref.borrow();
|
||||
if page.is_locked() {
|
||||
return Ok(CursorResult::IO);
|
||||
}
|
||||
|
||||
let page = page.contents.read().unwrap();
|
||||
let page = page.as_ref().unwrap();
|
||||
|
||||
// find cell
|
||||
let int_key = match key {
|
||||
OwnedValue::Integer(i) => *i as u64,
|
||||
_ => unreachable!("btree tables are indexed by integers!"),
|
||||
};
|
||||
let cell_idx = find_cell(page, int_key);
|
||||
if cell_idx >= page.cells.len() {
|
||||
Ok(CursorResult::Ok(false))
|
||||
} else {
|
||||
let equals = match &page.cells[cell_idx] {
|
||||
BTreeCell::TableLeafCell(l) => l._rowid == int_key,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
Ok(CursorResult::Ok(equals))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_cell(page: &BTreePage, int_key: u64) -> usize {
|
||||
let mut cell_idx = 0;
|
||||
for cell in &page.cells {
|
||||
match cell {
|
||||
BTreeCell::TableLeafCell(cell) => {
|
||||
if int_key <= cell._rowid {
|
||||
break;
|
||||
}
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
cell_idx += 1;
|
||||
}
|
||||
cell_idx
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ impl Cursor for PseudoCursor {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
fn exists(&mut self, key: &OwnedValue) -> Result<bool> {
|
||||
fn exists(&mut self, key: &OwnedValue) -> Result<CursorResult<bool>> {
|
||||
let _ = key;
|
||||
todo!()
|
||||
}
|
||||
|
||||
@@ -334,7 +334,6 @@ pub fn begin_write_btree_page(pager: &Pager, page: &Rc<RefCell<Page>>) -> Result
|
||||
}
|
||||
})
|
||||
};
|
||||
dbg!(buffer.borrow().len());
|
||||
let c = Rc::new(Completion::Write(WriteCompletion::new(write_complete)));
|
||||
page_source.write(page.id, buffer.clone(), c)?;
|
||||
Ok(())
|
||||
|
||||
@@ -371,7 +371,7 @@ pub trait Cursor {
|
||||
fn rowid(&self) -> Result<Option<u64>>;
|
||||
fn record(&self) -> Result<Ref<Option<OwnedRecord>>>;
|
||||
fn insert(&mut self, key: &OwnedValue, record: &OwnedRecord) -> Result<CursorResult<()>>;
|
||||
fn exists(&mut self, key: &OwnedValue) -> Result<bool>;
|
||||
fn exists(&mut self, key: &OwnedValue) -> Result<CursorResult<bool>>;
|
||||
fn set_null_flag(&mut self, flag: bool);
|
||||
fn get_null_flag(&self) -> bool;
|
||||
}
|
||||
|
||||
@@ -1346,10 +1346,11 @@ impl Program {
|
||||
} => {
|
||||
let cursor = cursors.get_mut(cursor).unwrap();
|
||||
match cursor.exists(&state.registers[*rowid_reg])? {
|
||||
true => state.pc += 1,
|
||||
false => state.pc = *target_pc,
|
||||
CursorResult::Ok(true) => state.pc += 1,
|
||||
CursorResult::Ok(false) => state.pc = *target_pc,
|
||||
CursorResult::IO => return Ok(StepResult::IO),
|
||||
};
|
||||
} // TODO(pere): how is not exists implemented? We probably need to traverse keys my pointing cursor.
|
||||
}
|
||||
// this cursor may be reused for next insert
|
||||
// Update: tablemoveto is used to travers on not exists, on insert depending on flags if nonseek it traverses again.
|
||||
// If not there might be some optimizations obviously.
|
||||
|
||||
@@ -95,7 +95,7 @@ impl Cursor for Sorter {
|
||||
todo!();
|
||||
}
|
||||
|
||||
fn exists(&mut self, key: &OwnedValue) -> Result<bool> {
|
||||
fn exists(&mut self, key: &OwnedValue) -> Result<CursorResult<bool>> {
|
||||
let _ = key;
|
||||
todo!()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user