17#include <TDataMember.h>
20#include <TEnumConstant.h>
25#include <fairlogger/Logger.h>
26#include <boost/property_tree/ptree.hpp>
27#include <boost/functional/hash.hpp>
42 std::ostringstream out;
48 size_t len =
label.size() - prefix.size() - 5;
54 out <<
"[ " + prov +
" ]";
56 out <<
"\t\t[ " + prov +
" ]";
64 out << pdm.
toString(
"",
false) <<
"\n";
72 return strcmp(dm.GetTrueTypeName(),
"string") == 0;
80 std::function<
void(
const TDataMember*,
int,
int)>&& callback)
82 auto memberlist = cl->GetListOfDataMembers();
83 for (
int i = 0;
i < memberlist->GetEntries(); ++
i) {
84 auto dm = (TDataMember*)memberlist->At(
i);
86 auto isValidComplex = [dm]() {
87 return isString(*dm) || dm->IsEnum();
91 if (dm->Property() & kIsStatic) {
95 if (dm->IsaPointer()) {
96 LOG(warning) <<
"Pointer types not supported in ConfigurableParams: " << dm->GetFullTypeName() <<
" " << dm->GetName();
99 if (!dm->IsBasic() && !isValidComplex()) {
100 LOG(warning) <<
"Generic complex types not supported in ConfigurableParams: " << dm->GetFullTypeName() <<
" " << dm->GetName();
104 const auto dim = dm->GetArrayDim();
107 LOG(warning) <<
"We support at most 1 dimensional arrays in ConfigurableParams: " << dm->GetFullTypeName() <<
" " << dm->GetName();
111 const auto size = (dim == 1) ? dm->GetMaxIndex(dim - 1) : 1;
123 std::stringstream namestream;
124 namestream << dm->GetName();
126 namestream <<
"[" <<
index <<
"]";
128 return namestream.str();
134 auto dt = dm.GetDataType();
140 auto tname = dm.GetFullTypeName();
141 if (strcmp(tname,
"string") == 0 || strcmp(tname,
"std::string")) {
142 return sizeof(std::string);
144 LOG(error) <<
"ENCOUNTERED AN UNSUPPORTED TYPE " << tname <<
"IN A CONFIGURABLE PARAMETER";
155 if (
auto dt = dm.GetDataType()) {
158 if (dt->GetType() == EDataType::kChar_t) {
161 }
else if (dt->GetType() == EDataType::kUChar_t) {
171 const auto enumtype = TEnum::GetEnum(dm.GetTypeName());
172 assert(enumtype !=
nullptr);
173 const auto constantlist = enumtype->GetConstants();
174 assert(constantlist !=
nullptr);
176 for (
int i = 0;
i < constantlist->GetEntries(); ++
i) {
177 const auto e = (TEnumConstant*)(constantlist->At(
i));
179 return std::string(e->GetName());
185 return std::string(
val);
190 return ((std::string*)
pointer)->c_str();
194 LOG(error) <<
"COULD NOT REPRESENT AS STRING";
195 return std::string();
200std::vector<ParamDataMember>* _ParamHelper::getDataMembersImpl(std::string
const& mainkey, TClass* cl,
void* obj,
201 std::map<std::string, ConfigurableParam::EParamProvenance>
const* provmap,
size_t globaloffset)
203 std::vector<ParamDataMember>* members =
new std::vector<ParamDataMember>;
205 auto toDataMember = [&members, obj, mainkey, provmap, globaloffset](
const TDataMember* dm,
int index,
int size) {
207 char*
pointer = ((
char*)obj) + dm->GetOffset() +
index * TS + globaloffset;
211 std::string prov =
"";
212 auto iter = provmap->find(mainkey +
"." +
name);
213 if (iter != provmap->end()) {
217 members->push_back(member);
233 switch (dt->GetType()) {
238 return typeid(
unsigned char);
241 return typeid(
short);
244 return typeid(
unsigned short);
250 return typeid(
unsigned int);
256 return typeid(
unsigned long);
259 return typeid(float);
262 return typeid(double);
265 return typeid(double);
271 return typeid(
long long);
274 return typeid(
unsigned long long);
282 if (strcmp(tname,
"string") == 0 || strcmp(tname,
"std::string")) {
283 return typeid(std::string);
285 LOG(error) <<
"ENCOUNTERED AN UNSUPPORTED TYPE " << tname <<
"IN A CONFIGURABLE PARAMETER";
286 return typeid(
"ERROR");
291void _ParamHelper::fillKeyValuesImpl(std::string
const& mainkey, TClass* cl,
void* obj, boost::property_tree::ptree*
tree,
292 std::map<std::string, std::pair<std::type_info const&, void*>>* keytostoragemap,
295 boost::property_tree::ptree localtree;
296 auto fillMap = [obj, &mainkey, &localtree, &keytostoragemap, &enumRegistry, globaloffset](
const TDataMember* dm,
int index,
int size) {
298 auto dt = dm->GetDataType();
300 char*
pointer = ((
char*)obj) + dm->GetOffset() +
index * TS + globaloffset;
303 auto key = mainkey +
"." +
name;
308 enumRegistry->
add(
key, dm);
311 using mapped_t = std::pair<std::type_info const&, void*>;
313 keytostoragemap->insert(std::pair<std::string, mapped_t>(
key, mapped_t(ti,
pointer)));
316 tree->add_child(mainkey, localtree);
321void _ParamHelper::printMembersImpl(std::string
const& mainkey, std::vector<ParamDataMember>
const* members,
bool showProv,
bool useLogger,
bool withPadding,
bool showHash)
324 _ParamHelper::outputMembersImpl(std::cout, mainkey, members, showProv, useLogger, withPadding, showHash);
327void _ParamHelper::outputMembersImpl(std::ostream& out, std::string
const& mainkey, std::vector<ParamDataMember>
const* members,
bool showProv,
bool useLogger,
bool withPadding,
bool showHash)
329 if (members ==
nullptr) {
335 for (
auto& member : *members) {
336 maxpad = std::max(maxpad, member.name.size() + member.value.size());
341 std::string shash = std::format(
"{:07x}", getHashImpl(mainkey, members));
342 shash = shash.substr(0, 7);
344 LOG(info) << mainkey <<
" [Hash#" << shash <<
"]";
346 out << mainkey <<
" [Hash#" << shash <<
"]\n";
350 for (
auto& member : *members) {
352 LOG(info) << member.toString(mainkey, showProv, maxpad);
354 out << member.toString(mainkey, showProv, maxpad) <<
"\n";
359size_t _ParamHelper::getHashImpl(std::string
const& mainkey, std::vector<ParamDataMember>
const* members)
362 boost::hash_combine(hash, mainkey);
363 for (
auto& member : *members) {
364 boost::hash_combine(hash, member.value);
374 for (
int i = 0;
i < sizeinbytes /
sizeof(
char); ++
i) {
375 if (block1[
i] != block2[
i]) {
384void _ParamHelper::assignmentImpl(std::string
const& mainkey, TClass* cl,
void* to,
void* from,
385 std::map<std::string, ConfigurableParam::EParamProvenance>* provmap,
size_t globaloffset)
387 auto assignifchanged = [to, from, &mainkey, provmap, globaloffset](
const TDataMember* dm,
int index,
int size) {
389 auto dt = dm->GetDataType();
391 char* pointerto = ((
char*)to) + dm->GetOffset() +
index * TS + globaloffset;
392 char* pointerfrom = ((
char*)from) + dm->GetOffset() +
index * TS + globaloffset;
395 auto updateProv = [&mainkey,
name, provmap]() {
396 auto key = mainkey +
"." +
name;
397 auto iter = provmap->find(
key);
398 if (iter != provmap->end()) {
401 LOG(warn) <<
"KEY " <<
key <<
" NOT FOUND WHILE UPDATING PARAMETER PROVENANCE";
410 std::string&
target = *(std::string*)pointerto;
411 std::string
const&
origin = *(std::string*)pointerfrom;
412 if (
target.compare(origin) != 0) {
431void _ParamHelper::syncCCDBandRegistry(
const std::string& mainkey, TClass* cl,
void* to,
void* from,
432 std::map<std::string, ConfigurableParam::EParamProvenance>* provmap,
size_t globaloffset)
434 auto sync = [to, from, &mainkey, provmap, globaloffset](
const TDataMember* dm,
int index,
int size) {
436 auto dt = dm->GetDataType();
438 char* pointerto = ((
char*)to) + dm->GetOffset() +
index * TS + globaloffset;
439 char* pointerfrom = ((
char*)from) + dm->GetOffset() +
index * TS + globaloffset;
442 auto key = mainkey +
"." +
name;
443 auto proviter = provmap->find(
key);
449 auto updateProv = [&proviter]() {
455 std::string&
target = *(std::string*)pointerto;
456 std::string
const&
origin = *(std::string*)pointerfrom;
476void _ParamHelper::printWarning(std::type_info
const& tinfo)
478 LOG(warning) <<
"Registered parameter class with name " << tinfo.name()
479 <<
" has no ROOT dictionary and will not be available in the configurable parameter system";
size_t getSizeOfUnderlyingType(const TDataMember &dm)
void loopOverMembers(TClass *cl, void *obj, std::function< void(const TDataMember *, int, int)> &&callback)
std::string getName(const TDataMember *dm, int index, int size)
std::string asString(TDataMember const &dm, char *pointer)
bool isString(TDataMember const &dm)
std::type_info const & nameToTypeInfo(const char *tname, TDataType const *dt)
static std::string toString(EParamProvenance p)
void add(const std::string &key, const TDataMember *dm)
GLuint const GLchar * name
GLsizei const GLfloat * value
GLuint GLsizei const GLchar * label
GLenum GLenum GLsizei len
consteval header::DataOrigin origin()
bool isMemblockDifferent(void const *block1, void const *block2)
std::ostream & operator<<(std::ostream &out, ConfigurableParam const ¶m)
std::string to_string(gsl::span< T, Size > span)
std::string toString(std::string const &prefix, bool showProv, size_t padding=0) const
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))