use std::path::{Path, PathBuf};
use crate::common::mmap::AdviceSetting;
use crate::common::stored_bitslice::StoredBitSlice;
use crate::common::types::PointOffsetType;
use crate::common::universal_io::{OpenOptions, Populate, TypedStorage, UniversalRead};
use roaring::RoaringBitmap;
use super::dynamic_stored_flags::{DynamicFlagsStatus, FLAGS_FILE, status_file};
use super::roaring_flags::RoaringFlagsRead;
use crate::segment::common::operation_error::OperationResult;
pub struct ReadOnlyRoaringFlags<S: UniversalRead> {
bitmap: RoaringBitmap,
len: usize,
directory: PathBuf,
_marker: std::marker::PhantomData<S>,
}
impl<S: UniversalRead> ReadOnlyRoaringFlags<S> {
pub fn open(fs: &S::Fs, directory: &Path) -> OperationResult<Self> {
let status_path = status_file(directory);
let status = TypedStorage::<S, DynamicFlagsStatus>::open(
fs,
&status_path,
OpenOptions {
writeable: false,
need_sequential: false,
populate: Populate::No,
advice: AdviceSetting::Global,
},
Default::default(),
)?;
let len = status.read_whole()?[0].len();
let flags_path = directory.join(FLAGS_FILE);
let flags_storage = StoredBitSlice::<S>::open(
fs,
&flags_path,
OpenOptions {
writeable: false,
need_sequential: false,
populate: Populate::No,
advice: AdviceSetting::Global,
},
Default::default(),
)?;
let bitmap = RoaringBitmap::from_sorted_iter(
flags_storage.iter_ones()?.map(|i| i as PointOffsetType),
)
.expect("iter_ones iterates in sorted order");
Ok(Self {
bitmap,
len,
directory: directory.to_path_buf(),
_marker: std::marker::PhantomData,
})
}
}
impl<S: UniversalRead> RoaringFlagsRead for ReadOnlyRoaringFlags<S> {
fn len(&self) -> usize {
self.len
}
fn get_bitmap(&self) -> &RoaringBitmap {
&self.bitmap
}
fn files(&self) -> Vec<PathBuf> {
vec![
status_file(&self.directory),
self.directory.join(FLAGS_FILE),
]
}
}