11 namespace fs = std::filesystem;
13 static constexpr auto snapshot_file_prefix =
"snapshot";
14 static constexpr auto snapshot_idx_delimiter =
"_";
15 static constexpr auto snapshot_committed_suffix =
".committed";
17 static bool is_snapshot_file(
const std::string& file_name)
19 return file_name.starts_with(snapshot_file_prefix);
22 static bool is_snapshot_file_committed(
const std::string& file_name)
24 return file_name.find(snapshot_committed_suffix) != std::string::npos;
27 static size_t read_idx(
const std::string& str)
30 const auto* end_ptr = str.data() + str.size();
32 auto res = std::from_chars(str.data(), end_ptr, idx);
33 if (res.ec != std::errc())
35 throw std::logic_error(
36 fmt::format(
"Could not read idx from string \"{}\": {}", str, res.ec));
39 if (res.ptr != end_ptr)
41 throw std::logic_error(fmt::format(
42 R
"(Trailing characters in "{}" cannot be converted to idx: "{}")",
44 std::string(res.ptr, end_ptr)));
49 static std::optional<size_t> get_evidence_commit_idx_from_file_name(
50 const std::string& file_name)
56 auto pos = file_name.find(snapshot_committed_suffix);
57 if (pos == std::string::npos)
59 throw std::logic_error(
60 fmt::format(
"Snapshot file \"{}\" is not committed", file_name));
63 pos = file_name.find(snapshot_idx_delimiter, pos);
64 if (pos == std::string::npos)
70 return read_idx(file_name.substr(pos + 1));
73 static size_t get_snapshot_idx_from_file_name(
const std::string& file_name)
75 if (!is_snapshot_file(file_name))
77 throw std::logic_error(
78 fmt::format(
"File \"{}\" is not a valid snapshot file", file_name));
81 auto idx_pos = file_name.find_first_of(snapshot_idx_delimiter);
82 if (idx_pos == std::string::npos)
84 throw std::logic_error(fmt::format(
85 "Snapshot file name {} does not contain snapshot seqno", file_name));
88 auto evidence_idx_pos =
89 file_name.find_first_of(snapshot_idx_delimiter, idx_pos + 1);
90 if (evidence_idx_pos == std::string::npos)
92 throw std::logic_error(fmt::format(
93 "Snapshot file \"{}\" does not contain evidence index", file_name));
97 file_name.substr(idx_pos + 1, evidence_idx_pos - idx_pos - 1));
100 static size_t get_snapshot_evidence_idx_from_file_name(
101 const std::string& file_name)
103 if (!is_snapshot_file(file_name))
105 throw std::logic_error(
106 fmt::format(
"File \"{}\" is not a valid snapshot file", file_name));
109 auto idx_pos = file_name.find_first_of(snapshot_idx_delimiter);
110 if (idx_pos == std::string::npos)
112 throw std::logic_error(
113 fmt::format(
"Snapshot file \"{}\" does not contain index", file_name));
116 auto evidence_idx_pos =
117 file_name.find_first_of(snapshot_idx_delimiter, idx_pos + 1);
118 if (evidence_idx_pos == std::string::npos)
120 throw std::logic_error(fmt::format(
121 "Snapshot file \"{}\" does not contain evidence index", file_name));
125 size_t end_str = std::string::npos;
126 auto commit_suffix_pos =
127 file_name.find_first_of(snapshot_committed_suffix, evidence_idx_pos + 1);
128 if (commit_suffix_pos != std::string::npos)
130 end_str = commit_suffix_pos - evidence_idx_pos - 1;
133 return read_idx(file_name.substr(evidence_idx_pos + 1, end_str));
137 const fs::path& directory,
size_t& latest_committed_snapshot_idx)
139 std::optional<fs::path> latest_committed_snapshot_file_name = std::nullopt;
141 for (
const auto& f : fs::directory_iterator(directory))
143 auto file_name = f.path().filename();
144 if (!is_snapshot_file(file_name))
146 LOG_INFO_FMT(
"Ignoring non-snapshot file {}", file_name);
150 if (!is_snapshot_file_committed(file_name))
152 LOG_INFO_FMT(
"Ignoring non-committed snapshot file {}", file_name);
156 if (fs::exists(f.path()) && fs::is_empty(f.path()))
158 LOG_INFO_FMT(
"Ignoring empty snapshot file {}", file_name);
162 auto snapshot_idx = get_snapshot_idx_from_file_name(file_name);
163 if (snapshot_idx > latest_committed_snapshot_idx)
165 latest_committed_snapshot_file_name = file_name;
166 latest_committed_snapshot_idx = snapshot_idx;
170 return latest_committed_snapshot_file_name;
#define LOG_INFO_FMT
Definition internal_logger.h:15
std::optional< fs::path > find_latest_committed_snapshot_in_directory(const fs::path &directory, size_t &latest_committed_snapshot_idx)
Definition filenames.h:136