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 (20)
25 , configurationName_ (configurationName)
26 , activeConfigurationView_(0)
32 std::string returnedExceptions = configurationInfoReader.read(
this);
34 if(returnedExceptions !=
"")
35 __COUT_ERR__ << returnedExceptions << std::endl;
37 if(accumulatedExceptions) *accumulatedExceptions += std::string(
"\n") + returnedExceptions;
41 __SS__ <<
"Failure in configurationInfoReader.read(this)" << std::endl;
42 __COUT_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 __COUT_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 __COUT_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 __COUT_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 __COUT__ <<
"Trimming temporary version: " << it->first << std::endl;
195 if(activeConfigurationView_ &&
196 getViewVersion() == it->first)
198 configurationViews_.erase(it++);
204 else if(targetVersion.isTemporaryVersion())
206 __COUT__ <<
"Trimming temporary version: " << targetVersion << std::endl;
207 eraseView(targetVersion);
212 __SS__ <<
"Temporary trim target was a persistent version: " <<
213 targetVersion << std::endl;
214 __COUT_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 __COUT_ERR__ <<
"\n" << ss.str();
238 throw std::runtime_error(ss.str());
242 unsigned int rows = needleView->getNumberOfRows();
243 unsigned int cols = needleView->getNumberOfColumns();
246 unsigned int potentialMatchCount = 0;
253 auto viewPairReverseIterator = configurationViews_.rbegin();
254 for(;viewPairReverseIterator != configurationViews_.rend(); ++viewPairReverseIterator)
256 if(viewPairReverseIterator->first == needleVersion)
continue;
257 if(viewPairReverseIterator->first == ignoreVersion)
continue;
258 if(viewPairReverseIterator->first.isTemporaryVersion())
continue;
260 if(viewPairReverseIterator->second.getNumberOfRows() != rows)
263 if(viewPairReverseIterator->second.getDataColumnSize() != cols ||
264 viewPairReverseIterator->second.getSourceColumnMismatch() != 0)
268 ++potentialMatchCount;
269 __COUT__ <<
"Checking version... " << viewPairReverseIterator->first << std::endl;
275 auto viewColInfoIt = viewPairReverseIterator->second.getColumnsInfo().begin();
276 for(
unsigned int col=0; match &&
277 viewPairReverseIterator->second.getColumnsInfo().size() > 3 &&
278 col<viewPairReverseIterator->second.getColumnsInfo().size()-3;++col,viewColInfoIt++)
279 if(viewColInfoIt->getName() !=
280 needleView->getColumnsInfo()[col].getName())
288 for(
unsigned int row=0;match && row<rows;++row)
290 for(
unsigned int col=0;col<cols-2;++col)
291 if(viewPairReverseIterator->second.getDataView()[row][col] !=
292 needleView->getDataView()[row][col])
309 __COUT_INFO__ <<
"Duplicate version found: " << viewPairReverseIterator->first << std::endl;
310 return viewPairReverseIterator->first;
314 __COUT__ <<
"No duplicates found in " << potentialMatchCount <<
" potential matches." << std::endl;
322 if(configurationViews_.find(temporaryVersion) == configurationViews_.end())
324 __SS__ <<
"ERROR: Temporary view version " << temporaryVersion <<
" doesn't exists!" << std::endl;
325 __COUT_ERR__ <<
"\n" << ss.str();
326 throw std::runtime_error(ss.str());
328 if(version.isInvalid())
330 __SS__ <<
"ERROR: Attempting to create an invalid version " << version <<
331 "! Did you really run out of versions? (this should never happen)" << std::endl;
332 __COUT_ERR__ <<
"\n" << ss.str();
333 throw std::runtime_error(ss.str());
336 if(configurationViews_.find(version) != configurationViews_.end())
337 __COUT_WARN__ <<
"WARNING: View version " << version <<
" already exists! Overwriting." << std::endl;
339 configurationViews_[version].copy(configurationViews_[temporaryVersion],
341 configurationViews_[temporaryVersion].getAuthor());
342 setActiveView(version);
343 eraseView(temporaryVersion);
349 return (configurationViews_.find(version) != configurationViews_.end());
355 if(!isStored(version))
358 if(activeConfigurationView_ &&
359 getViewVersion() == version)
362 configurationViews_.erase(version);
368 const std::string& ConfigurationBase::getConfigurationName(
void)
const
370 return configurationName_;
374 const std::string& ConfigurationBase::getConfigurationDescription(
void)
const
376 return configurationDescription_;
382 return getView().getVersion();
389 bool ConfigurationBase::latestAndMockupColumnNumberMismatch(
void)
const
391 std::set<ConfigurationVersion> retSet = getStoredVersions();
392 if(retSet.size() && !retSet.rbegin()->isTemporaryVersion())
394 return configurationViews_.find(*(retSet.rbegin()))->second.getNumberOfColumns() !=
395 mockupConfigurationView_.getNumberOfColumns();
402 std::set<ConfigurationVersion> ConfigurationBase::getStoredVersions(
void)
const
404 std::set<ConfigurationVersion> retSet;
405 for(
auto &configs:configurationViews_)
406 retSet.emplace(configs.first);
414 unsigned int ConfigurationBase::getNumberOfStoredViews(
void)
const
417 for(
auto &viewPair : configurationViews_)
418 if(viewPair.first.isTemporaryVersion())
continue;
419 else if(viewPair.first.isInvalid())
428 __COUT__ <<
"There is an invalid version now!.. where did it come from?" << std::endl;
437 if(!activeConfigurationView_)
439 __SS__ <<
"activeConfigurationView_ pointer is null! (...likely the active view was not setup properly. Check your system setup.)";
440 throw std::runtime_error(ss.str());
442 return *activeConfigurationView_;
448 if(!activeConfigurationView_)
450 __SS__ <<
"activeConfigurationView_ pointer is null! (...likely the active view was not setup properly. Check your system setup.)";
451 throw std::runtime_error(ss.str());
453 return activeConfigurationView_;
459 return &mockupConfigurationView_;
463 void ConfigurationBase::setConfigurationName(
const std::string &configurationName)
465 configurationName_ = configurationName;
469 void ConfigurationBase::setConfigurationDescription(
const std::string &configurationDescription)
471 configurationDescription_ = configurationDescription;
477 void ConfigurationBase::deactivate()
479 activeConfigurationView_ = 0;
484 bool ConfigurationBase::isActive()
486 return activeConfigurationView_?
true:
false;
492 if(!isStored(version))
495 __SS__ <<
"\nsetActiveView() ERROR: View with version " << version <<
496 " has never been stored before!" << std::endl;
497 __COUT_ERR__ <<
"\n" << ss.str();
498 throw std::runtime_error(ss.str());
501 activeConfigurationView_ = &configurationViews_[version];
503 if(configurationViews_[version].getVersion() != version)
505 __SS__ <<
"Something has gone very wrong with the version handling!" << std::endl;
506 throw std::runtime_error(ss.str());
523 throw(std::runtime_error)
526 if(sourceView.getNumberOfColumns() !=
527 mockupConfigurationView_.getNumberOfColumns())
529 __SS__ <<
"Error! Number of Columns of source view must match destination mock-up view." <<
530 "Dimension of source is [" << sourceView.getNumberOfColumns() <<
531 "] and of destination mockup is [" <<
532 mockupConfigurationView_.getNumberOfColumns() <<
"]." << std::endl;
533 throw std::runtime_error(ss.str());
537 if(!destinationVersion.isInvalid() &&
538 configurationViews_.find(sourceView.getVersion()) != configurationViews_.end())
540 __SS__ <<
"Error! Asked to copy a view with a conflicting version: " <<
541 sourceView.getVersion() << std::endl;
542 throw std::runtime_error(ss.str());
549 __COUT__ <<
"Copying from " << sourceView.getTableName() <<
"_v" <<
550 sourceView.getVersion() <<
" to " << getConfigurationName() <<
"_v" <<
551 destinationVersion << std::endl;
555 configurationViews_[destinationVersion].copy(sourceView,destinationVersion,author);
559 __COUT_ERR__ <<
"Failed to copy from " << sourceView.getTableName() <<
"_v" <<
560 sourceView.getVersion() <<
" to " << getConfigurationName() <<
"_v" <<
561 destinationVersion << std::endl;
562 __COUT_WARN__ <<
"Deleting the failed destination version " <<
563 destinationVersion << std::endl;
564 eraseView(destinationVersion);
568 return destinationVersion;
581 __COUT__ <<
"Configuration: " <<
582 getConfigurationName()<< std::endl;
584 __COUT__ <<
"Num of Views: " <<
585 configurationViews_.size() <<
" (Temporary Views: " <<
586 (configurationViews_.size() - getNumberOfStoredViews()) <<
")" << std::endl;
589 if(tmpVersion.isInvalid()) tmpVersion = ConfigurationVersion::getNextTemporaryVersion();
590 while(isStored(tmpVersion) &&
591 !(tmpVersion = ConfigurationVersion::getNextTemporaryVersion(tmpVersion)).isInvalid());
592 if(isStored(tmpVersion) || tmpVersion.isInvalid())
594 __SS__ <<
"Invalid destination temporary version: " <<
595 destTemporaryViewVersion <<
". Expected next temporary version < " << tmpVersion << std::endl;
596 __COUT_ERR__ << ss.str();
597 throw std::runtime_error(ss.str());
600 if(sourceViewVersion == ConfigurationVersion::INVALID ||
601 configurationViews_.find(sourceViewVersion) == configurationViews_.end())
603 if(sourceViewVersion != -1)
605 __SS__ <<
"ERROR: sourceViewVersion " << sourceViewVersion <<
" not found. " <<
606 "Invalid source version. Version requested is not stored (yet?) or does not exist." << std::endl;
607 __COUT_ERR__ << ss.str();
608 throw std::runtime_error(ss.str());
610 __COUT__ <<
"Using Mock-up view" << std::endl;
611 configurationViews_[tmpVersion].copy(mockupConfigurationView_,
613 mockupConfigurationView_.getAuthor());
619 configurationViews_[tmpVersion].copy(configurationViews_[sourceViewVersion],
621 configurationViews_[sourceViewVersion].getAuthor());
625 __COUT_WARN__ <<
"createTemporaryView() Source view failed init(). " <<
626 "This is being ignored (hopefully the new copy is being fixed)." << std::endl;
642 if(configurationViews_.size() != 0 && configurationViews_.begin()->first.isTemporaryVersion())
644 ConfigurationVersion::getNextTemporaryVersion(configurationViews_.begin()->first);
646 tmpVersion = ConfigurationVersion::getNextTemporaryVersion();
649 if(isStored(tmpVersion) || tmpVersion.isInvalid() || !tmpVersion.isTemporaryVersion())
651 __SS__ <<
"Invalid destination temporary version: " <<
652 tmpVersion << std::endl;
653 __COUT_ERR__ << ss.str();
654 throw std::runtime_error(ss.str());
668 if(configurationViews_.size() != 0 && !configurationViews_.rbegin()->first.isTemporaryVersion())
670 ConfigurationVersion::getNextVersion(configurationViews_.rbegin()->first);
672 tmpVersion = ConfigurationVersion::getNextVersion();
675 if(isStored(tmpVersion) || tmpVersion.isInvalid() || tmpVersion.isTemporaryVersion())
677 __SS__ <<
"Invalid destination next version: " <<
678 tmpVersion << std::endl;
679 __COUT_ERR__ << ss.str();
680 throw std::runtime_error(ss.str());
691 if(!temporaryVersion.isTemporaryVersion() ||
692 !isStored(temporaryVersion))
694 __SS__ << getConfigurationName() <<
":: Error! Temporary version not found!" << std::endl;
695 __COUT_ERR__ << ss.str();
696 throw std::runtime_error(ss.str());
698 return &configurationViews_[temporaryVersion];
706 std::string ConfigurationBase::convertToCaps(std::string& str,
bool isConfigName)
707 throw(std::runtime_error)
710 unsigned int configPos = (
unsigned int)std::string::npos;
711 if(isConfigName && (configPos = str.find(
"Configuration")) !=
712 str.size() - strlen(
"Configuration"))
713 str +=
"Configuration";
720 std::string capsStr =
"";
721 for(
unsigned int c=0;c<str.size();++c)
722 if(str[c] >=
'A' && str[c] <=
'Z')
726 (c && str[c-1] >=
'a' && str[c-1] <=
'z') ||
727 (c && str[c-1] >=
'A' && str[c-1] <=
'Z' &&
728 c+1 < str.size() && str[c+1] >=
'a' && str[c+1] <=
'z')
733 else if(str[c] >=
'a' && str[c] <=
'z')
734 capsStr += char(str[c] -32);
735 else if(str[c] >=
'0' && str[c] <=
'9')
738 throw std::runtime_error(std::string(
"ConfigurationBase::convertToCaps::") +
739 "Invalid character found in name (allowed: A-Z, a-z, 0-9):" +