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};
14use reth_primitives::{
15 static_file::{SegmentHeader, SegmentRangeInclusive},
16 StaticFileSegment,
17};
18
19mod masks;
20pub use masks::*;
21
22type SortedStaticFiles =
24 HashMap<StaticFileSegment, Vec<(SegmentRangeInclusive, Option<SegmentRangeInclusive>)>>;
25
26pub fn iter_static_files(path: impl AsRef<Path>) -> Result<SortedStaticFiles, NippyJarError> {
30 let path = path.as_ref();
31 if !path.exists() {
32 reth_fs_util::create_dir_all(path).map_err(|err| NippyJarError::Custom(err.to_string()))?;
33 }
34
35 let mut static_files = SortedStaticFiles::default();
36 let entries = reth_fs_util::read_dir(path)
37 .map_err(|err| NippyJarError::Custom(err.to_string()))?
38 .filter_map(Result::ok)
39 .collect::<Vec<_>>();
40
41 for entry in entries {
42 if entry.metadata().is_ok_and(|metadata| metadata.is_file()) {
43 if let Some((segment, _)) =
44 StaticFileSegment::parse_filename(&entry.file_name().to_string_lossy())
45 {
46 let jar = NippyJar::<SegmentHeader>::load(&entry.path())?;
47
48 let (block_range, tx_range) = (
49 jar.user_header().block_range().copied(),
50 jar.user_header().tx_range().copied(),
51 );
52
53 if let Some(block_range) = block_range {
54 match static_files.entry(segment) {
55 Entry::Occupied(mut entry) => {
56 entry.get_mut().push((block_range, tx_range));
57 }
58 Entry::Vacant(entry) => {
59 entry.insert(vec![(block_range, tx_range)]);
60 }
61 }
62 }
63 }
64 }
65 }
66
67 for range_list in static_files.values_mut() {
68 range_list.sort_by(|a, b| a.0.end().cmp(&b.0.end()));
70 }
71
72 Ok(static_files)
73}