use std::io::Cursor;
use std::path::Path;
use crate::common::bitvec::BitVec;
use crate::common::generic_consts::Sequential;
use crate::common::mmap::AdviceSetting;
use crate::common::stored_bitslice::StoredBitSlice;
use crate::common::universal_io::{
CachedReadFs, OpenOptions, Populate, ReadRange, TypedStorage, UniversalRead,
UniversalReadFileOps, UniversalReadFs,
};
use super::ReadOnlyImmutableIdTracker;
use crate::segment::common::operation_error::OperationResult;
use crate::segment::id_tracker::compressed::versions_store::CompressedVersions;
use crate::segment::id_tracker::immutable_id_tracker::deleted_storage::deleted_path;
use crate::segment::id_tracker::immutable_id_tracker::mappings_storage::{load_mapping, mappings_path};
use crate::segment::id_tracker::immutable_id_tracker::versions_storage::version_mapping_path;
use crate::segment::types::SeqNumberType;
impl<S: UniversalRead> ReadOnlyImmutableIdTracker<S> {
pub(super) fn 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 !UniversalReadFileOps::exists(fs, &mappings_path(segment_path))? {
return Ok(false);
}
let options = Self::open_options();
fs.schedule_prefetch(&deleted_path(segment_path), Some(options), None)?;
fs.schedule_prefetch(&version_mapping_path(segment_path), Some(options), None)?;
fs.schedule_prefetch(&mappings_path(segment_path), Some(options), None)?;
Ok(true)
}
pub fn try_open(
fs: &impl UniversalReadFs<File = S>,
segment_path: &Path,
) -> OperationResult<Option<Self>> {
if !UniversalReadFileOps::exists(fs, &mappings_path(segment_path))? {
return Ok(None);
}
Ok(Some(Self::open(fs, segment_path)?))
}
pub fn open(fs: &impl UniversalReadFs<File = S>, segment_path: &Path) -> OperationResult<Self> {
let options = Self::open_options();
let deleted =
StoredBitSlice::open(fs, deleted_path(segment_path), options, Default::default())?;
let mut deleted_bitvec = BitVec::new();
deleted_bitvec.extend_from_bitslice(deleted.read_all()?.as_ref());
let internal_to_version_file = TypedStorage::<S, SeqNumberType>::new(fs.open(
version_mapping_path(segment_path),
options,
Default::default(),
)?);
let internal_to_version =
CompressedVersions::from_slice(&internal_to_version_file.read_whole()?);
let mappings_file = fs.open(mappings_path(segment_path), options, Default::default())?;
let mappings_bytes = mappings_file
.read::<_, u8>(ReadRange::new(0, mappings_file.len::<u8>()?), Sequential)?;
let mappings = load_mapping(Cursor::new(mappings_bytes.as_ref()), Some(deleted_bitvec))?;
Ok(Self {
path: segment_path.to_path_buf(),
deleted,
internal_to_version,
mappings,
})
}
}