mirror of
https://github.com/aljazceru/turso.git
synced 2026-01-31 05:44:25 +01:00
add is_hole / punch_hole optional methods to IO trait and remove is_hole method from Database trait
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use super::{Buffer, Clock, Completion, File, OpenFlags, IO};
|
||||
use crate::LimboError;
|
||||
use crate::{io::clock::DefaultClock, Result};
|
||||
use crate::{turso_assert, LimboError};
|
||||
|
||||
use crate::io::clock::Instant;
|
||||
use std::{
|
||||
@@ -238,23 +238,25 @@ impl File for MemoryFile {
|
||||
fn has_hole(&self, pos: usize, len: usize) -> Result<bool> {
|
||||
let start_page = pos / PAGE_SIZE;
|
||||
let end_page = ((pos + len.max(1)) - 1) / PAGE_SIZE;
|
||||
let (mut holes, mut pages) = (0, 0);
|
||||
for page_no in start_page..=end_page {
|
||||
match self.get_page(page_no) {
|
||||
Some(_) => pages += 1,
|
||||
None => holes += 1,
|
||||
};
|
||||
if self.get_page(page_no).is_some() {
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
if holes == 0 {
|
||||
Ok(false)
|
||||
} else if pages == 0 {
|
||||
Ok(true)
|
||||
} else {
|
||||
Err(LimboError::InternalError(format!(
|
||||
"ambigous has_hole result: pos={pos}, len={len}, pages={pages}, holes={holes}"
|
||||
)))
|
||||
fn punch_hole(&self, pos: usize, len: usize) -> Result<()> {
|
||||
turso_assert!(
|
||||
pos % PAGE_SIZE == 0 && len % PAGE_SIZE == 0,
|
||||
"hole must be page aligned"
|
||||
);
|
||||
let start_page = pos / PAGE_SIZE;
|
||||
let end_page = ((pos + len.max(1)) - 1) / PAGE_SIZE;
|
||||
for page_no in start_page..=end_page {
|
||||
unsafe { (*self.pages.get()).remove(&page_no) };
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,10 +92,22 @@ pub trait File: Send + Sync {
|
||||
}
|
||||
fn size(&self) -> Result<u64>;
|
||||
fn truncate(&self, len: u64, c: Completion) -> Result<Completion>;
|
||||
|
||||
/// Optional method implemented by the IO which supports "partial" files (e.g. file with "holes")
|
||||
/// This method is used in sync engine only for now (in partial sync mode) and never used in the core database code
|
||||
///
|
||||
/// The hole is the contiguous file region which is not allocated by the file-system
|
||||
/// If there is a single byte which is allocated within a given range - method must return false in this case
|
||||
// todo: need to add custom completion type?
|
||||
fn has_hole(&self, _pos: usize, _len: usize) -> Result<bool> {
|
||||
panic!("has_hole is not supported for the given IO implementation")
|
||||
}
|
||||
/// Optional method implemented by the IO which supports "partial" files (e.g. file with "holes")
|
||||
/// This method is used in sync engine only for now (in partial sync mode) and never used in the core database code
|
||||
// todo: need to add custom completion type?
|
||||
fn punch_hole(&self, _pos: usize, _len: usize) -> Result<()> {
|
||||
panic!("punch_hole is not supported for the given IO implementation")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
|
||||
@@ -10,7 +10,7 @@ mod functions;
|
||||
mod incremental;
|
||||
pub mod index_method;
|
||||
mod info;
|
||||
mod io;
|
||||
pub mod io;
|
||||
#[cfg(feature = "json")]
|
||||
mod json;
|
||||
pub mod mvcc;
|
||||
|
||||
@@ -85,8 +85,6 @@ pub trait DatabaseStorage: Send + Sync {
|
||||
fn sync(&self, c: Completion) -> Result<Completion>;
|
||||
fn size(&self) -> Result<u64>;
|
||||
fn truncate(&self, len: usize, c: Completion) -> Result<Completion>;
|
||||
// todo: need to add custom completion type?
|
||||
fn has_hole(&self, pos: usize, len: usize) -> Result<bool>;
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -261,11 +259,6 @@ impl DatabaseStorage for DatabaseFile {
|
||||
let c = self.file.truncate(len as u64, c)?;
|
||||
Ok(c)
|
||||
}
|
||||
|
||||
#[instrument(skip_all, level = Level::INFO)]
|
||||
fn has_hole(&self, pos: usize, len: usize) -> Result<bool> {
|
||||
self.file.has_hole(pos, len)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "fs")]
|
||||
|
||||
Reference in New Issue
Block a user