Skip to content

Commit 6d12fa3

Browse files
committed
core/mvcc/cursor: use btree with exists
1 parent 94ee28c commit 6d12fa3

File tree

1 file changed

+56
-29
lines changed

1 file changed

+56
-29
lines changed

core/mvcc/cursor.rs

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,17 @@ enum PrevState {
4343
new_position_in_mvcc: CursorPosition,
4444
},
4545
}
46+
47+
#[derive(Debug, Clone)]
48+
enum ExistsState {
49+
ExistsBtree,
50+
}
51+
4652
#[derive(Debug, Clone)]
4753
enum MvccLazyCursorState {
4854
Next(NextState),
4955
Prev(PrevState),
56+
Exists(ExistsState),
5057
}
5158

5259
pub struct MvccLazyCursor<Clock: LogicalClock> {
@@ -632,39 +639,59 @@ impl<Clock: LogicalClock + 'static> CursorTrait for MvccLazyCursor<Clock> {
632639
}
633640

634641
fn exists(&mut self, key: &Value) -> Result<IOResult<bool>> {
635-
self.invalidate_record();
636-
let int_key = match key {
637-
Value::Integer(i) => i,
638-
_ => unreachable!("btree tables are indexed by integers!"),
639-
};
640-
let rowid = self.db.seek_rowid(
641-
Bound::Included(&RowID {
642-
table_id: self.table_id,
643-
row_id: RowKey::Int(*int_key),
644-
}),
645-
true,
646-
self.tx_id,
647-
);
648-
tracing::trace!("found {rowid:?}");
649-
let exists = if let Some(rowid) = rowid {
650-
let RowKey::Int(rowid) = rowid.row_id else {
651-
panic!("Rowid is not an integer in mvcc table cursor");
642+
if self.state.borrow().is_none() {
643+
self.invalidate_record();
644+
let int_key = match key {
645+
Value::Integer(i) => i,
646+
_ => unreachable!("btree tables are indexed by integers!"),
652647
};
653-
rowid == *int_key
654-
} else {
655-
false
656-
};
657-
if exists {
658-
self.current_pos.replace(CursorPosition::Loaded {
659-
row_id: RowID {
648+
let rowid = self.db.seek_rowid(
649+
Bound::Included(&RowID {
660650
table_id: self.table_id,
661651
row_id: RowKey::Int(*int_key),
662-
},
663-
in_btree: false,
664-
btree_consumed: false,
665-
});
652+
}),
653+
true,
654+
self.tx_id,
655+
);
656+
tracing::trace!("found {rowid:?}");
657+
let exists = if let Some(rowid) = rowid {
658+
let RowKey::Int(rowid) = rowid.row_id else {
659+
panic!("Rowid is not an integer in mvcc table cursor");
660+
};
661+
rowid == *int_key
662+
} else {
663+
false
664+
};
665+
if exists {
666+
self.current_pos.replace(CursorPosition::Loaded {
667+
row_id: RowID {
668+
table_id: self.table_id,
669+
row_id: RowKey::Int(*int_key),
670+
},
671+
in_btree: false,
672+
btree_consumed: false,
673+
});
674+
return Ok(IOResult::Done(exists));
675+
} else if self.is_btree_allocated() {
676+
self.state
677+
.replace(Some(MvccLazyCursorState::Exists(ExistsState::ExistsBtree)));
678+
} else {
679+
return Ok(IOResult::Done(false));
680+
}
666681
}
667-
Ok(IOResult::Done(exists))
682+
683+
let Some(MvccLazyCursorState::Exists(ExistsState::ExistsBtree)) =
684+
self.state.borrow().clone()
685+
else {
686+
panic!("Invalid state {:?}", self.state.borrow());
687+
};
688+
assert!(
689+
self.is_btree_allocated(),
690+
"BTree should be allocated when we are in ExistsBtree state"
691+
);
692+
self.state.replace(None);
693+
let found = return_if_io!(self.btree_cursor.exists(key));
694+
Ok(IOResult::Done(found))
668695
}
669696

670697
fn clear_btree(&mut self) -> Result<IOResult<Option<usize>>> {

0 commit comments

Comments
 (0)