mirror of
https://github.com/aljazceru/turso.git
synced 2026-01-04 08:54:20 +01:00
Merge 'Fix btree balance and seek after overwritten cell overflows' from Jussi Saurio
Closes #1809 Closes #1810 Closes #1811 Closes #1812 Closes #1813 Closes #1814 Closes #1815 and probably Closes #1805 Reviewed-by: Pere Diaz Bou <pere-altea@homail.com> Closes #1816
This commit is contained in:
@@ -2128,12 +2128,21 @@ impl BTreeCursor {
|
||||
match cell {
|
||||
BTreeCell::TableLeafCell(tbl_leaf) => {
|
||||
if tbl_leaf._rowid == bkey.to_rowid() {
|
||||
tracing::debug!("found exact match with cell_idx={cell_idx}, overwriting");
|
||||
tracing::debug!("TableLeafCell: found exact match with cell_idx={cell_idx}, overwriting");
|
||||
self.overwrite_cell(page.clone(), cell_idx, record)?;
|
||||
self.state
|
||||
let write_info = self
|
||||
.state
|
||||
.mut_write_info()
|
||||
.expect("expected write info")
|
||||
.state = WriteState::Finish;
|
||||
.expect("expected write info");
|
||||
if page.get().get_contents().overflow_cells.is_empty() {
|
||||
write_info.state = WriteState::Finish;
|
||||
} else {
|
||||
write_info.state = WriteState::BalanceStart;
|
||||
// If we balance, we must save the cursor position and seek to it later.
|
||||
// FIXME: we shouldn't have both DeleteState::SeekAfterBalancing and
|
||||
// save_context()/restore/context(), they are practically the same thing.
|
||||
self.save_context(CursorContext::TableRowId(bkey.to_rowid()));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -2149,13 +2158,22 @@ impl BTreeCursor {
|
||||
&self.collations,
|
||||
);
|
||||
if cmp == Ordering::Equal {
|
||||
tracing::debug!("found exact match with cell_idx={cell_idx}, overwriting");
|
||||
tracing::debug!("IndexLeafCell: found exact match with cell_idx={cell_idx}, overwriting");
|
||||
self.has_record.set(true);
|
||||
self.overwrite_cell(page.clone(), cell_idx, record)?;
|
||||
self.state
|
||||
let write_info = self
|
||||
.state
|
||||
.mut_write_info()
|
||||
.expect("expected write info")
|
||||
.state = WriteState::Finish;
|
||||
.expect("expected write info");
|
||||
if page.get().get_contents().overflow_cells.is_empty() {
|
||||
write_info.state = WriteState::Finish;
|
||||
} else {
|
||||
write_info.state = WriteState::BalanceStart;
|
||||
// If we balance, we must save the cursor position and seek to it later.
|
||||
// FIXME: we shouldn't have both DeleteState::SeekAfterBalancing and
|
||||
// save_context()/restore/context(), they are practically the same thing.
|
||||
self.save_context(CursorContext::IndexKeyRowId((*record).clone()));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -4023,7 +4041,10 @@ impl BTreeCursor {
|
||||
_rowid, _payload, ..
|
||||
}) = cell
|
||||
else {
|
||||
unreachable!("unexpected page_type");
|
||||
unreachable!(
|
||||
"BTreeCursor::rowid(): unexpected page_type: {:?}",
|
||||
page_type
|
||||
);
|
||||
};
|
||||
Ok(CursorResult::Ok(Some(_rowid)))
|
||||
} else {
|
||||
|
||||
@@ -485,14 +485,17 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
_ => panic!("Error executing query: {}", e),
|
||||
}
|
||||
}
|
||||
let mut res = conn.query("PRAGMA integrity_check", ()).await.unwrap();
|
||||
if let Some(row) = res.next().await? {
|
||||
let value = row.get_value(0).unwrap();
|
||||
if value != "ok".into() {
|
||||
panic!("integrity check failed: {:?}", value);
|
||||
const INTEGRITY_CHECK_INTERVAL: usize = 100;
|
||||
if query_index % INTEGRITY_CHECK_INTERVAL == 0 {
|
||||
let mut res = conn.query("PRAGMA integrity_check", ()).await.unwrap();
|
||||
if let Some(row) = res.next().await? {
|
||||
let value = row.get_value(0).unwrap();
|
||||
if value != "ok".into() {
|
||||
panic!("integrity check failed: {:?}", value);
|
||||
}
|
||||
} else {
|
||||
panic!("integrity check failed: no rows");
|
||||
}
|
||||
} else {
|
||||
panic!("integrity check failed: no rows");
|
||||
}
|
||||
}
|
||||
Ok::<_, Box<dyn std::error::Error + Send + Sync>>(())
|
||||
|
||||
Reference in New Issue
Block a user