Skip to content

Commit b6ccc25

Browse files
committed
Extend CCDB functions with optional headers
1 parent 9c91409 commit b6ccc25

File tree

5 files changed

+446
-10
lines changed

5 files changed

+446
-10
lines changed

CCDB/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ o2_add_test(CcdbDownloader
9292
PUBLIC_LINK_LIBRARIES O2::CCDB
9393
LABELS ccdb)
9494

95+
o2_add_test(CcdbApi-Headers
96+
SOURCES test/testCcdbApiHeaders.cxx
97+
COMPONENT_NAME ccdb
98+
PUBLIC_LINK_LIBRARIES O2::CCDB
99+
LABELS ccdb)
100+
95101
# extra CcdbApi test which dispatches to CCDBDownloader (tmp until full move done)
96102
#o2_add_test_command(NAME CcdbApi-MultiHandle
97103
# WORKING_DIRECTORY ${SIMTESTDIR}

CCDB/include/CCDB/BasicCCDBManager.h

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@
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

3032
class 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
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);
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

237238
template <typename T>
238-
T* CCDBManagerInstance::getForTimeStamp(std::string const& path, long timestamp)
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,15 +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
273+
if (headers) {
274+
*headers = cached.cacheOfHeaders;
275+
}
265276
return reinterpret_cast<T*>(cached.noCleanupPtr ? cached.noCleanupPtr : cached.objPtr.get());
266277
}
267278
ptr = mCCDBAccessor.retrieveFromTFileAny<T>(path, mMetaData, timestamp, &mHeaders, cached.uuid,
268279
mCreatedNotAfter ? std::to_string(mCreatedNotAfter) : "",
269280
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+
270301
if (ptr) { // new object was shipped, old one (if any) is not valid anymore
271302
cached.fetches++;
272303
mFetches++;
@@ -300,7 +331,7 @@ T* CCDBManagerInstance::getForTimeStamp(std::string const& path, long timestamp)
300331
size_t s = atol(sh->second.c_str());
301332
mFetchedSize += s;
302333
cached.minSize = std::min(s, cached.minSize);
303-
cached.maxSize = std::max(s, cached.minSize);
334+
cached.maxSize = std::max(s, cached.minSize); // I think this should be maxSize, not minSize
304335
}
305336
} else if (mHeaders.count("Error")) { // in case of errors the pointer is 0 and headers["Error"] should be set
306337
cached.failures++;

CCDB/include/CCDB/CcdbApi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ class CcdbApi //: public DatabaseInterface
281281
* @return: True in case operation successful or false if there was a failure/problem.
282282
*/
283283
bool retrieveBlob(std::string const& path, std::string const& targetdir, std::map<std::string, std::string> const& metadata, long timestamp,
284-
bool preservePathStructure = true, std::string const& localFileName = "snapshot.root", std::string const& createdNotAfter = "", std::string const& createdNotBefore = "") const;
284+
bool preservePathStructure = true, std::string const& localFileName = "snapshot.root", std::string const& createdNotAfter = "", std::string const& createdNotBefore = "", std::map<std::string, std::string>* headers = nullptr) const;
285285

286286
/**
287287
* Retrieve the headers of a CCDB entry, if it exists.

CCDB/src/CcdbApi.cxx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,7 @@ TObject* CcdbApi::retrieveFromTFile(std::string const& path, std::map<std::strin
831831
}
832832

833833
bool CcdbApi::retrieveBlob(std::string const& path, std::string const& targetdir, std::map<std::string, std::string> const& metadata,
834-
long timestamp, bool preservePath, std::string const& localFileName, std::string const& createdNotAfter, std::string const& createdNotBefore) const
834+
long timestamp, bool preservePath, std::string const& localFileName, std::string const& createdNotAfter, std::string const& createdNotBefore, std::map<std::string, std::string>* outHeaders) const
835835
{
836836

837837
// we setup the target path for this blob
@@ -879,6 +879,9 @@ bool CcdbApi::retrieveBlob(std::string const& path, std::string const& targetdir
879879
CCDBQuery querysummary(path, metadata, timestamp);
880880

881881
updateMetaInformationInLocalFile(targetpath.c_str(), &headers, &querysummary);
882+
if (outHeaders) {
883+
*outHeaders = std::move(headers); // Re-use the same headers to give back to the callee
884+
}
882885
return true;
883886
}
884887

0 commit comments

Comments
 (0)