use std::path::Path;
use std::sync::OnceLock;
use crate::common::mmap::AdviceSetting;
use crate::common::stored_bitslice::StoredBitSlice;
use crate::common::universal_io::{
CachedReadFs, OpenOptions, Populate, TypedStorage, UniversalRead, UniversalReadFs,
};
use super::ReadOnlyDiskIdTracker;
use crate::segment::common::operation_error::{OperationError, OperationResult};
use crate::segment::id_tracker::disk_id_tracker::reader::DiskMappingReader;
use crate::segment::id_tracker::immutable_id_tracker::{deleted_path, version_mapping_path};
use crate::segment::types::SeqNumberType;
impl<S: UniversalRead> ReadOnlyDiskIdTracker<S> {
pub(super) fn open_options() -> OpenOptions {
OpenOptions {
writeable: false,
need_sequential: false,
populate: Populate::No,
advice: AdviceSetting::Global,
}
}
fn deleted_open_options() -> OpenOptions {
OpenOptions {
writeable: false,
need_sequential: false,
populate: Populate::PreferBackground,
advice: AdviceSetting::Global,
}
}
pub fn try_preopen(
fs: &impl CachedReadFs<File = S>,
segment_path: &Path,
) -> OperationResult<bool> {
if !DiskMappingReader::try_preopen(fs, segment_path)? {
return Ok(false);
}
let options = Self::open_options();
fs.schedule_prefetch(&version_mapping_path(segment_path), Some(options), None)?;
fs.schedule_prefetch(
&deleted_path(segment_path),
Some(Self::deleted_open_options()),
None,
)?;
Ok(true)
}
pub fn open(fs: &impl UniversalReadFs<File = S>, segment_path: &Path) -> OperationResult<Self> {
Self::try_open(fs, segment_path)?.ok_or_else(|| {
OperationError::service_error(format!(
"on-disk id tracker not found in segment {}",
segment_path.display(),
))
})
}
pub fn try_open(
fs: &impl UniversalReadFs<File = S>,
segment_path: &Path,
) -> OperationResult<Option<Self>> {
let Some(reader) = DiskMappingReader::try_open(fs, segment_path)? else {
return Ok(None);
};
let options = Self::open_options();
let versions = TypedStorage::<S, SeqNumberType>::new(fs.open(
version_mapping_path(segment_path),
options,
Default::default(),
)?);
let versions_len = versions.len()?;
let deleted_file = StoredBitSlice::open(
fs,
deleted_path(segment_path),
Self::deleted_open_options(),
Default::default(),
)?;
Ok(Some(Self {
path: segment_path.to_path_buf(),
reader,
versions,
versions_len,
deleted_file,
deleted_full: OnceLock::new(),
}))
}
}