1 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationBase.h"
2 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationInfoReader.h"
12 #define __MF_SUBJECT__ "ConfigurationBase"
14 #define __MF_HDR__ __COUT_HDR_FL__ << getConfigurationName() << ": "
22 ConfigurationBase::ConfigurationBase(std::string configurationName,
23 std::string *accumulatedExceptions)
24 : MAX_VIEWS_IN_CACHE (5)
25 , configurationName_ (configurationName)
26 , activeConfigurationView_(0)
32 std::string returnedExceptions = configurationInfoReader.read(
this);
34 if(returnedExceptions !=
"")
35 __MOUT_ERR__ << returnedExceptions << std::endl;
37 if(accumulatedExceptions) *accumulatedExceptions += std::string(
"\n") + returnedExceptions;
41 __SS__ <<
"Failure in configurationInfoReader.read(this)" << std::endl;
42 __MOUT_ERR__ <<
"\n" << ss.str();
43 if(accumulatedExceptions) *accumulatedExceptions += std::string(
"\n") +
52 getMockupViewP()->init();
54 catch(std::runtime_error& e)
56 if(accumulatedExceptions) *accumulatedExceptions += std::string(
"\n") + e.what();
65 ConfigurationBase::ConfigurationBase(
void)
66 : MAX_VIEWS_IN_CACHE (1)
67 , configurationName_ (
"")
68 , activeConfigurationView_(0)
73 ConfigurationBase::~ConfigurationBase(
void)
78 std::string ConfigurationBase::getTypeId()
80 return typeid(
this).name();
90 void ConfigurationBase::reset(
bool keepTemporaryVersions)
94 if(keepTemporaryVersions)
97 configurationViews_.clear();
101 void ConfigurationBase::print(std::ostream &out)
const
104 if(!activeConfigurationView_)
106 __MOUT_ERR__ <<
"ERROR: No active view set" << std::endl;
109 activeConfigurationView_->print(out);
117 if(!isStored(version))
119 configurationViews_[version].copy(mockupConfigurationView_,
121 mockupConfigurationView_.getAuthor());
123 if(!isStored(version))
125 __SS__ <<
"\nsetupMockupView() IMPOSSIBLE ERROR: trimCache() is deleting the latest view version " <<
126 version <<
"!" << std::endl;
127 __MOUT_ERR__ <<
"\n" << ss.str();
128 throw std::runtime_error(ss.str());
133 __SS__ <<
"\nsetupMockupView() ERROR: View to fill with mockup already exists: " << version
134 <<
". Cannot overwrite!" << std::endl;
135 __MOUT_ERR__ <<
"\n" << ss.str();
136 throw std::runtime_error(ss.str());
146 void ConfigurationBase::trimCache(
unsigned int trimSize)
150 if(trimSize == (
unsigned int)-1)
151 trimSize = MAX_VIEWS_IN_CACHE;
154 while(getNumberOfStoredViews() > trimSize)
157 time_t stalestTime = -1;
159 for(
auto &viewPair : configurationViews_)
160 if(!viewPair.first.isTemporaryVersion())
162 if(stalestTime == -1 ||
163 viewPair.second.getLastAccessTime() < stalestTime)
165 versionToDelete = viewPair.first;
166 stalestTime = viewPair.second.getLastAccessTime();
171 if(versionToDelete.isInvalid())
173 __SS__ <<
"Can NOT have a stored view with an invalid version!";
174 throw std::runtime_error(ss.str());
177 eraseView(versionToDelete);
188 if(targetVersion.isInvalid())
190 for(
auto it = configurationViews_.begin(); it != configurationViews_.end(); )
192 if(it->first.isTemporaryVersion())
194 __MOUT__ <<
"Trimming temporary version: " << it->first << std::endl;
195 if(activeConfigurationView_ &&
196 getViewVersion() == it->first)
198 configurationViews_.erase(it++);
204 else if(targetVersion.isTemporaryVersion())
206 __MOUT__ <<
"Trimming temporary version: " << targetVersion << std::endl;
207 eraseView(targetVersion);
212 __SS__ <<
"Temporary trim target was a persistent version: " <<
213 targetVersion << std::endl;
214 __MOUT_ERR__ <<
"\n" << ss.str();
215 throw std::runtime_error(ss.str());
231 auto needleIt = configurationViews_.find(needleVersion);
232 if(needleIt == configurationViews_.end())
235 __SS__ <<
"needleVersion does not exist: " <<
236 needleVersion << std::endl;
237 __MOUT_ERR__ <<
"\n" << ss.str();
238 throw std::runtime_error(ss.str());
242 unsigned int rows = needleView->getNumberOfRows();
243 unsigned int cols = needleView->getNumberOfColumns();
248 for(
auto &viewPair: configurationViews_)
250 if(viewPair.first == needleVersion)
continue;
251 if(viewPair.first == ignoreVersion)
continue;
253 if(viewPair.second.getNumberOfRows() != rows)
256 if(viewPair.second.getDataColumnSize() != cols ||
257 viewPair.second.getSourceColumnMismatch() != 0)
263 auto srcColNameIt = viewPair.second.getSourceColumnNames().begin();
264 for(
unsigned int col=0; match &&
265 viewPair.second.getSourceColumnNames().size() > 3 &&
266 col<viewPair.second.getSourceColumnNames().size()-3;++col,srcColNameIt++)
268 needleView->getColumnsInfo()[col].getName())
271 for(
unsigned int row=0;match && row<rows;++row)
273 for(
unsigned int col=0;col<cols-2;++col)
274 if(viewPair.second.getDataView()[row][col] !=
275 needleView->getDataView()[row][col])
276 { match =
false;
break; }
280 __MOUT_INFO__ <<
"Duplicate version found: " << viewPair.first << std::endl;
281 return viewPair.first;
292 if(configurationViews_.find(temporaryVersion) == configurationViews_.end())
294 __SS__ <<
"ERROR: Temporary view version " << temporaryVersion <<
" doesn't exists!" << std::endl;
295 __MOUT_ERR__ <<
"\n" << ss.str();
296 throw std::runtime_error(ss.str());
298 if(version.isInvalid())
300 __SS__ <<
"ERROR: Attempting to create an invalid version " << version <<
301 "! Did you really run out of versions? (this should never happen)" << std::endl;
302 __MOUT_ERR__ <<
"\n" << ss.str();
303 throw std::runtime_error(ss.str());
306 if(configurationViews_.find(version) != configurationViews_.end())
307 __MOUT_WARN__ <<
"WARNING: View version " << version <<
" already exists! Overwriting." << std::endl;
309 configurationViews_[version].copy(configurationViews_[temporaryVersion],
311 configurationViews_[temporaryVersion].getAuthor());
312 setActiveView(version);
313 eraseView(temporaryVersion);
319 return (configurationViews_.find(version) != configurationViews_.end());
325 if(!isStored(version))
328 if(activeConfigurationView_ &&
329 getViewVersion() == version)
332 configurationViews_.erase(version);
338 const std::string& ConfigurationBase::getConfigurationName(
void)
const
340 return configurationName_;
344 const std::string& ConfigurationBase::getConfigurationDescription(
void)
const
346 return configurationDescription_;
352 return getView().getVersion();
359 bool ConfigurationBase::latestAndMockupColumnNumberMismatch(
void)
const
361 std::set<ConfigurationVersion> retSet = getStoredVersions();
362 if(retSet.size() && !retSet.rbegin()->isTemporaryVersion())
364 return configurationViews_.find(*(retSet.rbegin()))->second.getNumberOfColumns() !=
365 mockupConfigurationView_.getNumberOfColumns();
372 std::set<ConfigurationVersion> ConfigurationBase::getStoredVersions(
void)
const
374 std::set<ConfigurationVersion> retSet;
375 for(
auto &configs:configurationViews_)
376 retSet.emplace(configs.first);
384 unsigned int ConfigurationBase::getNumberOfStoredViews(
void)
const
387 for(
auto &viewPair : configurationViews_)
388 if(viewPair.first.isTemporaryVersion())
continue;
389 else if(viewPair.first.isInvalid())
398 __MOUT__ <<
"There is an invalid version now!.. where did it come from?" << std::endl;
407 if(!activeConfigurationView_)
409 __SS__ <<
"activeConfigurationView_ pointer is null! (...likely the active view was not setup properly. Check your system setup.)";
410 throw std::runtime_error(ss.str());
412 return *activeConfigurationView_;
418 if(!activeConfigurationView_)
420 __SS__ <<
"activeConfigurationView_ pointer is null! (...likely the active view was not setup properly. Check your system setup.)";
421 throw std::runtime_error(ss.str());
423 return activeConfigurationView_;
429 return &mockupConfigurationView_;
433 void ConfigurationBase::setConfigurationName(
const std::string &configurationName)
435 configurationName_ = configurationName;
439 void ConfigurationBase::setConfigurationDescription(
const std::string &configurationDescription)
441 configurationDescription_ = configurationDescription;
447 void ConfigurationBase::deactivate()
449 activeConfigurationView_ = 0;
454 bool ConfigurationBase::isActive()
456 return activeConfigurationView_?
true:
false;
462 if(!isStored(version))
465 __SS__ <<
"\nsetActiveView() ERROR: View with version " << version <<
466 " has never been stored before!" << std::endl;
467 __MOUT_ERR__ <<
"\n" << ss.str();
468 throw std::runtime_error(ss.str());
471 activeConfigurationView_ = &configurationViews_[version];
473 if(configurationViews_[version].getVersion() != version)
475 __SS__ <<
"Something has gone very wrong with the version handling!" << std::endl;
476 throw std::runtime_error(ss.str());
493 throw(std::runtime_error)
496 if(sourceView.getNumberOfColumns() !=
497 mockupConfigurationView_.getNumberOfColumns())
499 __SS__ <<
"Error! Number of Columns of source view must match destination mock-up view." <<
500 "Dimension of source is [" << sourceView.getNumberOfColumns() <<
501 "] and of destination mockup is [" <<
502 mockupConfigurationView_.getNumberOfColumns() <<
"]." << std::endl;
503 throw std::runtime_error(ss.str());
507 if(!destinationVersion.isInvalid() &&
508 configurationViews_.find(sourceView.getVersion()) != configurationViews_.end())
510 __SS__ <<
"Error! Asked to copy a view with a conflicting version: " <<
511 sourceView.getVersion() << std::endl;
512 throw std::runtime_error(ss.str());
519 __MOUT__ <<
"Copying from " << sourceView.getTableName() <<
"_v" <<
520 sourceView.getVersion() <<
" to " << getConfigurationName() <<
"_v" <<
521 destinationVersion << std::endl;
525 configurationViews_[destinationVersion].copy(sourceView,destinationVersion,author);
529 __MOUT_ERR__ <<
"Failed to copy from " << sourceView.getTableName() <<
"_v" <<
530 sourceView.getVersion() <<
" to " << getConfigurationName() <<
"_v" <<
531 destinationVersion << std::endl;
532 __MOUT_WARN__ <<
"Deleting the failed destination version " <<
533 destinationVersion << std::endl;
534 eraseView(destinationVersion);
537 return destinationVersion;
550 __MOUT__ <<
"Configuration: " <<
551 getConfigurationName()<< std::endl;
553 __MOUT__ <<
"Num of Views: " <<
554 configurationViews_.size() <<
" (Temporary Views: " <<
555 (configurationViews_.size() - getNumberOfStoredViews()) <<
")" << std::endl;
558 if(tmpVersion.isInvalid()) tmpVersion = ConfigurationVersion::getNextTemporaryVersion();
559 while(isStored(tmpVersion) &&
560 !(tmpVersion = ConfigurationVersion::getNextTemporaryVersion(tmpVersion)).isInvalid());
561 if(isStored(tmpVersion) || tmpVersion.isInvalid())
563 __MOUT_ERR__ <<
"Invalid destination temporary version: " <<
564 destTemporaryViewVersion <<
". Expected next temporary version < " << tmpVersion << std::endl;
565 throw std::runtime_error(
"Invalid temporary version destination");
568 if(sourceViewVersion == ConfigurationVersion::INVALID ||
569 configurationViews_.find(sourceViewVersion) == configurationViews_.end())
571 if(sourceViewVersion != -1)
573 __MOUT_ERR__ <<
"ERROR: sourceViewVersion " << sourceViewVersion <<
" not found" << std::endl;
574 throw std::runtime_error(
"Invalid source version. Version requested is not stored (yet?) or does not exist.");
576 __MOUT__ <<
"Using Mock-up view" << std::endl;
577 configurationViews_[tmpVersion].copy(mockupConfigurationView_,
579 mockupConfigurationView_.getAuthor());
585 configurationViews_[tmpVersion].copy(configurationViews_[sourceViewVersion],
587 configurationViews_[sourceViewVersion].getAuthor());
591 __MOUT_WARN__ <<
"createTemporaryView() Source view failed init(). " <<
592 "This is being ignored (hopefully the new copy is being fixed)." << std::endl;
608 if(configurationViews_.size() != 0 && configurationViews_.begin()->first.isTemporaryVersion())
610 ConfigurationVersion::getNextTemporaryVersion(configurationViews_.begin()->first);
612 tmpVersion = ConfigurationVersion::getNextTemporaryVersion();
615 if(isStored(tmpVersion) || tmpVersion.isInvalid() || !tmpVersion.isTemporaryVersion())
617 __MOUT_ERR__ <<
"Invalid destination temporary version: " <<
618 tmpVersion << std::endl;
619 throw std::runtime_error(
"Invalid temporary version found");
633 if(configurationViews_.size() != 0 && !configurationViews_.rbegin()->first.isTemporaryVersion())
635 ConfigurationVersion::getNextVersion(configurationViews_.rbegin()->first);
637 tmpVersion = ConfigurationVersion::getNextVersion();
640 if(isStored(tmpVersion) || tmpVersion.isInvalid() || tmpVersion.isTemporaryVersion())
642 __MOUT_ERR__ <<
"Invalid destination next version: " <<
643 tmpVersion << std::endl;
644 throw std::runtime_error(
"Invalid next version found");
655 if(!temporaryVersion.isTemporaryVersion() ||
656 !isStored(temporaryVersion))
658 __MOUT_ERR__ << getConfigurationName() <<
":: Error! Temporary version not found!" << std::endl;
659 throw std::runtime_error(
"Invalid temporary version");
661 return &configurationViews_[temporaryVersion];
669 std::string ConfigurationBase::convertToCaps(std::string& str,
bool isConfigName)
670 throw(std::runtime_error)
673 unsigned int configPos = (
unsigned int)std::string::npos;
674 if(isConfigName && (configPos = str.find(
"Configuration")) !=
675 str.size() - strlen(
"Configuration"))
676 str +=
"Configuration";
683 std::string capsStr =
"";
684 for(
unsigned int c=0;c<str.size();++c)
685 if(str[c] >=
'A' && str[c] <=
'Z')
689 (c && str[c-1] >=
'a' && str[c-1] <=
'z') ||
690 (c && str[c-1] >=
'A' && str[c-1] <=
'Z' &&
691 c+1 < str.size() && str[c+1] >=
'a' && str[c+1] <=
'z')
696 else if(str[c] >=
'a' && str[c] <=
'z')
697 capsStr += char(str[c] -32);
698 else if(str[c] >=
'0' && str[c] <=
'9')
701 throw std::runtime_error(std::string(
"ConfigurationBase::convertToCaps::") +
702 "Invalid character found in name (allowed: A-Z, a-z, 0-9):" +