2323#include < string>
2424#include < chrono>
2525#include < map>
26+ #include < string_view>
2627#include < unordered_map>
2728#include < memory>
2829#include < cstdlib>
30+ #include < vector>
2931
3032class TGeoManager ; // we need to forward-declare those classes which should not be cleaned up
3133
@@ -57,6 +59,7 @@ class CCDBManagerInstance
5759 int queries = 0 ;
5860 int fetches = 0 ;
5961 int failures = 0 ;
62+ std::map<std::string, std::string> cacheOfHeaders;
6063 bool isValid (long ts) { return ts < endvalidity && ts >= startvalidity; }
6164 bool isCacheValid (long ts)
6265 {
@@ -70,6 +73,7 @@ class CCDBManagerInstance
7073 uuid = " " ;
7174 startvalidity = 0 ;
7275 endvalidity = -1 ;
76+ cacheOfHeaders.clear ();
7377 }
7478 };
7579
@@ -98,9 +102,9 @@ class CCDBManagerInstance
98102 // / query timestamp
99103 long getTimestamp () const { return mTimestamp ; }
100104
101- // / retrieve an object of type T from CCDB as stored under path and timestamp. Optional to get the headers
105+ // / retrieve an object of type T from CCDB as stored under path and timestamp. Optional to get the headers. Can give a filter of headers to be saved in cache and returned (if present)
102106 template <typename T>
103- T* getForTimeStamp (std::string const & path, long timestamp, std::map<std::string, std::string>* headers = nullptr );
107+ T* getForTimeStamp (std::string const & path, long timestamp, std::map<std::string, std::string>* headers = nullptr , std::vector<std::string_view> headerFilter = {} );
104108
105109 // / retrieve an object of type T from CCDB as stored under path and using the timestamp in the middle of the run
106110 template <typename T>
@@ -112,10 +116,7 @@ class CCDBManagerInstance
112116 {
113117 // TODO: add some error info/handling when failing
114118 mMetaData = metaData;
115- auto obj = getForTimeStamp<T>(path, timestamp);
116- if (headers) {
117- *headers = mHeaders ;
118- }
119+ auto obj = getForTimeStamp<T>(path, timestamp, headers);
119120 return obj;
120121 }
121122
@@ -235,7 +236,7 @@ class CCDBManagerInstance
235236};
236237
237238template <typename T>
238- T* CCDBManagerInstance::getForTimeStamp (std::string const & path, long timestamp, std::map<std::string, std::string>* headers)
239+ T* CCDBManagerInstance::getForTimeStamp (std::string const & path, long timestamp, std::map<std::string, std::string>* headers, std::vector<std::string_view> headerFilter )
239240{
240241 mHeaders .clear (); // we clear at the beginning; to allow to retrieve the header information in a subsequent call
241242 T* ptr = nullptr ;
@@ -258,18 +259,45 @@ T* CCDBManagerInstance::getForTimeStamp(std::string const& path, long timestamp,
258259 mFetchedSize += s;
259260 }
260261 }
262+ if (!headerFilter.empty ()) {
263+ LOGP (warn, " Header filter ignored when caching is disabled, giving back all headers" );
264+ }
265+ if (headers) {
266+ *headers = mHeaders ;
267+ }
261268 } else {
262269 auto & cached = mCache [path];
263270 cached.queries ++;
264271 if ((!isOnline () && cached.isCacheValid (timestamp)) || (mCheckObjValidityEnabled && cached.isValid (timestamp))) {
272+ // Give back the cached/saved headers
265273 if (headers) {
266- *headers = mHeaders ;
274+ *headers = cached. cacheOfHeaders ;
267275 }
268276 return reinterpret_cast <T*>(cached.noCleanupPtr ? cached.noCleanupPtr : cached.objPtr .get ());
269277 }
270278 ptr = mCCDBAccessor .retrieveFromTFileAny <T>(path, mMetaData , timestamp, &mHeaders , cached.uuid ,
271279 mCreatedNotAfter ? std::to_string (mCreatedNotAfter ) : " " ,
272280 mCreatedNotBefore ? std::to_string (mCreatedNotBefore ) : " " );
281+
282+ // Cache the headers
283+ if (headerFilter.empty ()) {
284+ // No filter, cache all headers
285+ for (auto const & h : mHeaders ) {
286+ cached.cacheOfHeaders [h.first ] = h.second ;
287+ }
288+ } else {
289+ // Cache only the asked for headers
290+ for (auto const & k : headerFilter) {
291+ auto it = mHeaders .find (std::string (k));
292+ if (it != mHeaders .end ()) {
293+ cached.cacheOfHeaders .insert_or_assign (it->first , it->second ); // Only want to overwrite if the header exists in the source
294+ }
295+ }
296+ }
297+ if (headers) {
298+ *headers = cached.cacheOfHeaders ;
299+ }
300+
273301 if (ptr) { // new object was shipped, old one (if any) is not valid anymore
274302 cached.fetches ++;
275303 mFetches ++;
@@ -303,7 +331,7 @@ T* CCDBManagerInstance::getForTimeStamp(std::string const& path, long timestamp,
303331 size_t s = atol (sh->second .c_str ());
304332 mFetchedSize += s;
305333 cached.minSize = std::min (s, cached.minSize );
306- cached.maxSize = std::max (s, cached.minSize );
334+ cached.maxSize = std::max (s, cached.minSize ); // I think this should be maxSize, not minSize
307335 }
308336 } else if (mHeaders .count (" Error" )) { // in case of errors the pointer is 0 and headers["Error"] should be set
309337 cached.failures ++;
@@ -324,9 +352,6 @@ T* CCDBManagerInstance::getForTimeStamp(std::string const& path, long timestamp,
324352 mFailures ++;
325353 }
326354 }
327- if (headers) {
328- *headers = mHeaders ; // Do a deep copy of the headers
329- }
330355 auto end = std::chrono::system_clock::now ();
331356 mTimerMS += std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count ();
332357 return ptr;
0 commit comments