reth_db/static_file/
mod.rsuse std::{
collections::{hash_map::Entry, HashMap},
path::Path,
};
mod cursor;
pub use cursor::StaticFileCursor;
mod mask;
pub use mask::*;
use reth_nippy_jar::{NippyJar, NippyJarError};
use reth_primitives::{
static_file::{SegmentHeader, SegmentRangeInclusive},
StaticFileSegment,
};
mod masks;
type SortedStaticFiles =
HashMap<StaticFileSegment, Vec<(SegmentRangeInclusive, Option<SegmentRangeInclusive>)>>;
pub fn iter_static_files(path: impl AsRef<Path>) -> Result<SortedStaticFiles, NippyJarError> {
let path = path.as_ref();
if !path.exists() {
reth_fs_util::create_dir_all(path).map_err(|err| NippyJarError::Custom(err.to_string()))?;
}
let mut static_files = SortedStaticFiles::default();
let entries = reth_fs_util::read_dir(path)
.map_err(|err| NippyJarError::Custom(err.to_string()))?
.filter_map(Result::ok)
.collect::<Vec<_>>();
for entry in entries {
if entry.metadata().map_or(false, |metadata| metadata.is_file()) {
if let Some((segment, _)) =
StaticFileSegment::parse_filename(&entry.file_name().to_string_lossy())
{
let jar = NippyJar::<SegmentHeader>::load(&entry.path())?;
let (block_range, tx_range) = (
jar.user_header().block_range().copied(),
jar.user_header().tx_range().copied(),
);
if let Some(block_range) = block_range {
match static_files.entry(segment) {
Entry::Occupied(mut entry) => {
entry.get_mut().push((block_range, tx_range));
}
Entry::Vacant(entry) => {
entry.insert(vec![(block_range, tx_range)]);
}
}
}
}
}
}
for range_list in static_files.values_mut() {
range_list.sort_by(|a, b| a.0.end().cmp(&b.0.end()));
}
Ok(static_files)
}