reth_db/static_file/
mod.rs1use std::{
4 collections::{hash_map::Entry, HashMap},
5 path::Path,
6};
7
8mod cursor;
9pub use cursor::StaticFileCursor;
10
11mod mask;
12pub use mask::*;
13use reth_nippy_jar::{NippyJar, NippyJarError};
14
15mod masks;
16pub use masks::*;
17use reth_static_file_types::{SegmentHeader, SegmentRangeInclusive, StaticFileSegment};
18
19type SortedStaticFiles =
21 HashMap<StaticFileSegment, Vec<(SegmentRangeInclusive, Option<SegmentRangeInclusive>)>>;
22
23pub fn iter_static_files(path: &Path) -> Result<SortedStaticFiles, NippyJarError> {
27 if !path.exists() {
28 reth_fs_util::create_dir_all(path).map_err(|err| NippyJarError::Custom(err.to_string()))?;
29 }
30
31 let mut static_files = SortedStaticFiles::default();
32 let entries = reth_fs_util::read_dir(path)
33 .map_err(|err| NippyJarError::Custom(err.to_string()))?
34 .filter_map(Result::ok);
35 for entry in entries {
36 if entry.metadata().is_ok_and(|metadata| metadata.is_file()) &&
37 let Some((segment, _)) =
38 StaticFileSegment::parse_filename(&entry.file_name().to_string_lossy())
39 {
40 let jar = NippyJar::<SegmentHeader>::load(&entry.path())?;
41
42 let (block_range, tx_range) =
43 (jar.user_header().block_range().copied(), jar.user_header().tx_range().copied());
44
45 if let Some(block_range) = block_range {
46 match static_files.entry(segment) {
47 Entry::Occupied(mut entry) => {
48 entry.get_mut().push((block_range, tx_range));
49 }
50 Entry::Vacant(entry) => {
51 entry.insert(vec![(block_range, tx_range)]);
52 }
53 }
54 }
55 }
56 }
57
58 for range_list in static_files.values_mut() {
59 range_list.sort_by_key(|(r, _)| r.end());
61 }
62
63 Ok(static_files)
64}