use super::*;
impl<F: VfsFile, W: WalBarrier> Pager<F, W> {
pub(super) fn batch_active(&self) -> Result<bool, PagerError> {
Ok(self
.staged_pages
.lock()
.map_err(|_| PagerError::LockPoisoned)?
.is_some())
}
pub(super) fn bounded_writeback(&self) -> Result<bool, PagerError> {
Ok(self.batch_active()? || self.file_lock()?.max_read_buffer_bytes() < 2 * PAGE_SIZE)
}
pub fn begin_write_batch(&self) -> Result<(), PagerError> {
let _ownership = self.lock_ownership_mutations();
self.ensure_writeback_available()?;
if !self.dwb_enabled || self.batch_active()? {
return Err(PagerError::InvalidDatabase(
"write batch requires double-write protection and no active batch".into(),
));
}
self.sync()?;
*self
.staged_pages
.lock()
.map_err(|_| PagerError::LockPoisoned)? = Some(pager_io::StagedPageBatch::default());
Ok(())
}
pub fn commit_write_batch(&self) -> Result<(), PagerError> {
let _ownership = self.lock_ownership_mutations();
self.ensure_writeback_available()?;
if !self.batch_active()? {
return Err(PagerError::InvalidDatabase(
"no prepared write batch".into(),
));
}
let result = (|| {
self.flush()?;
let mut file = self.file_lock()?;
let batch = self
.staged_pages
.lock()
.map_err(|_| PagerError::LockPoisoned)?
.take()
.expect("active batch under exclusive mutation fence");
batch.publish(&mut *file)?;
drop(file);
if *self.header_dirty_lock()? {
self.write_header_and_sync()?;
}
Ok(())
})();
if result.is_err() {
self.writeback_failed
.store(true, std::sync::atomic::Ordering::Release);
}
result
}
pub fn fence_write_batch(&self) {
self.writeback_failed
.store(true, std::sync::atomic::Ordering::Release);
}
}