16 #include <boost/algorithm/string.hpp>
20 #include <unordered_map>
37 std::shared_ptr<TFile>
getFile(
const std::string& identifier )
override;
40 bool hasIdentifier(
const std::string& identifier )
const override;
45 this,
"Config", {},
"Map of keywords to file paths for file access" };
55 std::shared_ptr<TFile>
openFile(
const std::string& filePath,
const std::string& option,
int compress );
68 std::vector<std::shared_ptr<TFile>>
m_files;
80 std::map<std::string, std::string> parseFilePath(
const std::string&
path ) {
81 std::vector<std::string> parts;
82 boost::split( parts,
path, boost::is_any_of(
"?" ) );
83 std::map<std::string, std::string> result;
84 if ( parts.size() > 1 ) {
85 std::vector<std::string> params;
86 boost::split( params, parts[1], boost::is_any_of(
"&" ) );
87 for (
auto& param : params ) {
88 std::vector<std::string> kv;
89 boost::split( kv, param, boost::is_any_of(
"=" ) );
90 if ( kv.size() == 2 ) { result[boost::trim_copy( kv[0] )] = boost::trim_copy( kv[1] ); }
93 result[
"mode"] = ( result.find(
"mode" ) == result.end() ) ?
"CREATE" : result[
"mode"];
94 result[
"path"] = boost::trim_copy( parts[0] );
107 StatusCode checkConfig(
const std::map<std::string, std::string>& configMap,
const FileSvc& svc ) {
108 std::map<std::string, std::map<std::string, std::string>> fileParams;
109 for (
const auto& [identifier,
path] : configMap ) {
110 auto params = parseFilePath(
path );
112 auto& existingParams = fileParams[params[
"path"]];
113 if ( !existingParams.empty() ) {
114 if ( existingParams != params ) {
115 svc.error() <<
"Conflicting configurations for file path: " << params[
"path"] <<
endmsg;
119 existingParams = std::move( params );
132 std::optional<size_t> findFileIndex(
const std::vector<std::shared_ptr<TFile>>& files,
const std::string& filePath ) {
133 auto it = std::find_if( files.begin(), files.end(),
134 [&filePath](
const auto& file ) { return file && file->GetName() == filePath; } );
135 if ( it != files.end() ) {
return std::distance( files.begin(), it ); }
147 auto params = parseFilePath(
path );
150 if (
auto fileIndex = findFileIndex(
m_files, params[
"path"] ) ) {
152 m_identifiers[boost::to_lower_copy( identifier )] = *fileIndex;
155 int compress = ( params.find(
"compress" ) != params.end() )
156 ? std::stoi( params[
"compress"] )
157 : ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault;
158 if (
auto file =
openFile(
path, params[
"mode"], compress ) ) {
159 m_files.push_back( std::move( file ) );
162 error() <<
"Failed to open file: " << params[
"path"] <<
endmsg;
175 auto it =
m_identifiers.find( boost::to_lower_copy( identifier ) );
177 error() <<
"No file associated with identifier: " << identifier <<
endmsg;
185 std::shared_ptr<TFile>
FileSvc::openFile(
const std::string& filePath,
const std::string& option,
int compress ) {
186 auto file = std::make_shared<TFile>( filePath.c_str(), option.c_str(),
"", compress );
187 if ( !file || file->IsZombie() ) {
return nullptr; }
192 for (
const auto& file :
m_files ) {
193 if ( file ) { file->Close(); }