11#include "CrestApi/CrestApi.h"
12#include "CrestApi/CrestApiFs.h"
13#include "CoralBase/AttributeList.h"
14#include "CoralBase/Attribute.h"
15#include "CoolKernel/StorageType.h"
16#include "CoolKernel/RecordSpecification.h"
17#include "CoolKernel/Record.h"
22#include "GaudiKernel/MsgStream.h"
23#include "GaudiKernel/SystemOfUnits.h"
24#include <chai/Converter.h>
25#include <chai/Types.h>
34 const std::map<chai::Type, cool::StorageType::TypeId> coolTypeForChaiType={
35 {chai::Bool, cool::StorageType::Bool},
36 {chai::UInt8, cool::StorageType::UChar},
37 {chai::Int16, cool::StorageType::Int16},
38 {chai::UInt16, cool::StorageType::UInt16},
39 {chai::Int32, cool::StorageType::Int32},
40 {chai::UInt32, cool::StorageType::UInt32},
41 {chai::UInt64, cool::StorageType::UInt63},
42 {chai::Int64, cool::StorageType::Int64},
43 {chai::Float, cool::StorageType::Float},
44 {chai::Double, cool::StorageType::Double},
45 {chai::String, cool::StorageType::String16M},
46 {chai::Blob, cool::StorageType::Blob128M}
55 const std::type_info * coralTypeFor(chai::Type
type){
58 if (
type == chai::Int8)
return &
typeid(
char);
59 auto it = coolTypeForChaiType.find(
type);
60 if (it == coolTypeForChaiType.end())
return nullptr;
61 return &cool::StorageType::storageType(
it->second).cppType();
64 const std::string colonDelimiter{
" : "};
68 if(crest_path.length()==0)
71 m_crestCl = std::make_unique<Crest::CrestApi>(Crest::CrestApi(crest_path));
74 m_crestCl = std::make_unique<Crest::CrestApiFs>(Crest::CrestApiFs(false,crest_path));
79 std::unique_ptr<Crest::CrestApiBase> crestCl;
81 crestCl.reset(
new Crest::CrestApi(crest_path));
84 crestCl.reset(
new Crest::CrestApiFs(
true,crest_path));
86 std::map<std::string, std::string> tagmap;
88 Crest::GlobalTagMapSetDto dto = crestCl->findGlobalTagMap(globaltag,
"Trace");
89 for (
const auto &tagMapDto : dto.getResources()){
90 tagmap[tagMapDto.getLabel()]=tagMapDto.getTagName();
92 }
catch (std::exception & e){
94 gLog << MSG::ERROR << __FILE__<<
":"<<__LINE__<<
": " << e.what() <<
" Cannot get a global tag map for " << globaltag<<
endmsg;
100 std::string regex=R
"delim(<typeName>\s*([^\s]+)\s*</typeName>)delim";
101 std::regex re(regex);
102 std::smatch typeMatch;
104 return (
match) ? std::string(typeMatch[1]) : std::string(
"");
109 std::string folderDescription = info.getFolderDescription();
111 const std::string typeName =
parseTypeName(folderDescription);
112 if (typeName==
"CondAttrListVec"){
117 std::vector< std::pair<std::string,std::string> > spec= info.getPayloadSpec().getColumns();
118 std::vector< std::pair<std::string,std::string> > chs = info.getChannels().getChannels();
119 for (
auto &p : spec){
122 if(p.first==
"PoolRef" && chai::typeFromString(p.second)==chai::String){
123 int id=std::stoll(chs[0].first);
124 if(chs.size()==1 &&
id==0)
147 }
catch (std::exception & e){
149 gLog << MSG::ERROR << __FILE__<<
":"<<__LINE__<<
": " << e.what() <<
" Cannot get a tag meta info " <<
m_crestTag<<
endmsg;
157 return m_TagMeta.value().getTagInfoDto();
161 if(!
m_Tag.has_value()){
164 return m_Tag.value();
173 return info.getFolderDescription();
180 std::vector<cool::ChannelId> list;
181 std::vector<std::string> names;
182 std::vector< std::pair<std::string,std::string> >
res = info.getChannels().getChannels();
184 list.push_back(std::stoll(p.first));
185 names.push_back(p.second);
187 return std::make_pair(std::move(list), std::move(names));
192 std::vector< std::pair<std::string,std::string> > spec_vec= info.getPayloadSpec().getColumns();
193 auto * spec =
new coral::AttributeListSpecification();
194 for (
auto &p : spec_vec){
195 const std::type_info * coralType = coralTypeFor(chai::typeFromString(p.second));
196 if (coralType ==
nullptr){
201 const std::string errorMessage(
"Unsupported type \"" + p.second +
"\" for payload spec column \"" + p.first +
"\" of CREST tag " +
m_crestTag);
203 gLog << MSG::ERROR <<
"getAttributeListSpec: " << errorMessage <<
endmsg;
204 throw std::runtime_error(errorMessage);
206 spec->extend(p.first,*coralType);
216 const std::string & objectType = tag.getObjectType();
217 if(objectType==
"crest-json-multi-iov-sparse"){
220 else if(objectType==
"crest-json-multi-iov"){
226 const bool multiChannel = info.getChannels().getChannels().size() > 1;
232 std::pair<uint64_t,uint64_t>
234 uint64_t new_since = 0;
235 uint64_t new_until = 0;
239 gLog << MSG::ERROR <<
"Wrong since/until."<<
endmsg;
240 return std::make_pair(0,0);
242 const std::size_t N = v.size();
245 if(v[i] <= since && since < v[i+1]){
252 if(v[i] < until && until <= v[i+1]){
258 return std::make_pair(new_since,new_until);
261 std::pair<uint64_t,uint64_t>
263 Crest::IovSetDto dto =
m_crestCl->selectGroups(tag, 0, 10000, 0,
"id.since:ASC");
264 std::vector<uint64_t> v = dto.getListSince();
265 v.push_back(cool::ValidityKeyMax);
272 std::vector<std::pair<cool::ValidityKey,std::string>>
res;
273 Crest::IovSetDto dto;
274 if(iovNumber <=1000){
279 uint64_t s_time = ppt.first;
280 uint64_t u_time = ppt.second;
282 if (s_time == 0 && u_time == 0){
289 for (
auto &p : dto.getResources()){
290 res.push_back(std::make_pair((cool::ValidityKey)p.getSince(),p.getPayloadHash()));
301 }
catch (std::exception & e){
303 gLog << MSG::ERROR << __FILE__<<
":"<<__LINE__<<
": "<<e.what()<<
" while trying to find the payload"<<
endmsg;
304 throw std::runtime_error(e.what());
308 nlohmann::json j_spec=info.getPayloadSpec().toJson();
309 nlohmann::json j_chs=info.getChannels().toJson();
310 chai::PayloadSpec chaiSpec(j_spec,j_chs);
311 nlohmann::json j = reply;
315 ss >> std::quoted(st);
321 std::shared_ptr<chai::VectorContainer> cont = std::make_shared<chai::VectorContainer>(chai::VectorContainer::fromJson(j,chaiSpec));
322 m_chai_cont->insert(std::pair<uint64_t,chai::ContainerBasePtr>(since,cont));
325 std::shared_ptr<chai::Container> cont = std::make_shared<chai::Container>(chai::Container::fromJson(j,chaiSpec));
326 m_chai_cont->insert(std::pair<uint64_t,chai::ContainerBasePtr>(since,cont));
328 std::vector<uint64_t>
res;
333 std::unique_ptr<chai::ClobMultiIovConverter> converter;
335 converter = std::make_unique<chai::JsonMultiIovSparseConverter>(chaiSpec);
337 converter = std::make_unique<chai::JsonMultiIovConverter>(chaiSpec);
338 std::unique_ptr<chai::ContainerMapBase> chai_map_cont = converter->deserialize(j.dump());
339 std::vector<uint64_t>
res=chai_map_cont->keys();
340 for(
auto const& key:
res){
341 chai::ConstContainerPtr const_cont = chai_map_cont->getContainer(key);
348 chai::ContainerPtr cont
ATLAS_THREAD_SAFE = std::const_pointer_cast<chai::Container>(const_cont);
349 m_chai_cont->insert(std::pair<uint64_t,chai::ContainerBasePtr>(key,cont));
353 }
catch (std::exception & e){
355 gLog << MSG::ERROR <<
"LoadPayloadForHash:"<<e.what()<<
" while trying to parse the payload. Since="<<since<<
", hash="<<hash<<
endmsg;
356 throw std::runtime_error(e.what());
362 std::vector<std::string> chIds=
channelIds(since);
364 std::stringstream
res;
368 for (
auto &ch : chIds){
377 for (
const auto & vitr:attr){
388 coral::AttributeList attr=
getPayload(pspec,ch);
394 coral::AttributeList attr=
getPayload(pspec,ch);
395 std::ostringstream os;
396 attr[0].toOutputStream(os);
398 const auto separatorPosition =
str.find(colonDelimiter);
399 const std::string payloadOnly=
str.substr(separatorPosition+3);
400 res<<
"\""<<payloadOnly<<
"\"";
407 res<<
" a_data_value";
409 if (sep.empty()) sep=
",";
419 std::string errorMessage(
"Timestamp not found! timestamp=" + std::to_string(
m_since));
421 gLog << MSG::ERROR <<
"getPayload:" <<errorMessage<<
endmsg;
422 throw std::runtime_error(errorMessage);
424 uint64_t
id = std::stoul(chId);
425 chai::Container* cont2 =
dynamic_cast<chai::Container*
>(cont.get());
426 chai::Values& row = cont2->at(
id);
432 std::vector<coral::AttributeList>
res;
433 uint64_t
id = std::stoul(chId);
436 std::string errorMessage(
"Timestamp not found! timestamp=" + std::to_string(
m_since));
438 gLog << MSG::ERROR <<
"getPayload:" <<errorMessage<<
endmsg;
439 throw std::runtime_error(errorMessage);
441 chai::VectorContainer* cont2 =
dynamic_cast<chai::VectorContainer*
>(cont.get());
442 const std::vector<chai::ValuesPtr>& rows = cont2->rows(
id);
443 for (
auto &row : rows){
444 chai::Values* val = row.get();
457 std::vector<std::string> chIds;
458 std::vector<uint64_t> channels;
459 chai::ContainerBasePtr cont=
m_chai_cont->operator[](since);
462 if(chai::Container* v =
dynamic_cast<chai::Container*
>(cont.get()))
463 channels=v->channelIds();
464 else if(chai::VectorContainer* v =
dynamic_cast<chai::VectorContainer*
>(cont.get()))
465 channels=v->channelIds();
479 for (
auto id : channels) {
482 chIds.push_back(std::to_string(
id));
488 coral::AttributeList attr(*pSpec,
true);
489 unsigned int s=attr.size();
490 for (
unsigned int i(0);i!=s;++i){
498 chai::Type
type = row.type(att.specification().name());
502 att.setValue<
bool>(row.get<
bool>(att.specification().name()));
507 att.setValue<
char>(row.get<int8_t>(att.specification().name()));
512 att.setValue<
unsigned char>(row.get<uint8_t>(att.specification().name()));
517 att.setValue<
unsigned short>(row.get<uint16_t>(att.specification().name()));
522 att.setValue<
short>(row.get<int16_t>(att.specification().name()));
527 att.setValue<
unsigned int>(row.get<uint32_t>(att.specification().name()));
532 att.setValue<
int>(row.get<int32_t>(att.specification().name()));
537 att.setValue<
unsigned long long>(row.get<uint64_t>(att.specification().name()));
542 att.setValue<
long long>(row.get<int64_t>(att.specification().name()));
547 att.setValue<
float>(row.get<
float>(att.specification().name()));
552 att.setValue<
double>(row.get<
double>(att.specification().name()));
557 att.setValue<std::string>(row.get<std::string>(att.specification().name()));
562 const auto &charVec = row.get<chai::BlobData>(att.specification().name()).m_bytes;
563 coral::Blob blob(charVec.size());
564 if (!charVec.empty()) {
565 memcpy(blob.startingAddress(), charVec.data(), charVec.size());
567 att.setValue<coral::Blob>(blob);
572 std::string errorMessage(
"UNTREATED TYPE! " + std::to_string(
type));
574 gLog << MSG::ERROR <<
"LoadPayloadForHash:" <<errorMessage<<
endmsg;
575 throw std::runtime_error(errorMessage);
Header for CoralCrestManager class.
std::pair< std::vector< unsigned int >, bool > res
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
static std::map< std::string, std::string > getGlobalTagMap(const std::string &crest_path, const std::string &globaltag)
std::vector< std::pair< cool::ValidityKey, std::string > > getIovsForTag(uint64_t since, uint64_t until)
std::vector< std::string > channelIds(cool::ValidityKey since)
coral::AttributeList createAttributeList(coral::AttributeListSpecification *pSpec, chai::Values &row)
IOVDbNamespace::FolderType determineFolderType()
std::optional< std::map< uint64_t, chai::ContainerBasePtr > > m_chai_cont
std::vector< uint64_t > loadPayloadForHash(uint64_t since, const std::string &hash)
std::string dumpPayload(cool::ValidityKey since)
Crest::TagDto & getTagDto()
std::vector< coral::AttributeList > getVectorPayload(coral::AttributeListSpecification *pSpec, const std::string &chId)
std::optional< Crest::TagMetaDto > m_TagMeta
std::string getFolderDescription()
cool::ValidityKey m_since
std::optional< bool > m_isVectorPayload
std::optional< Crest::TagDto > m_Tag
std::string parseTypeName(const std::string &description)
CoralCrestManager(const std::string &crest_path, const std::string &crestTag)
static const std::string prefix1
std::pair< uint64_t, uint64_t > getIovInterval(const std::string &tag, const uint64_t since, const uint64_t until)
std::string getPayloadSpec()
std::pair< std::vector< cool::ChannelId >, std::vector< std::string > > getChannelList()
coral::AttributeList getPayload(coral::AttributeListSpecification *pSpec, const std::string &chId)
std::pair< uint64_t, uint64_t > getSinceUntilPair(std::vector< uint64_t > &v, const uint64_t since, const uint64_t until)
std::unique_ptr< Crest::CrestApiBase > m_crestCl
Crest::TagInfoDto getTagInfoDto()
coral::AttributeListSpecification * getAttributeListSpec()
static const std::string prefix2
const std::string m_crestTag
void selectIov(cool::ValidityKey since)
singleton-like access to IMessageSvc via open function and helper
std::string description
glabal timer - how long have I taken so far?
bool match(std::string s1, std::string s2)
match the individual directories of two strings
IMessageSvc * getMessageSvc(bool quiet=false)
std::string jsonAttributeList(const coral::AttributeList &atrlist)
Produce a representation of a coral::AttributeList as a json string.
static const std::string s_delimiterJson
json standard delimiter ', '
static const std::string s_closeJson
json close tag, '}'
static const std::string s_openJson
json open tag, '{'