14 #include "boost/format.hpp" 26 #include "tbb/concurrent_unordered_map.h" 41 using chrono::steady_clock;
47 using ConcurrentKey = std::pair<ScheduleID, std::string>;
48 struct ConcurrentKeyHasher {
50 operator()(ConcurrentKey
const&
key)
const 52 static std::hash<ScheduleID> schedule_hasher{};
53 static std::hash<std::string> string_hasher{};
55 return schedule_hasher(key.first) ^ string_hasher(key.second);
60 key(ScheduleID
const sid)
62 return ConcurrentKey{sid, {}};
67 return ConcurrentKey{mc.scheduleID(), mc.moduleLabel()};
106 string label{info.path};
107 if (!info.mod_label.empty()) {
108 label +=
':' + info.mod_label;
110 if (!info.mod_type.empty()) {
111 label +=
':' + info.mod_type;
126 static constexpr
bool service_handle_allowed{
false};
145 template <
unsigned SIZE>
152 Ntuple<uint32_t, uint32_t, uint32_t, string, string, string, double>;
161 void recordTime(
ModuleContext const& mc,
string const& suffix);
162 void logToDestination_(Statistics
const&
evt,
163 vector<Statistics>
const& modules);
165 tbb::concurrent_unordered_map<ConcurrentKey,
170 unique_ptr<cet::sqlite::Connection>
const db_;
172 string sourceType_{};
208 areg.sPostSourceConstruction.watch(
this,
219 areg.sPostModule.watch(
220 [
this](
auto const& mc) { this->
recordTime(mc,
""s); });
222 areg.sPostWriteEvent.watch(
223 [
this](
auto const& mc) { this->
recordTime(mc,
"(write)"s); });
242 if ((nEventRows == 0) && (nModuleRows == 0)) {
246 if (nEventRows == 0 && nModuleRows != 0) {
248 "Malformed TimeTracker database. The TimeEvent table is empty, but\n" 249 "the TimeModule table is not. This can happen if an exception has\n" 250 "been thrown from a module while processing the first event. Any\n" 251 "saved database file is suspect and should not be used."};
259 string const fullEventTime_ddl =
260 "CREATE TABLE temp.fullEventTime AS " 261 "SELECT Run,Subrun,Event,SUM(Time) AS FullEventTime FROM (" 262 " SELECT Run,Subrun,Event,Time FROM TimeEvent" 264 " SELECT Run,Subrun,Event,Time FROM TimeModule WHERE ModuleType " 267 " SELECT Run,Subrun,Event,Time FROM TimeSource" 268 ") GROUP BY Run,Subrun,Event";
271 Statistics
const evtStats{
272 "Full event",
"",
"", *
db_,
"temp.fullEventTime",
"FullEventTime"};
277 vector<Statistics> modStats;
278 modStats.emplace_back(
279 "source",
sourceType_ +
"(read)",
"", *
db_,
"TimeSource",
"Time");
280 for (
auto const&
row : r) {
281 auto const& [path, mod_label, mod_type] =
row;
284 .from(*
db_,
"TimeModule")
285 .where(
"Path='"s + path +
"'"s +
" AND ModuleLabel='"s +
286 mod_label +
"'"s +
" AND ModuleType='"s +
288 modStats.emplace_back(
289 path, mod_label, mod_type, *
db_,
"temp.tmpModTable",
"Time");
306 d.eventStart =
now();
314 auto const t = chrono::duration<double>{
now() -
d.eventStart}.count();
316 d.eventID.run(),
d.eventID.subRun(),
d.eventID.event(),
sourceType_,
t);
324 assert(
d.eventID ==
e.id());
325 d.eventStart =
now();
332 auto const t = chrono::duration<double>{
now() -
d.eventStart}.count();
334 d.eventID.run(),
d.eventID.subRun(),
d.eventID.event(),
t);
348 auto const t = chrono::duration<double>{
now() -
d.moduleStart}.count();
360 vector<Statistics>
const& modules)
363 auto identifier_size = [](Statistics
const&
s) {
367 cet::for_all(modules, [&identifier_size, &width](
auto const& mod) {
368 width =
max(width, identifier_size(mod));
370 ostringstream msgOss;
382 msgOss << rule(
'=') <<
'\n';
384 msgOss <<
"[ No processed events ]\n";
388 msgOss <<
setw(width) << evt <<
'\n' << rule(
'-') <<
'\n';
389 for (
auto const& mod : modules) {
390 msgOss <<
setw(width) << mod <<
'\n';
void insert(Args const ...)
void logToDestination_(Statistics const &evt, vector< Statistics > const &modules)
timeEvent_t timeEventTable_
void preEventReading(ScheduleContext)
T unique_value(query_result< T > const &r)
tbb::concurrent_unordered_map< ConcurrentKey, PerScheduleData, ConcurrentKeyHasher > data_
double rms(sqlite3 *db, std::string const &table_name, std::string const &column_name)
auto const & pathName() const
auto select_distinct(T const &...t)
static bool format(QChar::Decomposition tag, QString &str, int index, int len)
void preEventProcessing(Event const &, ScheduleContext)
name_array< 4u > const timeEventColumnNames_
std::string const & name() const
void postEventProcessing(Event const &, ScheduleContext)
void postSourceConstruction(ModuleDescription const &)
void create_table_as(std::string const &tablename, SelectStmt const &stmt)
cet::sqlite::name_array< SIZE > name_array
fhicl::Atom< bool > printSummary
std::string const & moduleName() const
auto const & moduleName() const
void postEventReading(Event const &, ScheduleContext)
timeModule_t timeModuleTable_
#define DECLARE_ART_SERVICE(svc, scope)
std::ostream & operator<<(std::ostream &os, Analyzer::Table< T > const &t)
static int max(int a, int b)
unique_ptr< cet::sqlite::Connection > const db_
name_array< 7u > const timeModuleColumnNames_
timeSource_t timeSourceTable_
auto select(T const &...t)
steady_clock::time_point moduleStart
Q_EXPORT QTSManip setw(int w)
void recordTime(ModuleContext const &mc, string const &suffix)
void drop_table(sqlite3 *db, std::string const &tablename)
name_array< 5u > const timeSourceColumnNames_
#define DEFINE_ART_SERVICE(svc)
void startTime(ModuleContext const &mc)
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
std::vector< std::string > column
auto const & moduleLabel() const
static constexpr EventID invalidEvent() noexcept
std::array< std::string, N > name_array
auto for_all(FwdCont &, Func)
steady_clock::time_point eventStart
unsigned nrows(sqlite3 *db, std::string const &tablename)
void exec(sqlite3 *db, std::string const &ddl)
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
MaybeLogger_< ELseverityLevel::ELsev_severe, true > LogAbsolute
double median(sqlite3 *db, std::string const &table_name, std::string const &column_name)
fhicl::Table< DBoutput > dbOutput
bool const overwriteContents_