use super::{
BorrowedRecord, MergedRecordSnapshot, RecordKeyIterator, RecordMetadata, RecordPointVisitor,
RecordValueVisitor,
};
use crate::mvcc::overlay::PrivateRecordSelection;
use crate::mvcc::VersionResult;
use crate::read_control::StorageReadControl;
pub struct SelectedRecordRead<'a> {
view: &'a MergedRecordSnapshot,
private: PrivateRecordSelection<'a>,
}
impl MergedRecordSnapshot {
pub fn selected(&self, control: &StorageReadControl) -> SelectedRecordRead<'_> {
SelectedRecordRead {
view: self,
private: PrivateRecordSelection::new(&self.private, control),
}
}
}
impl SelectedRecordRead<'_> {
pub fn visit_values(
&mut self,
keys: &mut RecordKeyIterator<'_>,
control: &StorageReadControl,
visit: &mut RecordPointVisitor<'_>,
) -> VersionResult<()> {
if self.view.private_revision().is_none() {
return self.view.committed.visit_values(keys, control, visit);
}
loop {
control.check()?;
let Some(key) = keys.next() else {
return Ok(());
};
let key = key?;
let mut more = true;
self.visit_value(&key, control, &mut |record| {
more = visit(&key, record)?;
Ok(())
})?;
control.check()?;
if !more {
return Ok(());
}
}
}
pub fn metadata(
&mut self,
key: &[u8],
control: &StorageReadControl,
) -> VersionResult<Option<RecordMetadata>> {
if let Some(record) = self.private.metadata(key, control)? {
return Ok(Some(record));
}
self.view.committed.metadata(key, control)
}
pub fn visit_value(
&mut self,
key: &[u8],
control: &StorageReadControl,
visit: &mut RecordValueVisitor<'_>,
) -> VersionResult<()> {
if let Some(write) = self.private.read(key, control)? {
visit(Some(BorrowedRecord {
revision: write.expected(),
value: write.value(),
}))?;
control.check()?;
return Ok(());
}
self.view.committed.visit_value(key, control, visit)
}
}