diff --git a/doc/Using_OO_API.md b/doc/Using_OO_API.md
index 4347c488fc4..cf543d3a84a 100644
--- a/doc/Using_OO_API.md
+++ b/doc/Using_OO_API.md
@@ -2101,3 +2101,44 @@ struct FbVarChar
This document is currently missing 2 types of plugins – ExternalEngine and Trace. Information about them will be made
available in next release of it.
+
+# Trace plugin
+
+_TODO_
+
+# Trace objects
+
+_TODO_
+
+# Trace performance statistics
+
+Trace plugin may retrieve various performance statistics available using the `getPerfStats()` method of the trace object, which returns a pointer to the `IPerformanceStats` interface.
+
+```cpp
+IPerformanceStats* stats = statement->getPerfStats();
+```
+
+The returned pointer may be `nullptr` if the corresponding trace object is not in the terminate state yet (i.e. still active / being executed).
+
+ PerformanceStats interface:
+
+- ISC_UINT64 getElapsedTime() - returns the elapsed time, in milliseconds
+- ISC_UINT64 getFetchedRecords() - returns number of records fetched during execution
+- IPerformanceCounters* getCounters(unsigned group) - returns the requested performance counters group
+
+The following groups of performance counters are currently supported:
+
+- COUNTER_GROUP_PAGES - per-pagespace counters
+- COUNTER_GROUP_TABLES - per-table counters
+
+If `getCounters()` is called with a counter group not supported by the implementation, `nullptr` is returned.
+
+ PerformanceCounters interface:
+
+- unsigned getObjectCount() - returns number of objects (e.g. tables) containing non-zero performance counters
+- unsigned getMaxCounterIndex() - returns maximum index number of the performance counters supported by the implementation (it's the same for all objects of the same group)
+- unsigned getObjectId(unsigned index) - returns ID of the specified object
+- const char* getObjectName(unsigned index) - returns name of the specified object
+- const ISC_INT64* getObjectCounters(unsigned index) - returns pointer to the vector of performance counters (containing getMaxCounterIndex() + 1 elements) of the specified object
+
+The returned pointer to the vector (as well as the whole instance of `PerformanceStats`) is valid until the object used to obtain the statistics (using the `getPerfStats()` method) is destroyed.
diff --git a/src/include/firebird/FirebirdInterface.idl b/src/include/firebird/FirebirdInterface.idl
index 06601ffa6ef..4bce83e70a4 100644
--- a/src/include/firebird/FirebirdInterface.idl
+++ b/src/include/firebird/FirebirdInterface.idl
@@ -1364,6 +1364,9 @@ interface TraceTransaction : Versioned
version: // 3.0.4 -> 3.0.5
int64 getInitialID();
int64 getPreviousID();
+
+version: // 5.0 -> 6.0
+ PerformanceStats getPerfStats();
}
interface TraceParams : Versioned
@@ -1379,6 +1382,9 @@ interface TraceStatement : Versioned
{
int64 getStmtID();
PerformanceInfo* getPerf();
+
+version: // 5.0 -> 6.0
+ PerformanceStats getPerfStats();
}
interface TraceSQLStatement : TraceStatement
@@ -1421,6 +1427,9 @@ version: // 4.0 -> 5.0
int64 getStmtID();
const string getPlan();
const string getExplainedPlan();
+
+version: // 5.0 -> 6.0
+ PerformanceStats getPerfStats();
}
interface TraceFunction : Versioned
@@ -1434,6 +1443,9 @@ version: // 4.0 -> 5.0
int64 getStmtID();
const string getPlan();
const string getExplainedPlan();
+
+version: // 5.0 -> 6.0
+ PerformanceStats getPerfStats();
}
interface TraceTrigger : Versioned
@@ -1456,6 +1468,9 @@ version: // 4.0 -> 5.0
int64 getStmtID();
const string getPlan();
const string getExplainedPlan();
+
+version: // 5.0 -> 6.0
+ PerformanceStats getPerfStats();
}
interface TraceServiceConnection : TraceConnection
@@ -1480,6 +1495,9 @@ interface TraceSweepInfo : Versioned
int64 getOAT();
int64 getNext();
PerformanceInfo* getPerf();
+
+version: // 5.0 -> 6.0
+ PerformanceStats getPerfStats();
}
interface TraceLogWriter : ReferenceCounted
@@ -1876,3 +1894,50 @@ interface ProfilerStats : Versioned
{
uint64 getElapsedTicks();
}
+
+// Extendable replacement for struct PerformanceInfo
+
+interface PerformanceCounters : Versioned
+{
+ // Page-level performance counters (grouped per tablespace)
+ const uint PAGE_FETCHES = 0;
+ const uint PAGE_READS = 1;
+ const uint PAGE_MARKS = 2;
+ const uint PAGE_WRITES = 3;
+
+ // Record-level performance counters (grouped per table)
+ const uint RECORD_SEQ_READS = 0;
+ const uint RECORD_IDX_READS = 1;
+ const uint RECORD_UPDATES = 2;
+ const uint RECORD_INSERTS = 3;
+ const uint RECORD_DELETES = 4;
+ const uint RECORD_BACKOUTS = 5;
+ const uint RECORD_PURGES = 6;
+ const uint RECORD_EXPUNGES = 7;
+ const uint RECORD_LOCKS = 8;
+ const uint RECORD_WAITS = 9;
+ const uint RECORD_CONFLICTS = 10;
+ const uint RECORD_BACK_READS = 11;
+ const uint RECORD_FRAGMENT_READS = 12;
+ const uint RECORD_RPT_READS = 13;
+ const uint RECORD_IMGC = 14;
+
+ uint getObjectCount();
+ uint getMaxCounterIndex();
+
+ uint getObjectId(uint index);
+ const string getObjectName(uint index);
+ const int64* getObjectCounters(uint index);
+}
+
+interface PerformanceStats : Versioned
+{
+ const uint COUNTER_GROUP_PAGES = 0;
+ const uint COUNTER_GROUP_TABLES = 1;
+
+ uint64 getElapsedTime(); // in milliseconds
+ uint64 getFetchedRecords();
+
+ PerformanceCounters getCounters(uint group);
+}
+
diff --git a/src/include/firebird/IdlFbInterfaces.h b/src/include/firebird/IdlFbInterfaces.h
index 43f3041054d..ea71d25e6bc 100644
--- a/src/include/firebird/IdlFbInterfaces.h
+++ b/src/include/firebird/IdlFbInterfaces.h
@@ -143,6 +143,8 @@ namespace Firebird
class IProfilerPlugin;
class IProfilerSession;
class IProfilerStats;
+ class IPerformanceCounters;
+ class IPerformanceStats;
// Interfaces declarations
@@ -5458,7 +5460,7 @@ namespace Firebird
}
};
-#define FIREBIRD_ITRACE_TRANSACTION_VERSION 3u
+#define FIREBIRD_ITRACE_TRANSACTION_VERSION 4u
class ITraceTransaction : public IVersioned
{
@@ -5472,6 +5474,7 @@ namespace Firebird
PerformanceInfo* (CLOOP_CARG *getPerf)(ITraceTransaction* self) CLOOP_NOEXCEPT;
ISC_INT64 (CLOOP_CARG *getInitialID)(ITraceTransaction* self) CLOOP_NOEXCEPT;
ISC_INT64 (CLOOP_CARG *getPreviousID)(ITraceTransaction* self) CLOOP_NOEXCEPT;
+ IPerformanceStats* (CLOOP_CARG *getPerfStats)(ITraceTransaction* self) CLOOP_NOEXCEPT;
};
protected:
@@ -5542,6 +5545,16 @@ namespace Firebird
ISC_INT64 ret = static_cast(this->cloopVTable)->getPreviousID(this);
return ret;
}
+
+ IPerformanceStats* getPerfStats()
+ {
+ if (cloopVTable->version < 4)
+ {
+ return 0;
+ }
+ IPerformanceStats* ret = static_cast(this->cloopVTable)->getPerfStats(this);
+ return ret;
+ }
};
#define FIREBIRD_ITRACE_PARAMS_VERSION 3u
@@ -5596,7 +5609,7 @@ namespace Firebird
}
};
-#define FIREBIRD_ITRACE_STATEMENT_VERSION 2u
+#define FIREBIRD_ITRACE_STATEMENT_VERSION 3u
class ITraceStatement : public IVersioned
{
@@ -5605,6 +5618,7 @@ namespace Firebird
{
ISC_INT64 (CLOOP_CARG *getStmtID)(ITraceStatement* self) CLOOP_NOEXCEPT;
PerformanceInfo* (CLOOP_CARG *getPerf)(ITraceStatement* self) CLOOP_NOEXCEPT;
+ IPerformanceStats* (CLOOP_CARG *getPerfStats)(ITraceStatement* self) CLOOP_NOEXCEPT;
};
protected:
@@ -5631,9 +5645,19 @@ namespace Firebird
PerformanceInfo* ret = static_cast(this->cloopVTable)->getPerf(this);
return ret;
}
+
+ IPerformanceStats* getPerfStats()
+ {
+ if (cloopVTable->version < 3)
+ {
+ return 0;
+ }
+ IPerformanceStats* ret = static_cast(this->cloopVTable)->getPerfStats(this);
+ return ret;
+ }
};
-#define FIREBIRD_ITRACE_SQLSTATEMENT_VERSION 3u
+#define FIREBIRD_ITRACE_SQLSTATEMENT_VERSION 4u
class ITraceSQLStatement : public ITraceStatement
{
@@ -5691,7 +5715,7 @@ namespace Firebird
}
};
-#define FIREBIRD_ITRACE_BLRSTATEMENT_VERSION 3u
+#define FIREBIRD_ITRACE_BLRSTATEMENT_VERSION 4u
class ITraceBLRStatement : public ITraceStatement
{
@@ -5823,7 +5847,7 @@ namespace Firebird
}
};
-#define FIREBIRD_ITRACE_PROCEDURE_VERSION 3u
+#define FIREBIRD_ITRACE_PROCEDURE_VERSION 4u
class ITraceProcedure : public IVersioned
{
@@ -5836,6 +5860,7 @@ namespace Firebird
ISC_INT64 (CLOOP_CARG *getStmtID)(ITraceProcedure* self) CLOOP_NOEXCEPT;
const char* (CLOOP_CARG *getPlan)(ITraceProcedure* self) CLOOP_NOEXCEPT;
const char* (CLOOP_CARG *getExplainedPlan)(ITraceProcedure* self) CLOOP_NOEXCEPT;
+ IPerformanceStats* (CLOOP_CARG *getPerfStats)(ITraceProcedure* self) CLOOP_NOEXCEPT;
};
protected:
@@ -5898,9 +5923,19 @@ namespace Firebird
const char* ret = static_cast(this->cloopVTable)->getExplainedPlan(this);
return ret;
}
+
+ IPerformanceStats* getPerfStats()
+ {
+ if (cloopVTable->version < 4)
+ {
+ return 0;
+ }
+ IPerformanceStats* ret = static_cast(this->cloopVTable)->getPerfStats(this);
+ return ret;
+ }
};
-#define FIREBIRD_ITRACE_FUNCTION_VERSION 3u
+#define FIREBIRD_ITRACE_FUNCTION_VERSION 4u
class ITraceFunction : public IVersioned
{
@@ -5914,6 +5949,7 @@ namespace Firebird
ISC_INT64 (CLOOP_CARG *getStmtID)(ITraceFunction* self) CLOOP_NOEXCEPT;
const char* (CLOOP_CARG *getPlan)(ITraceFunction* self) CLOOP_NOEXCEPT;
const char* (CLOOP_CARG *getExplainedPlan)(ITraceFunction* self) CLOOP_NOEXCEPT;
+ IPerformanceStats* (CLOOP_CARG *getPerfStats)(ITraceFunction* self) CLOOP_NOEXCEPT;
};
protected:
@@ -5982,9 +6018,19 @@ namespace Firebird
const char* ret = static_cast(this->cloopVTable)->getExplainedPlan(this);
return ret;
}
+
+ IPerformanceStats* getPerfStats()
+ {
+ if (cloopVTable->version < 4)
+ {
+ return 0;
+ }
+ IPerformanceStats* ret = static_cast(this->cloopVTable)->getPerfStats(this);
+ return ret;
+ }
};
-#define FIREBIRD_ITRACE_TRIGGER_VERSION 3u
+#define FIREBIRD_ITRACE_TRIGGER_VERSION 4u
class ITraceTrigger : public IVersioned
{
@@ -5999,6 +6045,7 @@ namespace Firebird
ISC_INT64 (CLOOP_CARG *getStmtID)(ITraceTrigger* self) CLOOP_NOEXCEPT;
const char* (CLOOP_CARG *getPlan)(ITraceTrigger* self) CLOOP_NOEXCEPT;
const char* (CLOOP_CARG *getExplainedPlan)(ITraceTrigger* self) CLOOP_NOEXCEPT;
+ IPerformanceStats* (CLOOP_CARG *getPerfStats)(ITraceTrigger* self) CLOOP_NOEXCEPT;
};
protected:
@@ -6077,6 +6124,16 @@ namespace Firebird
const char* ret = static_cast(this->cloopVTable)->getExplainedPlan(this);
return ret;
}
+
+ IPerformanceStats* getPerfStats()
+ {
+ if (cloopVTable->version < 4)
+ {
+ return 0;
+ }
+ IPerformanceStats* ret = static_cast(this->cloopVTable)->getPerfStats(this);
+ return ret;
+ }
};
#define FIREBIRD_ITRACE_SERVICE_CONNECTION_VERSION 3u
@@ -6174,7 +6231,7 @@ namespace Firebird
}
};
-#define FIREBIRD_ITRACE_SWEEP_INFO_VERSION 2u
+#define FIREBIRD_ITRACE_SWEEP_INFO_VERSION 3u
class ITraceSweepInfo : public IVersioned
{
@@ -6186,6 +6243,7 @@ namespace Firebird
ISC_INT64 (CLOOP_CARG *getOAT)(ITraceSweepInfo* self) CLOOP_NOEXCEPT;
ISC_INT64 (CLOOP_CARG *getNext)(ITraceSweepInfo* self) CLOOP_NOEXCEPT;
PerformanceInfo* (CLOOP_CARG *getPerf)(ITraceSweepInfo* self) CLOOP_NOEXCEPT;
+ IPerformanceStats* (CLOOP_CARG *getPerfStats)(ITraceSweepInfo* self) CLOOP_NOEXCEPT;
};
protected:
@@ -6230,6 +6288,16 @@ namespace Firebird
PerformanceInfo* ret = static_cast(this->cloopVTable)->getPerf(this);
return ret;
}
+
+ IPerformanceStats* getPerfStats()
+ {
+ if (cloopVTable->version < 3)
+ {
+ return 0;
+ }
+ IPerformanceStats* ret = static_cast(this->cloopVTable)->getPerfStats(this);
+ return ret;
+ }
};
#define FIREBIRD_ITRACE_LOG_WRITER_VERSION 4u
@@ -7538,6 +7606,131 @@ namespace Firebird
}
};
+#define FIREBIRD_IPERFORMANCE_COUNTERS_VERSION 2u
+
+ class IPerformanceCounters : public IVersioned
+ {
+ public:
+ struct VTable : public IVersioned::VTable
+ {
+ unsigned (CLOOP_CARG *getObjectCount)(IPerformanceCounters* self) CLOOP_NOEXCEPT;
+ unsigned (CLOOP_CARG *getMaxCounterIndex)(IPerformanceCounters* self) CLOOP_NOEXCEPT;
+ unsigned (CLOOP_CARG *getObjectId)(IPerformanceCounters* self, unsigned index) CLOOP_NOEXCEPT;
+ const char* (CLOOP_CARG *getObjectName)(IPerformanceCounters* self, unsigned index) CLOOP_NOEXCEPT;
+ const ISC_INT64* (CLOOP_CARG *getObjectCounters)(IPerformanceCounters* self, unsigned index) CLOOP_NOEXCEPT;
+ };
+
+ protected:
+ IPerformanceCounters(DoNotInherit)
+ : IVersioned(DoNotInherit())
+ {
+ }
+
+ ~IPerformanceCounters()
+ {
+ }
+
+ public:
+ static CLOOP_CONSTEXPR unsigned VERSION = FIREBIRD_IPERFORMANCE_COUNTERS_VERSION;
+
+ static CLOOP_CONSTEXPR unsigned PAGE_FETCHES = 0;
+ static CLOOP_CONSTEXPR unsigned PAGE_READS = 1;
+ static CLOOP_CONSTEXPR unsigned PAGE_MARKS = 2;
+ static CLOOP_CONSTEXPR unsigned PAGE_WRITES = 3;
+ static CLOOP_CONSTEXPR unsigned RECORD_SEQ_READS = 0;
+ static CLOOP_CONSTEXPR unsigned RECORD_IDX_READS = 1;
+ static CLOOP_CONSTEXPR unsigned RECORD_UPDATES = 2;
+ static CLOOP_CONSTEXPR unsigned RECORD_INSERTS = 3;
+ static CLOOP_CONSTEXPR unsigned RECORD_DELETES = 4;
+ static CLOOP_CONSTEXPR unsigned RECORD_BACKOUTS = 5;
+ static CLOOP_CONSTEXPR unsigned RECORD_PURGES = 6;
+ static CLOOP_CONSTEXPR unsigned RECORD_EXPUNGES = 7;
+ static CLOOP_CONSTEXPR unsigned RECORD_LOCKS = 8;
+ static CLOOP_CONSTEXPR unsigned RECORD_WAITS = 9;
+ static CLOOP_CONSTEXPR unsigned RECORD_CONFLICTS = 10;
+ static CLOOP_CONSTEXPR unsigned RECORD_BACK_READS = 11;
+ static CLOOP_CONSTEXPR unsigned RECORD_FRAGMENT_READS = 12;
+ static CLOOP_CONSTEXPR unsigned RECORD_RPT_READS = 13;
+ static CLOOP_CONSTEXPR unsigned RECORD_IMGC = 14;
+
+ unsigned getObjectCount()
+ {
+ unsigned ret = static_cast(this->cloopVTable)->getObjectCount(this);
+ return ret;
+ }
+
+ unsigned getMaxCounterIndex()
+ {
+ unsigned ret = static_cast(this->cloopVTable)->getMaxCounterIndex(this);
+ return ret;
+ }
+
+ unsigned getObjectId(unsigned index)
+ {
+ unsigned ret = static_cast(this->cloopVTable)->getObjectId(this, index);
+ return ret;
+ }
+
+ const char* getObjectName(unsigned index)
+ {
+ const char* ret = static_cast(this->cloopVTable)->getObjectName(this, index);
+ return ret;
+ }
+
+ const ISC_INT64* getObjectCounters(unsigned index)
+ {
+ const ISC_INT64* ret = static_cast(this->cloopVTable)->getObjectCounters(this, index);
+ return ret;
+ }
+ };
+
+#define FIREBIRD_IPERFORMANCE_STATS_VERSION 2u
+
+ class IPerformanceStats : public IVersioned
+ {
+ public:
+ struct VTable : public IVersioned::VTable
+ {
+ ISC_UINT64 (CLOOP_CARG *getElapsedTime)(IPerformanceStats* self) CLOOP_NOEXCEPT;
+ ISC_UINT64 (CLOOP_CARG *getFetchedRecords)(IPerformanceStats* self) CLOOP_NOEXCEPT;
+ IPerformanceCounters* (CLOOP_CARG *getCounters)(IPerformanceStats* self, unsigned group) CLOOP_NOEXCEPT;
+ };
+
+ protected:
+ IPerformanceStats(DoNotInherit)
+ : IVersioned(DoNotInherit())
+ {
+ }
+
+ ~IPerformanceStats()
+ {
+ }
+
+ public:
+ static CLOOP_CONSTEXPR unsigned VERSION = FIREBIRD_IPERFORMANCE_STATS_VERSION;
+
+ static CLOOP_CONSTEXPR unsigned COUNTER_GROUP_PAGES = 0;
+ static CLOOP_CONSTEXPR unsigned COUNTER_GROUP_TABLES = 1;
+
+ ISC_UINT64 getElapsedTime()
+ {
+ ISC_UINT64 ret = static_cast(this->cloopVTable)->getElapsedTime(this);
+ return ret;
+ }
+
+ ISC_UINT64 getFetchedRecords()
+ {
+ ISC_UINT64 ret = static_cast(this->cloopVTable)->getFetchedRecords(this);
+ return ret;
+ }
+
+ IPerformanceCounters* getCounters(unsigned group)
+ {
+ IPerformanceCounters* ret = static_cast(this->cloopVTable)->getCounters(this, group);
+ return ret;
+ }
+ };
+
// Interfaces implementations
template
@@ -17637,6 +17830,7 @@ namespace Firebird
this->getPerf = &Name::cloopgetPerfDispatcher;
this->getInitialID = &Name::cloopgetInitialIDDispatcher;
this->getPreviousID = &Name::cloopgetPreviousIDDispatcher;
+ this->getPerfStats = &Name::cloopgetPerfStatsDispatcher;
}
} vTable;
@@ -17733,6 +17927,19 @@ namespace Firebird
return static_cast(0);
}
}
+
+ static IPerformanceStats* CLOOP_CARG cloopgetPerfStatsDispatcher(ITraceTransaction* self) CLOOP_NOEXCEPT
+ {
+ try
+ {
+ return static_cast(self)->Name::getPerfStats();
+ }
+ catch (...)
+ {
+ StatusType::catchException(0);
+ return static_cast(0);
+ }
+ }
};
template > >
@@ -17755,6 +17962,7 @@ namespace Firebird
virtual PerformanceInfo* getPerf() = 0;
virtual ISC_INT64 getInitialID() = 0;
virtual ISC_INT64 getPreviousID() = 0;
+ virtual IPerformanceStats* getPerfStats() = 0;
};
template
@@ -17854,6 +18062,7 @@ namespace Firebird
this->version = Base::VERSION;
this->getStmtID = &Name::cloopgetStmtIDDispatcher;
this->getPerf = &Name::cloopgetPerfDispatcher;
+ this->getPerfStats = &Name::cloopgetPerfStatsDispatcher;
}
} vTable;
@@ -17885,6 +18094,19 @@ namespace Firebird
return static_cast(0);
}
}
+
+ static IPerformanceStats* CLOOP_CARG cloopgetPerfStatsDispatcher(ITraceStatement* self) CLOOP_NOEXCEPT
+ {
+ try
+ {
+ return static_cast(self)->Name::getPerfStats();
+ }
+ catch (...)
+ {
+ StatusType::catchException(0);
+ return static_cast(0);
+ }
+ }
};
template > >
@@ -17902,6 +18124,7 @@ namespace Firebird
virtual ISC_INT64 getStmtID() = 0;
virtual PerformanceInfo* getPerf() = 0;
+ virtual IPerformanceStats* getPerfStats() = 0;
};
template
@@ -17919,6 +18142,7 @@ namespace Firebird
this->version = Base::VERSION;
this->getStmtID = &Name::cloopgetStmtIDDispatcher;
this->getPerf = &Name::cloopgetPerfDispatcher;
+ this->getPerfStats = &Name::cloopgetPerfStatsDispatcher;
this->getText = &Name::cloopgetTextDispatcher;
this->getPlan = &Name::cloopgetPlanDispatcher;
this->getInputs = &Name::cloopgetInputsDispatcher;
@@ -18020,6 +18244,19 @@ namespace Firebird
return static_cast(0);
}
}
+
+ static IPerformanceStats* CLOOP_CARG cloopgetPerfStatsDispatcher(ITraceStatement* self) CLOOP_NOEXCEPT
+ {
+ try
+ {
+ return static_cast(self)->Name::getPerfStats();
+ }
+ catch (...)
+ {
+ StatusType::catchException(0);
+ return static_cast(0);
+ }
+ }
};
template > > > >
@@ -18057,6 +18294,7 @@ namespace Firebird
this->version = Base::VERSION;
this->getStmtID = &Name::cloopgetStmtIDDispatcher;
this->getPerf = &Name::cloopgetPerfDispatcher;
+ this->getPerfStats = &Name::cloopgetPerfStatsDispatcher;
this->getData = &Name::cloopgetDataDispatcher;
this->getDataLength = &Name::cloopgetDataLengthDispatcher;
this->getText = &Name::cloopgetTextDispatcher;
@@ -18130,6 +18368,19 @@ namespace Firebird
return static_cast(0);
}
}
+
+ static IPerformanceStats* CLOOP_CARG cloopgetPerfStatsDispatcher(ITraceStatement* self) CLOOP_NOEXCEPT
+ {
+ try
+ {
+ return static_cast(self)->Name::getPerfStats();
+ }
+ catch (...)
+ {
+ StatusType::catchException(0);
+ return static_cast(0);
+ }
+ }
};
template > > > >
@@ -18329,6 +18580,7 @@ namespace Firebird
this->getStmtID = &Name::cloopgetStmtIDDispatcher;
this->getPlan = &Name::cloopgetPlanDispatcher;
this->getExplainedPlan = &Name::cloopgetExplainedPlanDispatcher;
+ this->getPerfStats = &Name::cloopgetPerfStatsDispatcher;
}
} vTable;
@@ -18412,6 +18664,19 @@ namespace Firebird
return static_cast(0);
}
}
+
+ static IPerformanceStats* CLOOP_CARG cloopgetPerfStatsDispatcher(ITraceProcedure* self) CLOOP_NOEXCEPT
+ {
+ try
+ {
+ return static_cast(self)->Name::getPerfStats();
+ }
+ catch (...)
+ {
+ StatusType::catchException(0);
+ return static_cast(0);
+ }
+ }
};
template > >
@@ -18433,6 +18698,7 @@ namespace Firebird
virtual ISC_INT64 getStmtID() = 0;
virtual const char* getPlan() = 0;
virtual const char* getExplainedPlan() = 0;
+ virtual IPerformanceStats* getPerfStats() = 0;
};
template
@@ -18455,6 +18721,7 @@ namespace Firebird
this->getStmtID = &Name::cloopgetStmtIDDispatcher;
this->getPlan = &Name::cloopgetPlanDispatcher;
this->getExplainedPlan = &Name::cloopgetExplainedPlanDispatcher;
+ this->getPerfStats = &Name::cloopgetPerfStatsDispatcher;
}
} vTable;
@@ -18551,6 +18818,19 @@ namespace Firebird
return static_cast(0);
}
}
+
+ static IPerformanceStats* CLOOP_CARG cloopgetPerfStatsDispatcher(ITraceFunction* self) CLOOP_NOEXCEPT
+ {
+ try
+ {
+ return static_cast(self)->Name::getPerfStats();
+ }
+ catch (...)
+ {
+ StatusType::catchException(0);
+ return static_cast(0);
+ }
+ }
};
template > >
@@ -18573,6 +18853,7 @@ namespace Firebird
virtual ISC_INT64 getStmtID() = 0;
virtual const char* getPlan() = 0;
virtual const char* getExplainedPlan() = 0;
+ virtual IPerformanceStats* getPerfStats() = 0;
};
template
@@ -18596,6 +18877,7 @@ namespace Firebird
this->getStmtID = &Name::cloopgetStmtIDDispatcher;
this->getPlan = &Name::cloopgetPlanDispatcher;
this->getExplainedPlan = &Name::cloopgetExplainedPlanDispatcher;
+ this->getPerfStats = &Name::cloopgetPerfStatsDispatcher;
}
} vTable;
@@ -18705,6 +18987,19 @@ namespace Firebird
return static_cast(0);
}
}
+
+ static IPerformanceStats* CLOOP_CARG cloopgetPerfStatsDispatcher(ITraceTrigger* self) CLOOP_NOEXCEPT
+ {
+ try
+ {
+ return static_cast(self)->Name::getPerfStats();
+ }
+ catch (...)
+ {
+ StatusType::catchException(0);
+ return static_cast(0);
+ }
+ }
};
template > >
@@ -18728,6 +19023,7 @@ namespace Firebird
virtual ISC_INT64 getStmtID() = 0;
virtual const char* getPlan() = 0;
virtual const char* getExplainedPlan() = 0;
+ virtual IPerformanceStats* getPerfStats() = 0;
};
template
@@ -19049,6 +19345,7 @@ namespace Firebird
this->getOAT = &Name::cloopgetOATDispatcher;
this->getNext = &Name::cloopgetNextDispatcher;
this->getPerf = &Name::cloopgetPerfDispatcher;
+ this->getPerfStats = &Name::cloopgetPerfStatsDispatcher;
}
} vTable;
@@ -19119,6 +19416,19 @@ namespace Firebird
return static_cast(0);
}
}
+
+ static IPerformanceStats* CLOOP_CARG cloopgetPerfStatsDispatcher(ITraceSweepInfo* self) CLOOP_NOEXCEPT
+ {
+ try
+ {
+ return static_cast(self)->Name::getPerfStats();
+ }
+ catch (...)
+ {
+ StatusType::catchException(0);
+ return static_cast(0);
+ }
+ }
};
template > >
@@ -19139,6 +19449,7 @@ namespace Firebird
virtual ISC_INT64 getOAT() = 0;
virtual ISC_INT64 getNext() = 0;
virtual PerformanceInfo* getPerf() = 0;
+ virtual IPerformanceStats* getPerfStats() = 0;
};
template
@@ -21698,6 +22009,196 @@ namespace Firebird
virtual ISC_UINT64 getElapsedTicks() = 0;
};
+
+ template
+ class IPerformanceCountersBaseImpl : public Base
+ {
+ public:
+ typedef IPerformanceCounters Declaration;
+
+ IPerformanceCountersBaseImpl(DoNotInherit = DoNotInherit())
+ {
+ static struct VTableImpl : Base::VTable
+ {
+ VTableImpl()
+ {
+ this->version = Base::VERSION;
+ this->getObjectCount = &Name::cloopgetObjectCountDispatcher;
+ this->getMaxCounterIndex = &Name::cloopgetMaxCounterIndexDispatcher;
+ this->getObjectId = &Name::cloopgetObjectIdDispatcher;
+ this->getObjectName = &Name::cloopgetObjectNameDispatcher;
+ this->getObjectCounters = &Name::cloopgetObjectCountersDispatcher;
+ }
+ } vTable;
+
+ this->cloopVTable = &vTable;
+ }
+
+ static unsigned CLOOP_CARG cloopgetObjectCountDispatcher(IPerformanceCounters* self) CLOOP_NOEXCEPT
+ {
+ try
+ {
+ return static_cast(self)->Name::getObjectCount();
+ }
+ catch (...)
+ {
+ StatusType::catchException(0);
+ return static_cast(0);
+ }
+ }
+
+ static unsigned CLOOP_CARG cloopgetMaxCounterIndexDispatcher(IPerformanceCounters* self) CLOOP_NOEXCEPT
+ {
+ try
+ {
+ return static_cast(self)->Name::getMaxCounterIndex();
+ }
+ catch (...)
+ {
+ StatusType::catchException(0);
+ return static_cast(0);
+ }
+ }
+
+ static unsigned CLOOP_CARG cloopgetObjectIdDispatcher(IPerformanceCounters* self, unsigned index) CLOOP_NOEXCEPT
+ {
+ try
+ {
+ return static_cast(self)->Name::getObjectId(index);
+ }
+ catch (...)
+ {
+ StatusType::catchException(0);
+ return static_cast(0);
+ }
+ }
+
+ static const char* CLOOP_CARG cloopgetObjectNameDispatcher(IPerformanceCounters* self, unsigned index) CLOOP_NOEXCEPT
+ {
+ try
+ {
+ return static_cast(self)->Name::getObjectName(index);
+ }
+ catch (...)
+ {
+ StatusType::catchException(0);
+ return static_cast(0);
+ }
+ }
+
+ static const ISC_INT64* CLOOP_CARG cloopgetObjectCountersDispatcher(IPerformanceCounters* self, unsigned index) CLOOP_NOEXCEPT
+ {
+ try
+ {
+ return static_cast(self)->Name::getObjectCounters(index);
+ }
+ catch (...)
+ {
+ StatusType::catchException(0);
+ return static_cast(0);
+ }
+ }
+ };
+
+ template > >
+ class IPerformanceCountersImpl : public IPerformanceCountersBaseImpl
+ {
+ protected:
+ IPerformanceCountersImpl(DoNotInherit = DoNotInherit())
+ {
+ }
+
+ public:
+ virtual ~IPerformanceCountersImpl()
+ {
+ }
+
+ virtual unsigned getObjectCount() = 0;
+ virtual unsigned getMaxCounterIndex() = 0;
+ virtual unsigned getObjectId(unsigned index) = 0;
+ virtual const char* getObjectName(unsigned index) = 0;
+ virtual const ISC_INT64* getObjectCounters(unsigned index) = 0;
+ };
+
+ template
+ class IPerformanceStatsBaseImpl : public Base
+ {
+ public:
+ typedef IPerformanceStats Declaration;
+
+ IPerformanceStatsBaseImpl(DoNotInherit = DoNotInherit())
+ {
+ static struct VTableImpl : Base::VTable
+ {
+ VTableImpl()
+ {
+ this->version = Base::VERSION;
+ this->getElapsedTime = &Name::cloopgetElapsedTimeDispatcher;
+ this->getFetchedRecords = &Name::cloopgetFetchedRecordsDispatcher;
+ this->getCounters = &Name::cloopgetCountersDispatcher;
+ }
+ } vTable;
+
+ this->cloopVTable = &vTable;
+ }
+
+ static ISC_UINT64 CLOOP_CARG cloopgetElapsedTimeDispatcher(IPerformanceStats* self) CLOOP_NOEXCEPT
+ {
+ try
+ {
+ return static_cast(self)->Name::getElapsedTime();
+ }
+ catch (...)
+ {
+ StatusType::catchException(0);
+ return static_cast(0);
+ }
+ }
+
+ static ISC_UINT64 CLOOP_CARG cloopgetFetchedRecordsDispatcher(IPerformanceStats* self) CLOOP_NOEXCEPT
+ {
+ try
+ {
+ return static_cast(self)->Name::getFetchedRecords();
+ }
+ catch (...)
+ {
+ StatusType::catchException(0);
+ return static_cast(0);
+ }
+ }
+
+ static IPerformanceCounters* CLOOP_CARG cloopgetCountersDispatcher(IPerformanceStats* self, unsigned group) CLOOP_NOEXCEPT
+ {
+ try
+ {
+ return static_cast(self)->Name::getCounters(group);
+ }
+ catch (...)
+ {
+ StatusType::catchException(0);
+ return static_cast(0);
+ }
+ }
+ };
+
+ template > >
+ class IPerformanceStatsImpl : public IPerformanceStatsBaseImpl
+ {
+ protected:
+ IPerformanceStatsImpl(DoNotInherit = DoNotInherit())
+ {
+ }
+
+ public:
+ virtual ~IPerformanceStatsImpl()
+ {
+ }
+
+ virtual ISC_UINT64 getElapsedTime() = 0;
+ virtual ISC_UINT64 getFetchedRecords() = 0;
+ virtual IPerformanceCounters* getCounters(unsigned group) = 0;
+ };
};
diff --git a/src/include/gen/Firebird.pas b/src/include/gen/Firebird.pas
index 4fdd5a676e3..eb0cfeae5a0 100644
--- a/src/include/gen/Firebird.pas
+++ b/src/include/gen/Firebird.pas
@@ -114,6 +114,8 @@ IReplicatedSession = class;
IProfilerPlugin = class;
IProfilerSession = class;
IProfilerStats = class;
+ IPerformanceCounters = class;
+ IPerformanceStats = class;
FbException = class(Exception)
public
@@ -611,11 +613,13 @@ ISC_TIMESTAMP_TZ_EX = record
ITraceTransaction_getPerfPtr = function(this: ITraceTransaction): PerformanceInfoPtr; cdecl;
ITraceTransaction_getInitialIDPtr = function(this: ITraceTransaction): Int64; cdecl;
ITraceTransaction_getPreviousIDPtr = function(this: ITraceTransaction): Int64; cdecl;
+ ITraceTransaction_getPerfStatsPtr = function(this: ITraceTransaction): IPerformanceStats; cdecl;
ITraceParams_getCountPtr = function(this: ITraceParams): Cardinal; cdecl;
ITraceParams_getParamPtr = function(this: ITraceParams; idx: Cardinal): paramdscPtr; cdecl;
ITraceParams_getTextUTF8Ptr = function(this: ITraceParams; status: IStatus; idx: Cardinal): PAnsiChar; cdecl;
ITraceStatement_getStmtIDPtr = function(this: ITraceStatement): Int64; cdecl;
ITraceStatement_getPerfPtr = function(this: ITraceStatement): PerformanceInfoPtr; cdecl;
+ ITraceStatement_getPerfStatsPtr = function(this: ITraceStatement): IPerformanceStats; cdecl;
ITraceSQLStatement_getTextPtr = function(this: ITraceSQLStatement): PAnsiChar; cdecl;
ITraceSQLStatement_getPlanPtr = function(this: ITraceSQLStatement): PAnsiChar; cdecl;
ITraceSQLStatement_getInputsPtr = function(this: ITraceSQLStatement): ITraceParams; cdecl;
@@ -636,6 +640,7 @@ ISC_TIMESTAMP_TZ_EX = record
ITraceProcedure_getStmtIDPtr = function(this: ITraceProcedure): Int64; cdecl;
ITraceProcedure_getPlanPtr = function(this: ITraceProcedure): PAnsiChar; cdecl;
ITraceProcedure_getExplainedPlanPtr = function(this: ITraceProcedure): PAnsiChar; cdecl;
+ ITraceProcedure_getPerfStatsPtr = function(this: ITraceProcedure): IPerformanceStats; cdecl;
ITraceFunction_getFuncNamePtr = function(this: ITraceFunction): PAnsiChar; cdecl;
ITraceFunction_getInputsPtr = function(this: ITraceFunction): ITraceParams; cdecl;
ITraceFunction_getResultPtr = function(this: ITraceFunction): ITraceParams; cdecl;
@@ -643,6 +648,7 @@ ISC_TIMESTAMP_TZ_EX = record
ITraceFunction_getStmtIDPtr = function(this: ITraceFunction): Int64; cdecl;
ITraceFunction_getPlanPtr = function(this: ITraceFunction): PAnsiChar; cdecl;
ITraceFunction_getExplainedPlanPtr = function(this: ITraceFunction): PAnsiChar; cdecl;
+ ITraceFunction_getPerfStatsPtr = function(this: ITraceFunction): IPerformanceStats; cdecl;
ITraceTrigger_getTriggerNamePtr = function(this: ITraceTrigger): PAnsiChar; cdecl;
ITraceTrigger_getRelationNamePtr = function(this: ITraceTrigger): PAnsiChar; cdecl;
ITraceTrigger_getActionPtr = function(this: ITraceTrigger): Integer; cdecl;
@@ -651,6 +657,7 @@ ISC_TIMESTAMP_TZ_EX = record
ITraceTrigger_getStmtIDPtr = function(this: ITraceTrigger): Int64; cdecl;
ITraceTrigger_getPlanPtr = function(this: ITraceTrigger): PAnsiChar; cdecl;
ITraceTrigger_getExplainedPlanPtr = function(this: ITraceTrigger): PAnsiChar; cdecl;
+ ITraceTrigger_getPerfStatsPtr = function(this: ITraceTrigger): IPerformanceStats; cdecl;
ITraceServiceConnection_getServiceIDPtr = function(this: ITraceServiceConnection): Pointer; cdecl;
ITraceServiceConnection_getServiceMgrPtr = function(this: ITraceServiceConnection): PAnsiChar; cdecl;
ITraceServiceConnection_getServiceNamePtr = function(this: ITraceServiceConnection): PAnsiChar; cdecl;
@@ -663,6 +670,7 @@ ISC_TIMESTAMP_TZ_EX = record
ITraceSweepInfo_getOATPtr = function(this: ITraceSweepInfo): Int64; cdecl;
ITraceSweepInfo_getNextPtr = function(this: ITraceSweepInfo): Int64; cdecl;
ITraceSweepInfo_getPerfPtr = function(this: ITraceSweepInfo): PerformanceInfoPtr; cdecl;
+ ITraceSweepInfo_getPerfStatsPtr = function(this: ITraceSweepInfo): IPerformanceStats; cdecl;
ITraceLogWriter_writePtr = function(this: ITraceLogWriter; buf: Pointer; size: Cardinal): Cardinal; cdecl;
ITraceLogWriter_write_sPtr = function(this: ITraceLogWriter; status: IStatus; buf: Pointer; size: Cardinal): Cardinal; cdecl;
ITraceInitInfo_getConfigTextPtr = function(this: ITraceInitInfo): PAnsiChar; cdecl;
@@ -770,6 +778,14 @@ ISC_TIMESTAMP_TZ_EX = record
IProfilerSession_afterRecordSourceGetRecordPtr = procedure(this: IProfilerSession; statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats); cdecl;
IProfilerSession_defineStatement2Ptr = procedure(this: IProfilerSession; status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; schemaName: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar); cdecl;
IProfilerStats_getElapsedTicksPtr = function(this: IProfilerStats): QWord; cdecl;
+ IPerformanceCounters_getObjectCountPtr = function(this: IPerformanceCounters): Cardinal; cdecl;
+ IPerformanceCounters_getMaxCounterIndexPtr = function(this: IPerformanceCounters): Cardinal; cdecl;
+ IPerformanceCounters_getObjectIdPtr = function(this: IPerformanceCounters; index: Cardinal): Cardinal; cdecl;
+ IPerformanceCounters_getObjectNamePtr = function(this: IPerformanceCounters; index: Cardinal): PAnsiChar; cdecl;
+ IPerformanceCounters_getObjectCountersPtr = function(this: IPerformanceCounters; index: Cardinal): Int64Ptr; cdecl;
+ IPerformanceStats_getElapsedTimePtr = function(this: IPerformanceStats): QWord; cdecl;
+ IPerformanceStats_getFetchedRecordsPtr = function(this: IPerformanceStats): QWord; cdecl;
+ IPerformanceStats_getCountersPtr = function(this: IPerformanceStats; group: Cardinal): IPerformanceCounters; cdecl;
VersionedVTable = class
version: NativeInt;
@@ -3052,10 +3068,11 @@ TraceTransactionVTable = class(VersionedVTable)
getPerf: ITraceTransaction_getPerfPtr;
getInitialID: ITraceTransaction_getInitialIDPtr;
getPreviousID: ITraceTransaction_getPreviousIDPtr;
+ getPerfStats: ITraceTransaction_getPerfStatsPtr;
end;
ITraceTransaction = class(IVersioned)
- const VERSION = 3;
+ const VERSION = 4;
const ISOLATION_CONSISTENCY = Cardinal(1);
const ISOLATION_CONCURRENCY = Cardinal(2);
const ISOLATION_READ_COMMITTED_RECVER = Cardinal(3);
@@ -3069,6 +3086,7 @@ ITraceTransaction = class(IVersioned)
function getPerf(): PerformanceInfoPtr;
function getInitialID(): Int64;
function getPreviousID(): Int64;
+ function getPerfStats(): IPerformanceStats;
end;
ITraceTransactionImpl = class(ITraceTransaction)
@@ -3081,6 +3099,7 @@ ITraceTransactionImpl = class(ITraceTransaction)
function getPerf(): PerformanceInfoPtr; virtual; abstract;
function getInitialID(): Int64; virtual; abstract;
function getPreviousID(): Int64; virtual; abstract;
+ function getPerfStats(): IPerformanceStats; virtual; abstract;
end;
TraceParamsVTable = class(VersionedVTable)
@@ -3108,13 +3127,15 @@ ITraceParamsImpl = class(ITraceParams)
TraceStatementVTable = class(VersionedVTable)
getStmtID: ITraceStatement_getStmtIDPtr;
getPerf: ITraceStatement_getPerfPtr;
+ getPerfStats: ITraceStatement_getPerfStatsPtr;
end;
ITraceStatement = class(IVersioned)
- const VERSION = 2;
+ const VERSION = 3;
function getStmtID(): Int64;
function getPerf(): PerformanceInfoPtr;
+ function getPerfStats(): IPerformanceStats;
end;
ITraceStatementImpl = class(ITraceStatement)
@@ -3122,6 +3143,7 @@ ITraceStatementImpl = class(ITraceStatement)
function getStmtID(): Int64; virtual; abstract;
function getPerf(): PerformanceInfoPtr; virtual; abstract;
+ function getPerfStats(): IPerformanceStats; virtual; abstract;
end;
TraceSQLStatementVTable = class(TraceStatementVTable)
@@ -3133,7 +3155,7 @@ TraceSQLStatementVTable = class(TraceStatementVTable)
end;
ITraceSQLStatement = class(ITraceStatement)
- const VERSION = 3;
+ const VERSION = 4;
function getText(): PAnsiChar;
function getPlan(): PAnsiChar;
@@ -3147,6 +3169,7 @@ ITraceSQLStatementImpl = class(ITraceSQLStatement)
function getStmtID(): Int64; virtual; abstract;
function getPerf(): PerformanceInfoPtr; virtual; abstract;
+ function getPerfStats(): IPerformanceStats; virtual; abstract;
function getText(): PAnsiChar; virtual; abstract;
function getPlan(): PAnsiChar; virtual; abstract;
function getInputs(): ITraceParams; virtual; abstract;
@@ -3161,7 +3184,7 @@ TraceBLRStatementVTable = class(TraceStatementVTable)
end;
ITraceBLRStatement = class(ITraceStatement)
- const VERSION = 3;
+ const VERSION = 4;
function getData(): BytePtr;
function getDataLength(): Cardinal;
@@ -3173,6 +3196,7 @@ ITraceBLRStatementImpl = class(ITraceBLRStatement)
function getStmtID(): Int64; virtual; abstract;
function getPerf(): PerformanceInfoPtr; virtual; abstract;
+ function getPerfStats(): IPerformanceStats; virtual; abstract;
function getData(): BytePtr; virtual; abstract;
function getDataLength(): Cardinal; virtual; abstract;
function getText(): PAnsiChar; virtual; abstract;
@@ -3229,10 +3253,11 @@ TraceProcedureVTable = class(VersionedVTable)
getStmtID: ITraceProcedure_getStmtIDPtr;
getPlan: ITraceProcedure_getPlanPtr;
getExplainedPlan: ITraceProcedure_getExplainedPlanPtr;
+ getPerfStats: ITraceProcedure_getPerfStatsPtr;
end;
ITraceProcedure = class(IVersioned)
- const VERSION = 3;
+ const VERSION = 4;
function getProcName(): PAnsiChar;
function getInputs(): ITraceParams;
@@ -3240,6 +3265,7 @@ ITraceProcedure = class(IVersioned)
function getStmtID(): Int64;
function getPlan(): PAnsiChar;
function getExplainedPlan(): PAnsiChar;
+ function getPerfStats(): IPerformanceStats;
end;
ITraceProcedureImpl = class(ITraceProcedure)
@@ -3251,6 +3277,7 @@ ITraceProcedureImpl = class(ITraceProcedure)
function getStmtID(): Int64; virtual; abstract;
function getPlan(): PAnsiChar; virtual; abstract;
function getExplainedPlan(): PAnsiChar; virtual; abstract;
+ function getPerfStats(): IPerformanceStats; virtual; abstract;
end;
TraceFunctionVTable = class(VersionedVTable)
@@ -3261,10 +3288,11 @@ TraceFunctionVTable = class(VersionedVTable)
getStmtID: ITraceFunction_getStmtIDPtr;
getPlan: ITraceFunction_getPlanPtr;
getExplainedPlan: ITraceFunction_getExplainedPlanPtr;
+ getPerfStats: ITraceFunction_getPerfStatsPtr;
end;
ITraceFunction = class(IVersioned)
- const VERSION = 3;
+ const VERSION = 4;
function getFuncName(): PAnsiChar;
function getInputs(): ITraceParams;
@@ -3273,6 +3301,7 @@ ITraceFunction = class(IVersioned)
function getStmtID(): Int64;
function getPlan(): PAnsiChar;
function getExplainedPlan(): PAnsiChar;
+ function getPerfStats(): IPerformanceStats;
end;
ITraceFunctionImpl = class(ITraceFunction)
@@ -3285,6 +3314,7 @@ ITraceFunctionImpl = class(ITraceFunction)
function getStmtID(): Int64; virtual; abstract;
function getPlan(): PAnsiChar; virtual; abstract;
function getExplainedPlan(): PAnsiChar; virtual; abstract;
+ function getPerfStats(): IPerformanceStats; virtual; abstract;
end;
TraceTriggerVTable = class(VersionedVTable)
@@ -3296,10 +3326,11 @@ TraceTriggerVTable = class(VersionedVTable)
getStmtID: ITraceTrigger_getStmtIDPtr;
getPlan: ITraceTrigger_getPlanPtr;
getExplainedPlan: ITraceTrigger_getExplainedPlanPtr;
+ getPerfStats: ITraceTrigger_getPerfStatsPtr;
end;
ITraceTrigger = class(IVersioned)
- const VERSION = 3;
+ const VERSION = 4;
const TYPE_ALL = Cardinal(0);
const TYPE_BEFORE = Cardinal(1);
const TYPE_AFTER = Cardinal(2);
@@ -3312,6 +3343,7 @@ ITraceTrigger = class(IVersioned)
function getStmtID(): Int64;
function getPlan(): PAnsiChar;
function getExplainedPlan(): PAnsiChar;
+ function getPerfStats(): IPerformanceStats;
end;
ITraceTriggerImpl = class(ITraceTrigger)
@@ -3325,6 +3357,7 @@ ITraceTriggerImpl = class(ITraceTrigger)
function getStmtID(): Int64; virtual; abstract;
function getPlan(): PAnsiChar; virtual; abstract;
function getExplainedPlan(): PAnsiChar; virtual; abstract;
+ function getPerfStats(): IPerformanceStats; virtual; abstract;
end;
TraceServiceConnectionVTable = class(TraceConnectionVTable)
@@ -3389,16 +3422,18 @@ TraceSweepInfoVTable = class(VersionedVTable)
getOAT: ITraceSweepInfo_getOATPtr;
getNext: ITraceSweepInfo_getNextPtr;
getPerf: ITraceSweepInfo_getPerfPtr;
+ getPerfStats: ITraceSweepInfo_getPerfStatsPtr;
end;
ITraceSweepInfo = class(IVersioned)
- const VERSION = 2;
+ const VERSION = 3;
function getOIT(): Int64;
function getOST(): Int64;
function getOAT(): Int64;
function getNext(): Int64;
function getPerf(): PerformanceInfoPtr;
+ function getPerfStats(): IPerformanceStats;
end;
ITraceSweepInfoImpl = class(ITraceSweepInfo)
@@ -3409,6 +3444,7 @@ ITraceSweepInfoImpl = class(ITraceSweepInfo)
function getOAT(): Int64; virtual; abstract;
function getNext(): Int64; virtual; abstract;
function getPerf(): PerformanceInfoPtr; virtual; abstract;
+ function getPerfStats(): IPerformanceStats; virtual; abstract;
end;
TraceLogWriterVTable = class(ReferenceCountedVTable)
@@ -4025,6 +4061,77 @@ IProfilerStatsImpl = class(IProfilerStats)
function getElapsedTicks(): QWord; virtual; abstract;
end;
+ PerformanceCountersVTable = class(VersionedVTable)
+ getObjectCount: IPerformanceCounters_getObjectCountPtr;
+ getMaxCounterIndex: IPerformanceCounters_getMaxCounterIndexPtr;
+ getObjectId: IPerformanceCounters_getObjectIdPtr;
+ getObjectName: IPerformanceCounters_getObjectNamePtr;
+ getObjectCounters: IPerformanceCounters_getObjectCountersPtr;
+ end;
+
+ IPerformanceCounters = class(IVersioned)
+ const VERSION = 2;
+ const PAGE_FETCHES = Cardinal(0);
+ const PAGE_READS = Cardinal(1);
+ const PAGE_MARKS = Cardinal(2);
+ const PAGE_WRITES = Cardinal(3);
+ const RECORD_SEQ_READS = Cardinal(0);
+ const RECORD_IDX_READS = Cardinal(1);
+ const RECORD_UPDATES = Cardinal(2);
+ const RECORD_INSERTS = Cardinal(3);
+ const RECORD_DELETES = Cardinal(4);
+ const RECORD_BACKOUTS = Cardinal(5);
+ const RECORD_PURGES = Cardinal(6);
+ const RECORD_EXPUNGES = Cardinal(7);
+ const RECORD_LOCKS = Cardinal(8);
+ const RECORD_WAITS = Cardinal(9);
+ const RECORD_CONFLICTS = Cardinal(10);
+ const RECORD_BACK_READS = Cardinal(11);
+ const RECORD_FRAGMENT_READS = Cardinal(12);
+ const RECORD_RPT_READS = Cardinal(13);
+ const RECORD_IMGC = Cardinal(14);
+
+ function getObjectCount(): Cardinal;
+ function getMaxCounterIndex(): Cardinal;
+ function getObjectId(index: Cardinal): Cardinal;
+ function getObjectName(index: Cardinal): PAnsiChar;
+ function getObjectCounters(index: Cardinal): Int64Ptr;
+ end;
+
+ IPerformanceCountersImpl = class(IPerformanceCounters)
+ constructor create;
+
+ function getObjectCount(): Cardinal; virtual; abstract;
+ function getMaxCounterIndex(): Cardinal; virtual; abstract;
+ function getObjectId(index: Cardinal): Cardinal; virtual; abstract;
+ function getObjectName(index: Cardinal): PAnsiChar; virtual; abstract;
+ function getObjectCounters(index: Cardinal): Int64Ptr; virtual; abstract;
+ end;
+
+ PerformanceStatsVTable = class(VersionedVTable)
+ getElapsedTime: IPerformanceStats_getElapsedTimePtr;
+ getFetchedRecords: IPerformanceStats_getFetchedRecordsPtr;
+ getCounters: IPerformanceStats_getCountersPtr;
+ end;
+
+ IPerformanceStats = class(IVersioned)
+ const VERSION = 2;
+ const COUNTER_GROUP_PAGES = Cardinal(0);
+ const COUNTER_GROUP_TABLES = Cardinal(1);
+
+ function getElapsedTime(): QWord;
+ function getFetchedRecords(): QWord;
+ function getCounters(group: Cardinal): IPerformanceCounters;
+ end;
+
+ IPerformanceStatsImpl = class(IPerformanceStats)
+ constructor create;
+
+ function getElapsedTime(): QWord; virtual; abstract;
+ function getFetchedRecords(): QWord; virtual; abstract;
+ function getCounters(group: Cardinal): IPerformanceCounters; virtual; abstract;
+ end;
+
{$IFNDEF NO_FBCLIENT}
function fb_get_master_interface : IMaster; cdecl; external 'fbclient';
{$ENDIF}
@@ -9100,6 +9207,16 @@ function ITraceTransaction.getPreviousID(): Int64;
end;
end;
+function ITraceTransaction.getPerfStats(): IPerformanceStats;
+begin
+ if (vTable.version < 4) then begin
+ Result := nil;
+ end
+ else begin
+ Result := TraceTransactionVTable(vTable).getPerfStats(Self);
+ end;
+end;
+
function ITraceParams.getCount(): Cardinal;
begin
Result := TraceParamsVTable(vTable).getCount(Self);
@@ -9132,6 +9249,16 @@ function ITraceStatement.getPerf(): PerformanceInfoPtr;
Result := TraceStatementVTable(vTable).getPerf(Self);
end;
+function ITraceStatement.getPerfStats(): IPerformanceStats;
+begin
+ if (vTable.version < 3) then begin
+ Result := nil;
+ end
+ else begin
+ Result := TraceStatementVTable(vTable).getPerfStats(Self);
+ end;
+end;
+
function ITraceSQLStatement.getText(): PAnsiChar;
begin
Result := TraceSQLStatementVTable(vTable).getText(Self);
@@ -9247,6 +9374,16 @@ function ITraceProcedure.getExplainedPlan(): PAnsiChar;
end;
end;
+function ITraceProcedure.getPerfStats(): IPerformanceStats;
+begin
+ if (vTable.version < 4) then begin
+ Result := nil;
+ end
+ else begin
+ Result := TraceProcedureVTable(vTable).getPerfStats(Self);
+ end;
+end;
+
function ITraceFunction.getFuncName(): PAnsiChar;
begin
Result := TraceFunctionVTable(vTable).getFuncName(Self);
@@ -9297,6 +9434,16 @@ function ITraceFunction.getExplainedPlan(): PAnsiChar;
end;
end;
+function ITraceFunction.getPerfStats(): IPerformanceStats;
+begin
+ if (vTable.version < 4) then begin
+ Result := nil;
+ end
+ else begin
+ Result := TraceFunctionVTable(vTable).getPerfStats(Self);
+ end;
+end;
+
function ITraceTrigger.getTriggerName(): PAnsiChar;
begin
Result := TraceTriggerVTable(vTable).getTriggerName(Self);
@@ -9352,6 +9499,16 @@ function ITraceTrigger.getExplainedPlan(): PAnsiChar;
end;
end;
+function ITraceTrigger.getPerfStats(): IPerformanceStats;
+begin
+ if (vTable.version < 4) then begin
+ Result := nil;
+ end
+ else begin
+ Result := TraceTriggerVTable(vTable).getPerfStats(Self);
+ end;
+end;
+
function ITraceServiceConnection.getServiceID(): Pointer;
begin
Result := TraceServiceConnectionVTable(vTable).getServiceID(Self);
@@ -9412,6 +9569,16 @@ function ITraceSweepInfo.getPerf(): PerformanceInfoPtr;
Result := TraceSweepInfoVTable(vTable).getPerf(Self);
end;
+function ITraceSweepInfo.getPerfStats(): IPerformanceStats;
+begin
+ if (vTable.version < 3) then begin
+ Result := nil;
+ end
+ else begin
+ Result := TraceSweepInfoVTable(vTable).getPerfStats(Self);
+ end;
+end;
+
function ITraceLogWriter.write(buf: Pointer; size: Cardinal): Cardinal;
begin
Result := TraceLogWriterVTable(vTable).write(Self, buf, size);
@@ -10049,6 +10216,46 @@ function IProfilerStats.getElapsedTicks(): QWord;
Result := ProfilerStatsVTable(vTable).getElapsedTicks(Self);
end;
+function IPerformanceCounters.getObjectCount(): Cardinal;
+begin
+ Result := PerformanceCountersVTable(vTable).getObjectCount(Self);
+end;
+
+function IPerformanceCounters.getMaxCounterIndex(): Cardinal;
+begin
+ Result := PerformanceCountersVTable(vTable).getMaxCounterIndex(Self);
+end;
+
+function IPerformanceCounters.getObjectId(index: Cardinal): Cardinal;
+begin
+ Result := PerformanceCountersVTable(vTable).getObjectId(Self, index);
+end;
+
+function IPerformanceCounters.getObjectName(index: Cardinal): PAnsiChar;
+begin
+ Result := PerformanceCountersVTable(vTable).getObjectName(Self, index);
+end;
+
+function IPerformanceCounters.getObjectCounters(index: Cardinal): Int64Ptr;
+begin
+ Result := PerformanceCountersVTable(vTable).getObjectCounters(Self, index);
+end;
+
+function IPerformanceStats.getElapsedTime(): QWord;
+begin
+ Result := PerformanceStatsVTable(vTable).getElapsedTime(Self);
+end;
+
+function IPerformanceStats.getFetchedRecords(): QWord;
+begin
+ Result := PerformanceStatsVTable(vTable).getFetchedRecords(Self);
+end;
+
+function IPerformanceStats.getCounters(group: Cardinal): IPerformanceCounters;
+begin
+ Result := PerformanceStatsVTable(vTable).getCounters(Self, group);
+end;
+
var
IVersionedImpl_vTable: VersionedVTable;
@@ -15428,6 +15635,16 @@ function ITraceTransactionImpl_getPreviousIDDispatcher(this: ITraceTransaction):
end
end;
+function ITraceTransactionImpl_getPerfStatsDispatcher(this: ITraceTransaction): IPerformanceStats; cdecl;
+begin
+ Result := nil;
+ try
+ Result := ITraceTransactionImpl(this).getPerfStats();
+ except
+ on e: Exception do FbException.catchException(nil, e);
+ end
+end;
+
var
ITraceTransactionImpl_vTable: TraceTransactionVTable;
@@ -15494,6 +15711,16 @@ function ITraceStatementImpl_getPerfDispatcher(this: ITraceStatement): Performan
end
end;
+function ITraceStatementImpl_getPerfStatsDispatcher(this: ITraceStatement): IPerformanceStats; cdecl;
+begin
+ Result := nil;
+ try
+ Result := ITraceStatementImpl(this).getPerfStats();
+ except
+ on e: Exception do FbException.catchException(nil, e);
+ end
+end;
+
var
ITraceStatementImpl_vTable: TraceStatementVTable;
@@ -15522,6 +15749,16 @@ function ITraceSQLStatementImpl_getPerfDispatcher(this: ITraceSQLStatement): Per
end
end;
+function ITraceSQLStatementImpl_getPerfStatsDispatcher(this: ITraceSQLStatement): IPerformanceStats; cdecl;
+begin
+ Result := nil;
+ try
+ Result := ITraceSQLStatementImpl(this).getPerfStats();
+ except
+ on e: Exception do FbException.catchException(nil, e);
+ end
+end;
+
function ITraceSQLStatementImpl_getTextDispatcher(this: ITraceSQLStatement): PAnsiChar; cdecl;
begin
Result := nil;
@@ -15600,6 +15837,16 @@ function ITraceBLRStatementImpl_getPerfDispatcher(this: ITraceBLRStatement): Per
end
end;
+function ITraceBLRStatementImpl_getPerfStatsDispatcher(this: ITraceBLRStatement): IPerformanceStats; cdecl;
+begin
+ Result := nil;
+ try
+ Result := ITraceBLRStatementImpl(this).getPerfStats();
+ except
+ on e: Exception do FbException.catchException(nil, e);
+ end
+end;
+
function ITraceBLRStatementImpl_getDataDispatcher(this: ITraceBLRStatement): BytePtr; cdecl;
begin
Result := nil;
@@ -15774,6 +16021,16 @@ function ITraceProcedureImpl_getExplainedPlanDispatcher(this: ITraceProcedure):
end
end;
+function ITraceProcedureImpl_getPerfStatsDispatcher(this: ITraceProcedure): IPerformanceStats; cdecl;
+begin
+ Result := nil;
+ try
+ Result := ITraceProcedureImpl(this).getPerfStats();
+ except
+ on e: Exception do FbException.catchException(nil, e);
+ end
+end;
+
var
ITraceProcedureImpl_vTable: TraceProcedureVTable;
@@ -15852,6 +16109,16 @@ function ITraceFunctionImpl_getExplainedPlanDispatcher(this: ITraceFunction): PA
end
end;
+function ITraceFunctionImpl_getPerfStatsDispatcher(this: ITraceFunction): IPerformanceStats; cdecl;
+begin
+ Result := nil;
+ try
+ Result := ITraceFunctionImpl(this).getPerfStats();
+ except
+ on e: Exception do FbException.catchException(nil, e);
+ end
+end;
+
var
ITraceFunctionImpl_vTable: TraceFunctionVTable;
@@ -15940,6 +16207,16 @@ function ITraceTriggerImpl_getExplainedPlanDispatcher(this: ITraceTrigger): PAns
end
end;
+function ITraceTriggerImpl_getPerfStatsDispatcher(this: ITraceTrigger): IPerformanceStats; cdecl;
+begin
+ Result := nil;
+ try
+ Result := ITraceTriggerImpl(this).getPerfStats();
+ except
+ on e: Exception do FbException.catchException(nil, e);
+ end
+end;
+
var
ITraceTriggerImpl_vTable: TraceTriggerVTable;
@@ -16174,6 +16451,16 @@ function ITraceSweepInfoImpl_getPerfDispatcher(this: ITraceSweepInfo): Performan
end
end;
+function ITraceSweepInfoImpl_getPerfStatsDispatcher(this: ITraceSweepInfo): IPerformanceStats; cdecl;
+begin
+ Result := nil;
+ try
+ Result := ITraceSweepInfoImpl(this).getPerfStats();
+ except
+ on e: Exception do FbException.catchException(nil, e);
+ end
+end;
+
var
ITraceSweepInfoImpl_vTable: TraceSweepInfoVTable;
@@ -17543,6 +17830,102 @@ constructor IProfilerStatsImpl.create;
vTable := IProfilerStatsImpl_vTable;
end;
+function IPerformanceCountersImpl_getObjectCountDispatcher(this: IPerformanceCounters): Cardinal; cdecl;
+begin
+ Result := 0;
+ try
+ Result := IPerformanceCountersImpl(this).getObjectCount();
+ except
+ on e: Exception do FbException.catchException(nil, e);
+ end
+end;
+
+function IPerformanceCountersImpl_getMaxCounterIndexDispatcher(this: IPerformanceCounters): Cardinal; cdecl;
+begin
+ Result := 0;
+ try
+ Result := IPerformanceCountersImpl(this).getMaxCounterIndex();
+ except
+ on e: Exception do FbException.catchException(nil, e);
+ end
+end;
+
+function IPerformanceCountersImpl_getObjectIdDispatcher(this: IPerformanceCounters; index: Cardinal): Cardinal; cdecl;
+begin
+ Result := 0;
+ try
+ Result := IPerformanceCountersImpl(this).getObjectId(index);
+ except
+ on e: Exception do FbException.catchException(nil, e);
+ end
+end;
+
+function IPerformanceCountersImpl_getObjectNameDispatcher(this: IPerformanceCounters; index: Cardinal): PAnsiChar; cdecl;
+begin
+ Result := nil;
+ try
+ Result := IPerformanceCountersImpl(this).getObjectName(index);
+ except
+ on e: Exception do FbException.catchException(nil, e);
+ end
+end;
+
+function IPerformanceCountersImpl_getObjectCountersDispatcher(this: IPerformanceCounters; index: Cardinal): Int64Ptr; cdecl;
+begin
+ Result := nil;
+ try
+ Result := IPerformanceCountersImpl(this).getObjectCounters(index);
+ except
+ on e: Exception do FbException.catchException(nil, e);
+ end
+end;
+
+var
+ IPerformanceCountersImpl_vTable: PerformanceCountersVTable;
+
+constructor IPerformanceCountersImpl.create;
+begin
+ vTable := IPerformanceCountersImpl_vTable;
+end;
+
+function IPerformanceStatsImpl_getElapsedTimeDispatcher(this: IPerformanceStats): QWord; cdecl;
+begin
+ Result := 0;
+ try
+ Result := IPerformanceStatsImpl(this).getElapsedTime();
+ except
+ on e: Exception do FbException.catchException(nil, e);
+ end
+end;
+
+function IPerformanceStatsImpl_getFetchedRecordsDispatcher(this: IPerformanceStats): QWord; cdecl;
+begin
+ Result := 0;
+ try
+ Result := IPerformanceStatsImpl(this).getFetchedRecords();
+ except
+ on e: Exception do FbException.catchException(nil, e);
+ end
+end;
+
+function IPerformanceStatsImpl_getCountersDispatcher(this: IPerformanceStats; group: Cardinal): IPerformanceCounters; cdecl;
+begin
+ Result := nil;
+ try
+ Result := IPerformanceStatsImpl(this).getCounters(group);
+ except
+ on e: Exception do FbException.catchException(nil, e);
+ end
+end;
+
+var
+ IPerformanceStatsImpl_vTable: PerformanceStatsVTable;
+
+constructor IPerformanceStatsImpl.create;
+begin
+ vTable := IPerformanceStatsImpl_vTable;
+end;
+
constructor FbException.create(status: IStatus);
begin
inherited Create('FbException');
@@ -18308,7 +18691,7 @@ initialization
ITraceDatabaseConnectionImpl_vTable.getDatabaseName := @ITraceDatabaseConnectionImpl_getDatabaseNameDispatcher;
ITraceTransactionImpl_vTable := TraceTransactionVTable.create;
- ITraceTransactionImpl_vTable.version := 3;
+ ITraceTransactionImpl_vTable.version := 4;
ITraceTransactionImpl_vTable.getTransactionID := @ITraceTransactionImpl_getTransactionIDDispatcher;
ITraceTransactionImpl_vTable.getReadOnly := @ITraceTransactionImpl_getReadOnlyDispatcher;
ITraceTransactionImpl_vTable.getWait := @ITraceTransactionImpl_getWaitDispatcher;
@@ -18316,6 +18699,7 @@ initialization
ITraceTransactionImpl_vTable.getPerf := @ITraceTransactionImpl_getPerfDispatcher;
ITraceTransactionImpl_vTable.getInitialID := @ITraceTransactionImpl_getInitialIDDispatcher;
ITraceTransactionImpl_vTable.getPreviousID := @ITraceTransactionImpl_getPreviousIDDispatcher;
+ ITraceTransactionImpl_vTable.getPerfStats := @ITraceTransactionImpl_getPerfStatsDispatcher;
ITraceParamsImpl_vTable := TraceParamsVTable.create;
ITraceParamsImpl_vTable.version := 3;
@@ -18324,14 +18708,16 @@ initialization
ITraceParamsImpl_vTable.getTextUTF8 := @ITraceParamsImpl_getTextUTF8Dispatcher;
ITraceStatementImpl_vTable := TraceStatementVTable.create;
- ITraceStatementImpl_vTable.version := 2;
+ ITraceStatementImpl_vTable.version := 3;
ITraceStatementImpl_vTable.getStmtID := @ITraceStatementImpl_getStmtIDDispatcher;
ITraceStatementImpl_vTable.getPerf := @ITraceStatementImpl_getPerfDispatcher;
+ ITraceStatementImpl_vTable.getPerfStats := @ITraceStatementImpl_getPerfStatsDispatcher;
ITraceSQLStatementImpl_vTable := TraceSQLStatementVTable.create;
- ITraceSQLStatementImpl_vTable.version := 3;
+ ITraceSQLStatementImpl_vTable.version := 4;
ITraceSQLStatementImpl_vTable.getStmtID := @ITraceSQLStatementImpl_getStmtIDDispatcher;
ITraceSQLStatementImpl_vTable.getPerf := @ITraceSQLStatementImpl_getPerfDispatcher;
+ ITraceSQLStatementImpl_vTable.getPerfStats := @ITraceSQLStatementImpl_getPerfStatsDispatcher;
ITraceSQLStatementImpl_vTable.getText := @ITraceSQLStatementImpl_getTextDispatcher;
ITraceSQLStatementImpl_vTable.getPlan := @ITraceSQLStatementImpl_getPlanDispatcher;
ITraceSQLStatementImpl_vTable.getInputs := @ITraceSQLStatementImpl_getInputsDispatcher;
@@ -18339,9 +18725,10 @@ initialization
ITraceSQLStatementImpl_vTable.getExplainedPlan := @ITraceSQLStatementImpl_getExplainedPlanDispatcher;
ITraceBLRStatementImpl_vTable := TraceBLRStatementVTable.create;
- ITraceBLRStatementImpl_vTable.version := 3;
+ ITraceBLRStatementImpl_vTable.version := 4;
ITraceBLRStatementImpl_vTable.getStmtID := @ITraceBLRStatementImpl_getStmtIDDispatcher;
ITraceBLRStatementImpl_vTable.getPerf := @ITraceBLRStatementImpl_getPerfDispatcher;
+ ITraceBLRStatementImpl_vTable.getPerfStats := @ITraceBLRStatementImpl_getPerfStatsDispatcher;
ITraceBLRStatementImpl_vTable.getData := @ITraceBLRStatementImpl_getDataDispatcher;
ITraceBLRStatementImpl_vTable.getDataLength := @ITraceBLRStatementImpl_getDataLengthDispatcher;
ITraceBLRStatementImpl_vTable.getText := @ITraceBLRStatementImpl_getTextDispatcher;
@@ -18359,16 +18746,17 @@ initialization
ITraceContextVariableImpl_vTable.getVarValue := @ITraceContextVariableImpl_getVarValueDispatcher;
ITraceProcedureImpl_vTable := TraceProcedureVTable.create;
- ITraceProcedureImpl_vTable.version := 3;
+ ITraceProcedureImpl_vTable.version := 4;
ITraceProcedureImpl_vTable.getProcName := @ITraceProcedureImpl_getProcNameDispatcher;
ITraceProcedureImpl_vTable.getInputs := @ITraceProcedureImpl_getInputsDispatcher;
ITraceProcedureImpl_vTable.getPerf := @ITraceProcedureImpl_getPerfDispatcher;
ITraceProcedureImpl_vTable.getStmtID := @ITraceProcedureImpl_getStmtIDDispatcher;
ITraceProcedureImpl_vTable.getPlan := @ITraceProcedureImpl_getPlanDispatcher;
ITraceProcedureImpl_vTable.getExplainedPlan := @ITraceProcedureImpl_getExplainedPlanDispatcher;
+ ITraceProcedureImpl_vTable.getPerfStats := @ITraceProcedureImpl_getPerfStatsDispatcher;
ITraceFunctionImpl_vTable := TraceFunctionVTable.create;
- ITraceFunctionImpl_vTable.version := 3;
+ ITraceFunctionImpl_vTable.version := 4;
ITraceFunctionImpl_vTable.getFuncName := @ITraceFunctionImpl_getFuncNameDispatcher;
ITraceFunctionImpl_vTable.getInputs := @ITraceFunctionImpl_getInputsDispatcher;
ITraceFunctionImpl_vTable.getResult := @ITraceFunctionImpl_getResultDispatcher;
@@ -18376,9 +18764,10 @@ initialization
ITraceFunctionImpl_vTable.getStmtID := @ITraceFunctionImpl_getStmtIDDispatcher;
ITraceFunctionImpl_vTable.getPlan := @ITraceFunctionImpl_getPlanDispatcher;
ITraceFunctionImpl_vTable.getExplainedPlan := @ITraceFunctionImpl_getExplainedPlanDispatcher;
+ ITraceFunctionImpl_vTable.getPerfStats := @ITraceFunctionImpl_getPerfStatsDispatcher;
ITraceTriggerImpl_vTable := TraceTriggerVTable.create;
- ITraceTriggerImpl_vTable.version := 3;
+ ITraceTriggerImpl_vTable.version := 4;
ITraceTriggerImpl_vTable.getTriggerName := @ITraceTriggerImpl_getTriggerNameDispatcher;
ITraceTriggerImpl_vTable.getRelationName := @ITraceTriggerImpl_getRelationNameDispatcher;
ITraceTriggerImpl_vTable.getAction := @ITraceTriggerImpl_getActionDispatcher;
@@ -18387,6 +18776,7 @@ initialization
ITraceTriggerImpl_vTable.getStmtID := @ITraceTriggerImpl_getStmtIDDispatcher;
ITraceTriggerImpl_vTable.getPlan := @ITraceTriggerImpl_getPlanDispatcher;
ITraceTriggerImpl_vTable.getExplainedPlan := @ITraceTriggerImpl_getExplainedPlanDispatcher;
+ ITraceTriggerImpl_vTable.getPerfStats := @ITraceTriggerImpl_getPerfStatsDispatcher;
ITraceServiceConnectionImpl_vTable := TraceServiceConnectionVTable.create;
ITraceServiceConnectionImpl_vTable.version := 3;
@@ -18411,12 +18801,13 @@ initialization
ITraceStatusVectorImpl_vTable.getText := @ITraceStatusVectorImpl_getTextDispatcher;
ITraceSweepInfoImpl_vTable := TraceSweepInfoVTable.create;
- ITraceSweepInfoImpl_vTable.version := 2;
+ ITraceSweepInfoImpl_vTable.version := 3;
ITraceSweepInfoImpl_vTable.getOIT := @ITraceSweepInfoImpl_getOITDispatcher;
ITraceSweepInfoImpl_vTable.getOST := @ITraceSweepInfoImpl_getOSTDispatcher;
ITraceSweepInfoImpl_vTable.getOAT := @ITraceSweepInfoImpl_getOATDispatcher;
ITraceSweepInfoImpl_vTable.getNext := @ITraceSweepInfoImpl_getNextDispatcher;
ITraceSweepInfoImpl_vTable.getPerf := @ITraceSweepInfoImpl_getPerfDispatcher;
+ ITraceSweepInfoImpl_vTable.getPerfStats := @ITraceSweepInfoImpl_getPerfStatsDispatcher;
ITraceLogWriterImpl_vTable := TraceLogWriterVTable.create;
ITraceLogWriterImpl_vTable.version := 4;
@@ -18600,6 +18991,20 @@ initialization
IProfilerStatsImpl_vTable.version := 2;
IProfilerStatsImpl_vTable.getElapsedTicks := @IProfilerStatsImpl_getElapsedTicksDispatcher;
+ IPerformanceCountersImpl_vTable := PerformanceCountersVTable.create;
+ IPerformanceCountersImpl_vTable.version := 2;
+ IPerformanceCountersImpl_vTable.getObjectCount := @IPerformanceCountersImpl_getObjectCountDispatcher;
+ IPerformanceCountersImpl_vTable.getMaxCounterIndex := @IPerformanceCountersImpl_getMaxCounterIndexDispatcher;
+ IPerformanceCountersImpl_vTable.getObjectId := @IPerformanceCountersImpl_getObjectIdDispatcher;
+ IPerformanceCountersImpl_vTable.getObjectName := @IPerformanceCountersImpl_getObjectNameDispatcher;
+ IPerformanceCountersImpl_vTable.getObjectCounters := @IPerformanceCountersImpl_getObjectCountersDispatcher;
+
+ IPerformanceStatsImpl_vTable := PerformanceStatsVTable.create;
+ IPerformanceStatsImpl_vTable.version := 2;
+ IPerformanceStatsImpl_vTable.getElapsedTime := @IPerformanceStatsImpl_getElapsedTimeDispatcher;
+ IPerformanceStatsImpl_vTable.getFetchedRecords := @IPerformanceStatsImpl_getFetchedRecordsDispatcher;
+ IPerformanceStatsImpl_vTable.getCounters := @IPerformanceStatsImpl_getCountersDispatcher;
+
finalization
IVersionedImpl_vTable.destroy;
IReferenceCountedImpl_vTable.destroy;
@@ -18699,5 +19104,7 @@ finalization
IProfilerPluginImpl_vTable.destroy;
IProfilerSessionImpl_vTable.destroy;
IProfilerStatsImpl_vTable.destroy;
+ IPerformanceCountersImpl_vTable.destroy;
+ IPerformanceStatsImpl_vTable.destroy;
end.
diff --git a/src/jrd/Monitoring.cpp b/src/jrd/Monitoring.cpp
index ea09c3daa32..07f64418679 100644
--- a/src/jrd/Monitoring.cpp
+++ b/src/jrd/Monitoring.cpp
@@ -1451,36 +1451,39 @@ void Monitoring::putStatistics(SnapshotData::DumpRecord& record, const RuntimeSt
// logical I/O statistics (table wise)
- for (auto iter(statistics.getRelCounters()); iter; ++iter)
+ for (const auto& counts : statistics.getTableCounters())
{
+ if (counts.isEmpty())
+ continue;
+
const auto rec_stat_id = getGlobalId(fb_utils::genUniqueId());
record.reset(rel_mon_tab_stats);
record.storeGlobalId(f_mon_tab_stat_id, id);
record.storeInteger(f_mon_tab_stat_group, stat_group);
- record.storeTableIdSchemaName(f_mon_tab_sch_name, (*iter).getRelationId());
- record.storeTableIdObjectName(f_mon_tab_name, (*iter).getRelationId());
+ record.storeTableIdSchemaName(f_mon_tab_sch_name, counts.getGroupId());
+ record.storeTableIdObjectName(f_mon_tab_name, counts.getGroupId());
record.storeGlobalId(f_mon_tab_rec_stat_id, rec_stat_id);
record.write();
record.reset(rel_mon_rec_stats);
record.storeGlobalId(f_mon_rec_stat_id, rec_stat_id);
record.storeInteger(f_mon_rec_stat_group, stat_group);
- record.storeInteger(f_mon_rec_seq_reads, (*iter)[RecordStatType::SEQ_READS]);
- record.storeInteger(f_mon_rec_idx_reads, (*iter)[RecordStatType::IDX_READS]);
- record.storeInteger(f_mon_rec_inserts, (*iter)[RecordStatType::INSERTS]);
- record.storeInteger(f_mon_rec_updates, (*iter)[RecordStatType::UPDATES]);
- record.storeInteger(f_mon_rec_deletes, (*iter)[RecordStatType::DELETES]);
- record.storeInteger(f_mon_rec_backouts, (*iter)[RecordStatType::BACKOUTS]);
- record.storeInteger(f_mon_rec_purges, (*iter)[RecordStatType::PURGES]);
- record.storeInteger(f_mon_rec_expunges, (*iter)[RecordStatType::EXPUNGES]);
- record.storeInteger(f_mon_rec_locks, (*iter)[RecordStatType::LOCKS]);
- record.storeInteger(f_mon_rec_waits, (*iter)[RecordStatType::WAITS]);
- record.storeInteger(f_mon_rec_conflicts, (*iter)[RecordStatType::CONFLICTS]);
- record.storeInteger(f_mon_rec_bkver_reads, (*iter)[RecordStatType::BACK_READS]);
- record.storeInteger(f_mon_rec_frg_reads, (*iter)[RecordStatType::FRAGMENT_READS]);
- record.storeInteger(f_mon_rec_rpt_reads, (*iter)[RecordStatType::RPT_READS]);
- record.storeInteger(f_mon_rec_imgc, (*iter)[RecordStatType::IMGC]);
+ record.storeInteger(f_mon_rec_seq_reads, counts[RecordStatType::SEQ_READS]);
+ record.storeInteger(f_mon_rec_idx_reads, counts[RecordStatType::IDX_READS]);
+ record.storeInteger(f_mon_rec_inserts, counts[RecordStatType::INSERTS]);
+ record.storeInteger(f_mon_rec_updates, counts[RecordStatType::UPDATES]);
+ record.storeInteger(f_mon_rec_deletes, counts[RecordStatType::DELETES]);
+ record.storeInteger(f_mon_rec_backouts, counts[RecordStatType::BACKOUTS]);
+ record.storeInteger(f_mon_rec_purges, counts[RecordStatType::PURGES]);
+ record.storeInteger(f_mon_rec_expunges, counts[RecordStatType::EXPUNGES]);
+ record.storeInteger(f_mon_rec_locks, counts[RecordStatType::LOCKS]);
+ record.storeInteger(f_mon_rec_waits, counts[RecordStatType::WAITS]);
+ record.storeInteger(f_mon_rec_conflicts, counts[RecordStatType::CONFLICTS]);
+ record.storeInteger(f_mon_rec_bkver_reads, counts[RecordStatType::BACK_READS]);
+ record.storeInteger(f_mon_rec_frg_reads, counts[RecordStatType::FRAGMENT_READS]);
+ record.storeInteger(f_mon_rec_rpt_reads, counts[RecordStatType::RPT_READS]);
+ record.storeInteger(f_mon_rec_imgc, counts[RecordStatType::IMGC]);
record.write();
}
}
diff --git a/src/jrd/RuntimeStatistics.cpp b/src/jrd/RuntimeStatistics.cpp
index 95630662623..d4ce6474d6f 100644
--- a/src/jrd/RuntimeStatistics.cpp
+++ b/src/jrd/RuntimeStatistics.cpp
@@ -33,52 +33,75 @@ namespace Jrd {
GlobalPtr RuntimeStatistics::dummy;
-void RuntimeStatistics::adjustRelStats(const RuntimeStatistics& baseStats, const RuntimeStatistics& newStats)
+void RuntimeStatistics::adjust(const RuntimeStatistics& baseStats, const RuntimeStatistics& newStats)
{
- if (baseStats.relChgNumber == newStats.relChgNumber)
+ if (baseStats.allChgNumber == newStats.allChgNumber)
return;
- relChgNumber++;
+ allChgNumber++;
+ for (size_t i = 0; i < GLOBAL_ITEMS; ++i)
+ values[i] += newStats.values[i] - baseStats.values[i];
+
+ if (baseStats.pageChgNumber != newStats.pageChgNumber)
+ {
+ pageChgNumber++;
+ pageCounters.adjust(baseStats.pageCounters, newStats.pageCounters);
+ }
+
+ if (baseStats.tabChgNumber != newStats.tabChgNumber)
+ {
+ tabChgNumber++;
+ tableCounters.adjust(baseStats.tableCounters, newStats.tableCounters);
+ }
+}
- auto locate = [this](SLONG relId) -> FB_SIZE_T
+void RuntimeStatistics::adjustPageStats(RuntimeStatistics& baseStats, const RuntimeStatistics& newStats)
+{
+ if (baseStats.allChgNumber == newStats.allChgNumber)
+ return;
+
+ allChgNumber++;
+ for (size_t i = 0; i < PAGE_TOTAL_ITEMS; ++i)
{
- FB_SIZE_T pos;
- if (!rel_counts.find(relId, pos))
- rel_counts.insert(pos, RelationCounts(relId));
- return pos;
- };
+ const SINT64 delta = newStats.values[i] - baseStats.values[i];
- auto baseIter = baseStats.rel_counts.begin(), newIter = newStats.rel_counts.begin();
- const auto baseEnd = baseStats.rel_counts.end(), newEnd = newStats.rel_counts.end();
+ values[i] += delta;
+ baseStats.values[i] += delta;
+ }
+}
+
+template
+void RuntimeStatistics::GroupedCountsArray::adjust(const GroupedCountsArray& baseStats, const GroupedCountsArray& newStats)
+{
+ auto baseIter = baseStats.m_counts.begin(), newIter = newStats.m_counts.begin();
+ const auto baseEnd = baseStats.m_counts.end(), newEnd = newStats.m_counts.end();
- // The loop below assumes that newStats cannot miss relations existing in baseStats,
+ // The loop below assumes that newStats cannot miss objects existing in baseStats,
// this must be always the case as long as newStats is an incremented version of baseStats
while (newIter != newEnd || baseIter != baseEnd)
{
if (baseIter == baseEnd)
{
- // Relation exists in newStats but missing in baseStats
- const auto newRelId = newIter->getRelationId();
- rel_counts[locate(newRelId)] += *newIter++;
+ // Object exists in newStats but missing in baseStats
+ const auto newId = newIter->getGroupId();
+ (*this)[newId] += *newIter++;
}
else if (newIter != newEnd)
{
- const auto baseRelId = baseIter->getRelationId();
- const auto newRelId = newIter->getRelationId();
+ const auto baseId = baseIter->getGroupId();
+ const auto newId = newIter->getGroupId();
- if (newRelId == baseRelId)
+ if (newId == baseId)
{
- // Relation exists in both newStats and baseStats
- fb_assert(baseRelId == newRelId);
- const auto pos = locate(baseRelId);
- rel_counts[pos] -= *baseIter++;
- rel_counts[pos] += *newIter++;
+ // Object exists in both newStats and baseStats
+ (*this)[newId] += *newIter++;
+ (*this)[newId] -= *baseIter++;
}
- else if (newRelId < baseRelId)
+ else if (newId < baseId)
{
- // Relation exists in newStats but missing in baseStats
- rel_counts[locate(newRelId)] += *newIter++;
+ // Object exists in newStats but missing in baseStats
+ (*this)[newId] += *newIter++;
}
else
fb_assert(false); // should never happen
@@ -88,114 +111,23 @@ void RuntimeStatistics::adjustRelStats(const RuntimeStatistics& baseStats, const
}
}
-PerformanceInfo* RuntimeStatistics::computeDifference(Attachment* att,
- const RuntimeStatistics& new_stat,
- PerformanceInfo& dest,
- TraceCountsArray& temp,
- ObjectsArray& tempNames)
+void RuntimeStatistics::setToDiff(const RuntimeStatistics& newStats)
{
- // NOTE: we do not initialize dest.pin_time. This must be done by the caller
-
- // Calculate database-level statistics
for (size_t i = 0; i < GLOBAL_ITEMS; i++)
- values[i] = new_stat.values[i] - values[i];
+ values[i] = newStats.values[i] - values[i];
- dest.pin_counters = values;
-
- // Calculate relation-level statistics
- temp.clear();
- tempNames.clear();
-
- // This loop assumes that base array is smaller than new one
- RelCounters::iterator base_cnts = rel_counts.begin();
- bool base_found = (base_cnts != rel_counts.end());
-
- for (const auto& new_cnts : new_stat.rel_counts)
+ for (const auto& newCounts : newStats.pageCounters)
{
- const SLONG rel_id = new_cnts.getRelationId();
-
- if (base_found && base_cnts->getRelationId() == rel_id)
- {
- // Point TraceCounts to counts array from baseline object
- if (base_cnts->setToDiff(new_cnts))
- {
- jrd_rel* const relation =
- rel_id < static_cast(att->att_relations->count()) ?
- (*att->att_relations)[rel_id] : NULL;
-
- TraceCounts traceCounts;
- traceCounts.trc_relation_id = rel_id;
- traceCounts.trc_counters = base_cnts->getCounterVector();
-
- if (relation)
- {
- auto& tempName = tempNames.add();
- tempName = relation->rel_name.toQuotedString();
- traceCounts.trc_relation_name = tempName.c_str();
- }
- else
- traceCounts.trc_relation_name = nullptr;
-
- temp.add(traceCounts);
- }
-
- ++base_cnts;
- base_found = (base_cnts != rel_counts.end());
- }
- else
- {
- jrd_rel* const relation =
- rel_id < static_cast(att->att_relations->count()) ?
- (*att->att_relations)[rel_id] : NULL;
-
- // Point TraceCounts to counts array from object with updated counters
- TraceCounts traceCounts;
- traceCounts.trc_relation_id = rel_id;
- traceCounts.trc_counters = new_cnts.getCounterVector();
-
- if (relation)
- {
- auto& tempName = tempNames.add();
- tempName = relation->rel_name.toQuotedString();
- traceCounts.trc_relation_name = tempName.c_str();
- }
- else
- traceCounts.trc_relation_name = nullptr;
-
- temp.add(traceCounts);
- }
- };
-
- dest.pin_count = temp.getCount();
- dest.pin_tables = temp.begin();
-
- return &dest;
-}
-
-void RuntimeStatistics::adjust(const RuntimeStatistics& baseStats, const RuntimeStatistics& newStats)
-{
- if (baseStats.allChgNumber == newStats.allChgNumber)
- return;
-
- allChgNumber++;
- for (size_t i = 0; i < GLOBAL_ITEMS; ++i)
- values[i] += newStats.values[i] - baseStats.values[i];
-
- adjustRelStats(baseStats, newStats);
-}
-
-void RuntimeStatistics::adjustPageStats(RuntimeStatistics& baseStats, const RuntimeStatistics& newStats)
-{
- if (baseStats.allChgNumber == newStats.allChgNumber)
- return;
+ const auto pageSpaceId = newCounts.getGroupId();
+ if (!pageCounters[pageSpaceId].setToDiff(newCounts))
+ pageCounters.remove(pageSpaceId);
+ }
- allChgNumber++;
- for (size_t i = 0; i < PAGE_TOTAL_ITEMS; ++i)
+ for (const auto& newCounts : newStats.tableCounters)
{
- const SINT64 delta = newStats.values[i] - baseStats.values[i];
-
- values[i] += delta;
- baseStats.values[i] += delta;
+ const auto relationId = newCounts.getGroupId();
+ if (!tableCounters[relationId].setToDiff(newCounts))
+ tableCounters.remove(relationId);
}
}
diff --git a/src/jrd/RuntimeStatistics.h b/src/jrd/RuntimeStatistics.h
index d340cd0d079..3db58932ab0 100644
--- a/src/jrd/RuntimeStatistics.h
+++ b/src/jrd/RuntimeStatistics.h
@@ -29,19 +29,11 @@
#include "../common/classes/init.h"
#include "../common/classes/tree.h"
#include "../common/classes/File.h"
+#include "../jrd/ini.h"
+#include "../jrd/pag.h"
#include
-namespace Firebird
-{
-
-// declared in firebird/Interface.h
-struct TraceCounts;
-struct PerformanceInfo;
-
-} // namespace Firebird
-
-
namespace Jrd {
class Attachment;
@@ -49,7 +41,6 @@ class Database;
class thread_db;
class jrd_rel;
-typedef Firebird::HalfStaticArray TraceCountsArray;
// Runtime statistics
@@ -92,7 +83,7 @@ class RuntimeStatistics : protected Firebird::AutoStorage
//
// dimitr: Currently, they include page-level and record-level counters.
// However, this is not strictly required to maintain global record-level counters,
- // as they may be aggregated from the rel_counts array on demand. This would slow down
+ // as they may be aggregated from the tableCounters array on demand. This would slow down
// the retrieval of counters but save some CPU cycles inside tdbb->bumpStats().
// As long as public struct PerformanceInfo don't include record-level counters,
// this is not going to affect any existing applications/plugins.
@@ -135,6 +126,24 @@ class RuntimeStatistics : protected Firebird::AutoStorage
return *this;
}
+ bool setToDiff(const CountsVector& other)
+ {
+ bool ret = false;
+
+ for (size_t i = 0; i < m_counters.size(); i++)
+ {
+ if ( (m_counters[i] = other.m_counters[i] - m_counters[i]) )
+ ret = true;
+ }
+
+ return ret;
+ }
+
+ static unsigned getVectorCapacity()
+ {
+ return (unsigned) SIZE;
+ }
+
const SINT64* getCounterVector() const
{
return m_counters.data();
@@ -156,104 +165,187 @@ class RuntimeStatistics : protected Firebird::AutoStorage
std::array m_counters = {};
};
- // Performance counters for individual table
-
- class RelationCounts : public CountsVector
+ template
+ class CountsGroup : public CountsVector
{
public:
- explicit RelationCounts(SLONG relation_id)
- : m_relation_id(relation_id)
+ typedef Key ID;
+
+ explicit CountsGroup(ID id)
+ : m_id(id)
+ {}
+
+ ID getGroupId() const
{
+ return m_id;
}
- SLONG getRelationId() const
+ CountsGroup& operator+=(const CountsGroup& other)
{
- return m_relation_id;
+ fb_assert(m_id == other.m_id);
+ CountsVector::operator+=(other);
+ return *this;
}
- bool setToDiff(const RelationCounts& other)
+ CountsGroup& operator-=(const CountsGroup& other)
{
- fb_assert(m_relation_id == other.m_relation_id);
+ fb_assert(m_id == other.m_id);
+ CountsVector::operator-=(other);
+ return *this;
+ }
- bool ret = false;
+ bool setToDiff(const CountsGroup& other)
+ {
+ fb_assert(m_id == other.m_id);
+ return CountsVector::setToDiff(other);
+ }
- for (size_t i = 0; i < m_counters.size(); i++)
+ inline static const ID& generate(const CountsGroup& item)
+ {
+ return item.m_id;
+ }
+
+ private:
+ ID m_id;
+ };
+
+ template
+ class GroupedCountsArray
+ {
+ typedef typename Counts::ID ID;
+ typedef Firebird::SortedArray<
+ Counts, Firebird::EmptyStorage, ID, Counts> SortedCountsArray;
+ typedef typename SortedCountsArray::const_iterator ConstIterator;
+
+ public:
+ GroupedCountsArray(MemoryPool& pool, FB_SIZE_T capacity)
+ : m_counts(pool, capacity)
+ {}
+
+ GroupedCountsArray(MemoryPool& pool, const GroupedCountsArray& other)
+ : m_counts(pool, other.m_counts.getCapacity())
+ {}
+
+ Counts& operator[](ID id)
+ {
+ if ((m_lastPos != (FB_SIZE_T) ~0 && m_counts[m_lastPos].getGroupId() == id) ||
+ // if m_lastPos is mispositioned
+ m_counts.find(id, m_lastPos))
{
- if ( (m_counters[i] = other.m_counters[i] - m_counters[i]) )
- ret = true;
+ return m_counts[m_lastPos];
}
- return ret;
+ Counts counts(id);
+ m_counts.insert(m_lastPos, counts);
+ return m_counts[m_lastPos];
}
- RelationCounts& operator+=(const RelationCounts& other)
+ unsigned getCount() const
{
- fb_assert(m_relation_id == other.m_relation_id);
- CountsVector::operator+=(other);
- return *this;
+ return m_counts.getCount();
}
- RelationCounts& operator-=(const RelationCounts& other)
+ static unsigned getVectorCapacity()
{
- fb_assert(m_relation_id == other.m_relation_id);
- CountsVector::operator-=(other);
- return *this;
+ return Counts::getVectorCapacity();
+ }
+
+ void remove(ID id)
+ {
+ if ((m_lastPos != (FB_SIZE_T) ~0 && m_counts[m_lastPos].getGroupId() == id) ||
+ // if m_lastPos is mispositioned
+ m_counts.find(id, m_lastPos))
+ {
+ m_counts.remove(m_lastPos);
+ m_lastPos = (FB_SIZE_T) ~0;
+ }
+ }
+
+ void reset()
+ {
+ m_counts.clear();
+ m_lastPos = (FB_SIZE_T) ~0;
}
- inline static const SLONG& generate(const RelationCounts& item)
+ ConstIterator begin() const
{
- return item.m_relation_id;
+ return m_counts.begin();
}
+ ConstIterator end() const
+ {
+ return m_counts.end();
+ }
+
+ void adjust(const GroupedCountsArray& baseStats, const GroupedCountsArray& newStats);
+
private:
- SLONG m_relation_id;
+ SortedCountsArray m_counts;
+ FB_SIZE_T m_lastPos = (FB_SIZE_T) ~0;
};
- typedef Firebird::SortedArray,
- SLONG, RelationCounts> RelCounters;
-
public:
+ typedef GroupedCountsArray > PageCounters;
+ typedef GroupedCountsArray > TableCounters;
+
RuntimeStatistics()
- : Firebird::AutoStorage(), rel_counts(getPool())
+ : Firebird::AutoStorage(),
+ pageCounters(getPool(), DB_PAGE_SPACE + 1),
+ tableCounters(getPool(), rel_MAX)
{
reset();
}
explicit RuntimeStatistics(MemoryPool& pool)
- : Firebird::AutoStorage(pool), rel_counts(getPool())
+ : Firebird::AutoStorage(pool),
+ pageCounters(getPool(), DB_PAGE_SPACE + 1),
+ tableCounters(getPool(), rel_MAX)
{
reset();
}
RuntimeStatistics(const RuntimeStatistics& other)
- : Firebird::AutoStorage(), rel_counts(getPool())
+ : Firebird::AutoStorage(),
+ pageCounters(getPool(), other.pageCounters),
+ tableCounters(getPool(), other.tableCounters)
{
memcpy(values, other.values, sizeof(values));
- rel_counts = other.rel_counts;
+
+ pageCounters = other.pageCounters;
+ tableCounters = other.tableCounters;
allChgNumber = other.allChgNumber;
- relChgNumber = other.relChgNumber;
+ pageChgNumber = other.pageChgNumber;
+ tabChgNumber = other.tabChgNumber;
}
RuntimeStatistics(MemoryPool& pool, const RuntimeStatistics& other)
- : Firebird::AutoStorage(pool), rel_counts(getPool())
+ : Firebird::AutoStorage(pool),
+ pageCounters(getPool(), other.pageCounters),
+ tableCounters(getPool(), other.tableCounters)
{
memcpy(values, other.values, sizeof(values));
- rel_counts = other.rel_counts;
+
+ pageCounters = other.pageCounters;
+ tableCounters = other.tableCounters;
allChgNumber = other.allChgNumber;
- relChgNumber = other.relChgNumber;
+ pageChgNumber = other.pageChgNumber;
+ tabChgNumber = other.tabChgNumber;
}
~RuntimeStatistics() = default;
void reset()
{
- memset(values, 0, sizeof values);
- rel_counts.clear();
- rel_last_pos = (FB_SIZE_T) ~0;
+ memset(values, 0, sizeof(values));
+
+ pageCounters.reset();
+ tableCounters.reset();
+
allChgNumber = 0;
- relChgNumber = 0;
+ pageChgNumber = 0;
+ tabChgNumber = 0;
}
const SINT64& operator[](const PageStatType type) const
@@ -262,11 +354,17 @@ class RuntimeStatistics : protected Firebird::AutoStorage
return values[index];
}
- void bumpValue(const PageStatType type, SINT64 delta = 1)
+ void bumpValue(const PageStatType type, ULONG pageSpaceId, SINT64 delta = 1)
{
+ ++allChgNumber;
const auto index = static_cast(type);
values[index] += delta;
- ++allChgNumber;
+
+ if (isValid()) // optimization for non-trivial data access
+ {
+ ++pageChgNumber;
+ pageCounters[pageSpaceId][type] += delta;
+ }
}
const SINT64& operator[](const RecordStatType type) const
@@ -279,42 +377,28 @@ class RuntimeStatistics : protected Firebird::AutoStorage
{
SINT64 value = 0;
- for (const auto& counts : rel_counts)
+ for (const auto& counts : tableCounters)
value += counts[type];
return value;
}
- void bumpValue(const RecordStatType type, SINT64 delta = 1)
+ void bumpValue(const RecordStatType type, SLONG relationId, SINT64 delta = 1)
{
+ ++allChgNumber;
const auto index = static_cast(type);
values[PAGE_TOTAL_ITEMS + index] += delta;
- ++allChgNumber;
- }
- void bumpValue(const RecordStatType type, SLONG relation_id, SINT64 delta = 1)
- {
- ++allChgNumber;
- ++relChgNumber;
-
- if ((rel_last_pos != (FB_SIZE_T)~0 && rel_counts[rel_last_pos].getRelationId() == relation_id) ||
- // if rel_last_pos is mispositioned
- rel_counts.find(relation_id, rel_last_pos))
- {
- rel_counts[rel_last_pos][type] += delta;
- }
- else
+ if (isValid()) // optimization for non-trivial data access
{
- RelationCounts counts(relation_id);
- counts[type] += delta;
- rel_counts.insert(rel_last_pos, counts);
+ ++tabChgNumber;
+ tableCounters[relationId][type] += delta;
}
}
// Calculate difference between counts stored in this object and current
// counts of given request. Counts stored in object are destroyed.
- Firebird::PerformanceInfo* computeDifference(Attachment* att, const RuntimeStatistics& new_stat,
- Firebird::PerformanceInfo& dest, TraceCountsArray& temp, Firebird::ObjectsArray& tempNames);
+ void setToDiff(const RuntimeStatistics& newStats);
// Add difference between newStats and baseStats to our counters
// (newStats and baseStats must be "in-sync")
@@ -331,16 +415,27 @@ class RuntimeStatistics : protected Firebird::AutoStorage
memcpy(values, other.values, sizeof(values));
allChgNumber = other.allChgNumber;
- if (relChgNumber != other.relChgNumber)
+ if (pageChgNumber != other.pageChgNumber)
{
- rel_counts = other.rel_counts;
- relChgNumber = other.relChgNumber;
+ pageCounters = other.pageCounters;
+ pageChgNumber = other.pageChgNumber;
+ }
+
+ if (tabChgNumber != other.tabChgNumber)
+ {
+ tableCounters = other.tableCounters;
+ tabChgNumber = other.tabChgNumber;
}
}
return *this;
}
+ bool isValid() const
+ {
+ return (this != &dummy);
+ }
+
static RuntimeStatistics* getDummy()
{
return &dummy;
@@ -364,62 +459,28 @@ class RuntimeStatistics : protected Firebird::AutoStorage
SINT64 m_counter = 0;
};
- template class Iterator
+ const PageCounters& getPageCounters() const
{
- public:
- explicit Iterator(const T& counts)
- : m_iter(counts.begin()), m_end(counts.end())
- {
- advance();
- }
-
- void operator++()
- {
- m_iter++;
- advance();
- }
-
- typename T::const_reference operator*() const
- {
- return *m_iter;
- }
-
- operator bool() const
- {
- return (m_iter != m_end);
- }
-
- private:
- typename T::const_iterator m_iter;
- const typename T::const_iterator m_end;
-
- void advance()
- {
- while (m_iter != m_end && m_iter->isEmpty())
- m_iter++;
- }
- };
-
- typedef Iterator RelationIterator;
+ return pageCounters;
+ }
- RelationIterator getRelCounters() const
+ const TableCounters& getTableCounters() const
{
- return RelationIterator(rel_counts);
+ return tableCounters;
}
private:
- void adjustRelStats(const RuntimeStatistics& baseStats, const RuntimeStatistics& newStats);
-
SINT64 values[GLOBAL_ITEMS];
- RelCounters rel_counts;
- FB_SIZE_T rel_last_pos;
+ PageCounters pageCounters;
+ TableCounters tableCounters;
- // These three numbers are used in adjust() and assign() methods as "generation"
+ // These numbers are used in adjust() and assign() methods as "generation"
// values in order to avoid costly operations when two instances of RuntimeStatistics
// contain equal counters values. This is intended to use *only* with the
// same pair of class instances, as in Request.
ULONG allChgNumber; // incremented when any counter changes
- ULONG relChgNumber; // incremented when relation counter changes
+ ULONG pageChgNumber; // incremented when page counter changes
+ ULONG tabChgNumber; // incremented when table counter changes
// This dummy RuntimeStatistics is used instead of missing elements in tdbb,
// helping us to avoid conditional checks in time-critical places of code.
diff --git a/src/jrd/cch.cpp b/src/jrd/cch.cpp
index d660ce17bf1..ecb7ed947bb 100644
--- a/src/jrd/cch.cpp
+++ b/src/jrd/cch.cpp
@@ -930,9 +930,10 @@ void CCH_fetch_page(thread_db* tdbb, WIN* window, const bool read_shadow)
pag* page = bdb->bdb_buffer;
bdb->bdb_incarnation = ++bcb->bcb_page_incarnation;
- tdbb->bumpStats(PageStatType::READS);
+ const ULONG pageSpaceId = bdb->bdb_page.getPageSpaceID();
+ tdbb->bumpStats(PageStatType::READS, pageSpaceId);
- PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(bdb->bdb_page.getPageSpaceID());
+ const auto pageSpace = dbb->dbb_page_manager.findPageSpace(pageSpaceId);
fb_assert(pageSpace);
jrd_file* file = pageSpace->file;
@@ -1011,7 +1012,7 @@ void CCH_fetch_page(thread_db* tdbb, WIN* window, const bool read_shadow)
{
diff_page = bm->getPageIndex(tdbb, bdb->bdb_page.getPageNum());
NBAK_TRACE(("Reading page %d:%06d, state=%d, diff page=%d",
- bdb->bdb_page.getPageSpaceID(), bdb->bdb_page.getPageNum(), (int) backupState, diff_page));
+ pageSpaceId, bdb->bdb_page.getPageNum(), (int) backupState, diff_page));
}
// In merge mode, if we are reading past beyond old end of file and page is in .delta file
@@ -1021,7 +1022,7 @@ void CCH_fetch_page(thread_db* tdbb, WIN* window, const bool read_shadow)
fb_assert(bdb->bdb_page == window->win_page);
NBAK_TRACE(("Reading page %d:%06d, state=%d, diff page=%d from DISK",
- bdb->bdb_page.getPageSpaceID(), bdb->bdb_page.getPageNum(), (int) backupState, diff_page));
+ pageSpaceId, bdb->bdb_page.getPageNum(), (int) backupState, diff_page));
// Read page from disk as normal
Pio io(file, bdb, isTempPage, read_shadow, pageSpace);
@@ -1701,14 +1702,16 @@ void CCH_mark(thread_db* tdbb, WIN* window, bool mark_system, bool must_write)
SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase();
- tdbb->bumpStats(PageStatType::MARKS);
+
+ const ULONG pageSpaceId = window->win_page.getPageSpaceID();
+ tdbb->bumpStats(PageStatType::MARKS, pageSpaceId);
BufferControl* bcb = dbb->dbb_bcb;
if (!(bdb->bdb_flags & BDB_writer))
BUGCHECK(208); // msg 208 page not accessed for write
- CCH_TRACE(("MARK %d:%06d", window->win_page.getPageSpaceID(), window->win_page.getPageNum()));
+ CCH_TRACE(("MARK %d:%06d", pageSpaceId, window->win_page.getPageNum()));
// A LATCH_mark is needed before the BufferDesc can be marked.
// This prevents a write while the page is being modified.
@@ -3805,6 +3808,8 @@ static BufferDesc* get_buffer(thread_db* tdbb, const PageNumber page, SyncType s
BufferControl* bcb = dbb->dbb_bcb;
Attachment* att = tdbb->getAttachment();
+ const ULONG pageSpaceId = page.getPageSpaceID();
+
if (att && att->att_bdb_cache)
{
if (BufferDesc* bdb = att->att_bdb_cache->get(page))
@@ -3814,7 +3819,7 @@ static BufferDesc* get_buffer(thread_db* tdbb, const PageNumber page, SyncType s
if (bdb->bdb_page == page)
{
recentlyUsed(bdb);
- tdbb->bumpStats(PageStatType::FETCHES);
+ tdbb->bumpStats(PageStatType::FETCHES, pageSpaceId);
return bdb;
}
@@ -3857,7 +3862,7 @@ static BufferDesc* get_buffer(thread_db* tdbb, const PageNumber page, SyncType s
if (bdb->bdb_page == page)
{
recentlyUsed(bdb);
- tdbb->bumpStats(PageStatType::FETCHES);
+ tdbb->bumpStats(PageStatType::FETCHES, pageSpaceId);
cacheBuffer(att, bdb);
return bdb;
}
@@ -3897,7 +3902,7 @@ static BufferDesc* get_buffer(thread_db* tdbb, const PageNumber page, SyncType s
{
bdb->downgrade(syncType);
recentlyUsed(bdb);
- tdbb->bumpStats(PageStatType::FETCHES);
+ tdbb->bumpStats(PageStatType::FETCHES, pageSpaceId);
cacheBuffer(att, bdb);
return bdb;
}
@@ -3941,7 +3946,7 @@ static BufferDesc* get_buffer(thread_db* tdbb, const PageNumber page, SyncType s
else
recentlyUsed(bdb);
}
- tdbb->bumpStats(PageStatType::FETCHES);
+ tdbb->bumpStats(PageStatType::FETCHES, pageSpaceId);
cacheBuffer(att, bdb);
return bdb;
}
@@ -3959,7 +3964,7 @@ static BufferDesc* get_buffer(thread_db* tdbb, const PageNumber page, SyncType s
continue;
}
recentlyUsed(bdb2);
- tdbb->bumpStats(PageStatType::FETCHES);
+ tdbb->bumpStats(PageStatType::FETCHES, pageSpaceId);
cacheBuffer(att, bdb2);
}
else
@@ -4914,7 +4919,8 @@ static bool write_page(thread_db* tdbb, BufferDesc* bdb, FbStatusVector* const s
// I won't wipe out the if() itself to allow my changes be verified easily by others
if (true)
{
- tdbb->bumpStats(PageStatType::WRITES);
+ const ULONG pageSpaceId = bdb->bdb_page.getPageSpaceID();
+ tdbb->bumpStats(PageStatType::WRITES, pageSpaceId);
// write out page to main database file, and to any
// shadows, making a special case of the header page
@@ -4952,8 +4958,7 @@ static bool write_page(thread_db* tdbb, BufferDesc* bdb, FbStatusVector* const s
gds__trace(buffer);
#endif
- PageSpace* pageSpace =
- dbb->dbb_page_manager.findPageSpace(bdb->bdb_page.getPageSpaceID());
+ const auto pageSpace = dbb->dbb_page_manager.findPageSpace(pageSpaceId);
fb_assert(pageSpace);
const bool isTempPage = pageSpace->isTemporary();
diff --git a/src/jrd/inf.cpp b/src/jrd/inf.cpp
index 7d0d42b9eb6..60f0b6a29bd 100644
--- a/src/jrd/inf.cpp
+++ b/src/jrd/inf.cpp
@@ -273,11 +273,11 @@ void INF_database_info(thread_db* tdbb,
resultBuffer.clear();
FB_SIZE_T bufferLength = 0;
- for (auto iter(recordStats->getRelCounters()); iter; ++iter)
+ for (const auto& counts : recordStats->getTableCounters())
{
- if (const SINT64 n = (*iter)[type])
+ if (const SINT64 n = counts[type])
{
- const USHORT relationId = (*iter).getRelationId();
+ const USHORT relationId = counts.getGroupId();
const USHORT length = INF_convert(n, numBuffer);
const FB_SIZE_T newBufferLength = bufferLength + length + sizeof(USHORT);
resultBuffer.grow(newBufferLength);
diff --git a/src/jrd/jrd.h b/src/jrd/jrd.h
index 2e3644c89cc..d6b2896c0db 100644
--- a/src/jrd/jrd.h
+++ b/src/jrd/jrd.h
@@ -612,44 +612,35 @@ class thread_db final : public Firebird::ThreadData
tdbb_flags |= TDBB_sweeper;
}
- void bumpStats(const PageStatType type, SINT64 delta = 1)
+ void bumpStats(const PageStatType type, ULONG pageSpaceId, SINT64 delta = 1)
{
- reqStat->bumpValue(type, delta);
- traStat->bumpValue(type, delta);
- attStat->bumpValue(type, delta);
+ fb_assert(pageSpaceId != INVALID_PAGE_SPACE);
+
+ // [0] element stores statistics for temporary page spaces
+ if (PageSpace::isTemporary(pageSpaceId))
+ pageSpaceId = 0;
+
+ reqStat->bumpValue(type, pageSpaceId, delta);
+ traStat->bumpValue(type, pageSpaceId, delta);
+ attStat->bumpValue(type, pageSpaceId, delta);
if ((tdbb_flags & TDBB_async) && !attachment)
- dbbStat->bumpValue(type, delta);
+ dbbStat->bumpValue(type, pageSpaceId, delta);
- // else dbbStat is adjusted from attStat, see Attachment::mergeAsyncStats()
+ // else dbbStat is adjusted from attStat, see Attachment::mergeStats()
}
- void bumpStats(const RecordStatType type, SLONG relation_id, SINT64 delta = 1)
+ void bumpStats(const RecordStatType type, SLONG relationId, SINT64 delta = 1)
{
- // We don't bump counters for dbbStat here, they're merged from attStats on demand
-
- reqStat->bumpValue(type, delta);
- traStat->bumpValue(type, delta);
- attStat->bumpValue(type, delta);
-
- const RuntimeStatistics* const dummyStat = RuntimeStatistics::getDummy();
-
// We expect that at least attStat is present (not a dummy object)
- fb_assert(attStat != dummyStat);
-
- // Relation statistics is a quite complex beast, so a conditional check
- // does not hurt. It also allows to avoid races while accessing the static
- // dummy object concurrently.
+ fb_assert(attStat != RuntimeStatistics::getDummy());
- if (reqStat != dummyStat)
- reqStat->bumpValue(type, relation_id, delta);
+ reqStat->bumpValue(type, relationId, delta);
+ traStat->bumpValue(type, relationId, delta);
+ attStat->bumpValue(type, relationId, delta);
- if (traStat != dummyStat)
- traStat->bumpValue(type, relation_id, delta);
-
- if (attStat != dummyStat)
- attStat->bumpValue(type, relation_id, delta);
+ // We don't bump counters for dbbStat here, they're merged from attStats on demand
}
ISC_STATUS getCancelState(ISC_STATUS* secondary = NULL);
diff --git a/src/jrd/tra.cpp b/src/jrd/tra.cpp
index ba658f45dc2..b2844c4f8a2 100644
--- a/src/jrd/tra.cpp
+++ b/src/jrd/tra.cpp
@@ -4330,7 +4330,7 @@ void TraceSweepEvent::endSweepRelation(jrd_rel* relation)
fb_utils::query_performance_counter() - m_relation_clock,
0);
- m_sweep_info.setPerf(stats.getPerf());
+ m_sweep_info.setStats(&stats);
TraceConnectionImpl conn(att);
TraceManager* trace_mgr = att->att_trace_manager;
@@ -4377,7 +4377,7 @@ void TraceSweepEvent::report(ntrace_process_state_t state)
TraceRuntimeStats stats(att, &m_base_stats, &att->att_stats, finiTime, 0);
- m_sweep_info.setPerf(stats.getPerf());
+ m_sweep_info.setStats(&stats);
trace_mgr->event_sweep(&conn, &m_sweep_info, state);
if (state == ITracePlugin::SWEEP_STATE_FAILED || state == ITracePlugin::SWEEP_STATE_FINISHED)
diff --git a/src/jrd/trace/TraceDSQLHelpers.h b/src/jrd/trace/TraceDSQLHelpers.h
index 3d3f0cd78cf..1941edcac42 100644
--- a/src/jrd/trace/TraceDSQLHelpers.h
+++ b/src/jrd/trace/TraceDSQLHelpers.h
@@ -173,7 +173,7 @@ class TraceDSQLExecute
fb_utils::query_performance_counter() - m_start_clock,
m_dsqlRequest->req_fetch_rowcount);
- TraceSQLStatementImpl stmt(m_dsqlRequest, stats.getPerf(), m_data);
+ TraceSQLStatementImpl stmt(m_dsqlRequest, &stats, m_data);
TraceManager::event_dsql_execute(m_attachment, m_dsqlRequest->req_transaction, &stmt, false, result);
m_dsqlRequest->req_fetch_baseline = NULL;
@@ -233,7 +233,7 @@ class TraceDSQLFetch
&m_dsqlRequest->getRequest()->req_stats, m_dsqlRequest->req_fetch_elapsed,
m_dsqlRequest->req_fetch_rowcount);
- TraceSQLStatementImpl stmt(m_dsqlRequest, stats.getPerf(), nullptr);
+ TraceSQLStatementImpl stmt(m_dsqlRequest, &stats, nullptr);
TraceManager::event_dsql_execute(m_attachment, m_dsqlRequest->req_transaction,
&stmt, false, result);
diff --git a/src/jrd/trace/TraceJrdHelpers.h b/src/jrd/trace/TraceJrdHelpers.h
index 2dbbfdabd97..994116042ec 100644
--- a/src/jrd/trace/TraceJrdHelpers.h
+++ b/src/jrd/trace/TraceJrdHelpers.h
@@ -75,7 +75,7 @@ class TraceTransactionEnd
fb_utils::query_performance_counter() - m_start_clock, 0);
TraceConnectionImpl conn(attachment);
- TraceTransactionImpl tran(m_transaction, stats.getPerf(), m_prevID);
+ TraceTransactionImpl tran(m_transaction, &stats, m_prevID);
attachment->att_trace_manager->event_transaction_end(&conn, &tran, m_commit, m_retain, result);
m_baseline = NULL;
@@ -205,7 +205,7 @@ class TraceProcExecute
TraceConnectionImpl conn(attachment);
TraceTransactionImpl tran(transaction);
- TraceProcedureImpl proc(m_request, stats.getPerf());
+ TraceProcedureImpl proc(m_request, &stats);
const auto trace_mgr = attachment->att_trace_manager;
trace_mgr->event_proc_execute(&conn, &tran, &proc, false, result);
@@ -268,7 +268,7 @@ class TraceProcFetch
TraceConnectionImpl conn(attachment);
TraceTransactionImpl tran(transaction);
- TraceProcedureImpl proc(m_request, stats.getPerf());
+ TraceProcedureImpl proc(m_request, &stats);
const auto trace_mgr = attachment->att_trace_manager;
trace_mgr->event_proc_execute(&conn, &tran, &proc, false, result);
@@ -402,7 +402,7 @@ class TraceFuncExecute
TraceTransactionImpl tran(transaction);
TraceDscFromMsg inputs(m_request->getStatement()->function->getInputFormat(), m_inMsg, m_inMsgLength);
- TraceFunctionImpl func(m_request, stats.getPerf(), inputs, value);
+ TraceFunctionImpl func(m_request, &stats, inputs, value);
const auto trace_mgr = attachment->att_trace_manager;
trace_mgr->event_func_execute(&conn, &tran, &func, false, result);
@@ -566,7 +566,7 @@ class TraceTrigExecute
TraceConnectionImpl conn(attachment);
TraceTransactionImpl tran(transaction);
- TraceTriggerImpl trig(m_which, m_request, stats.getPerf());
+ TraceTriggerImpl trig(m_which, m_request, &stats);
const auto trace_mgr = attachment->att_trace_manager;
trace_mgr->event_trigger_execute(&conn, &tran, &trig, false, result);
@@ -689,7 +689,7 @@ class TraceBlrExecute
TraceConnectionImpl conn(m_tdbb->getAttachment());
TraceTransactionImpl tran(m_tdbb->getTransaction());
- TraceBLRStatementImpl stmt(m_request->getStatement(), stats.getPerf());
+ TraceBLRStatementImpl stmt(m_request->getStatement(), &stats);
TraceManager* trace_mgr = m_tdbb->getAttachment()->att_trace_manager;
trace_mgr->event_blr_execute(&conn, &tran, &stmt, result);
diff --git a/src/jrd/trace/TraceObjects.cpp b/src/jrd/trace/TraceObjects.cpp
index 6b2d4f251df..86a503b922e 100644
--- a/src/jrd/trace/TraceObjects.cpp
+++ b/src/jrd/trace/TraceObjects.cpp
@@ -261,16 +261,6 @@ const char* TraceSQLStatementImpl::getTextUTF8()
return m_textUTF8.c_str();
}
-PerformanceInfo* TraceSQLStatementImpl::getPerf()
-{
- return m_perf;
-}
-
-ITraceParams* TraceSQLStatementImpl::getInputs()
-{
- return &m_inputs;
-}
-
/// TraceSQLStatementImpl::DSQLParamsImpl
@@ -633,24 +623,62 @@ const char* TraceServiceImpl::getRemoteProcessName()
/// TraceRuntimeStats
-TraceRuntimeStats::TraceRuntimeStats(Attachment* att, RuntimeStatistics* baseline, RuntimeStatistics* stats,
- SINT64 clock, SINT64 records_fetched)
+TraceRuntimeStats::TraceRuntimeStats(Attachment* attachment,
+ RuntimeStatistics* baseline, RuntimeStatistics* stats,
+ SINT64 clock, SINT64 recordsFetched)
{
+ memset(&m_info, 0, sizeof(m_info));
m_info.pin_time = clock * 1000 / fb_utils::query_performance_frequency();
- m_info.pin_records_fetched = records_fetched;
+ m_info.pin_records_fetched = recordsFetched;
+ m_info.pin_counters = m_globalCounters;
if (baseline && stats)
- baseline->computeDifference(att, *stats, m_info, m_counts, m_tempNames);
+ {
+ baseline->setToDiff(*stats);
+
+ m_globalCounters[PerformanceInfo::FETCHES] = (*baseline)[PageStatType::FETCHES];
+ m_globalCounters[PerformanceInfo::READS] = (*baseline)[PageStatType::READS];
+ m_globalCounters[PerformanceInfo::MARKS] = (*baseline)[PageStatType::MARKS];
+ m_globalCounters[PerformanceInfo::WRITES] = (*baseline)[PageStatType::WRITES];
+
+ auto getTablespaceName = [&](unsigned id) -> Firebird::string
+ {
+ return ""; // TODO
+ };
+
+ m_pageCounters.reset(&baseline->getPageCounters(), getTablespaceName);
+
+ auto getTableName = [&](unsigned id) -> Firebird::string
+ {
+ if (attachment->att_relations && id < attachment->att_relations->count())
+ {
+ if (const auto relation = (*attachment->att_relations)[id])
+ return relation->rel_name.toQuotedString();
+ }
+
+ return "";
+ };
+
+ m_tableCounters.reset(&baseline->getTableCounters(), getTableName);
+
+ m_info.pin_count = m_tableCounters.getObjectCount();
+ m_legacyCounts.resize(m_info.pin_count);
+ m_info.pin_tables = m_legacyCounts.begin();
+
+ for (unsigned i = 0; i < m_info.pin_count; i++)
+ {
+ m_info.pin_tables[i].trc_relation_id = m_tableCounters.getObjectId(i);
+ m_info.pin_tables[i].trc_relation_name = m_tableCounters.getObjectName(i);
+ m_info.pin_tables[i].trc_counters = m_tableCounters.getObjectCounters(i);
+ i++;
+ }
+ }
else
{
- // Report all zero counts for the moment.
- memset(&m_info, 0, sizeof(m_info));
- m_info.pin_counters = m_dummy_counts;
+ memset(m_globalCounters, 0, sizeof(m_globalCounters));
}
}
-SINT64 TraceRuntimeStats::m_dummy_counts[RuntimeStatistics::GLOBAL_ITEMS] = {0};
-
/// TraceStatusVectorImpl
diff --git a/src/jrd/trace/TraceObjects.h b/src/jrd/trace/TraceObjects.h
index f20cd8b0038..36a7ec8ca64 100644
--- a/src/jrd/trace/TraceObjects.h
+++ b/src/jrd/trace/TraceObjects.h
@@ -96,6 +96,127 @@ class StatementHolder
};
+class TraceRuntimeStats :
+ public Firebird::AutoIface >
+{
+ static constexpr unsigned GLOBAL_COUNTERS = 4; // PerformanceInfo::{FETCHES|READS|MARKS|WRITES}
+
+ template
+ class GenericCounters :
+ public Firebird::AutoIface, Firebird::CheckStatusWrapper> >
+ {
+ public:
+ GenericCounters() = default;
+ ~GenericCounters() = default;
+
+ void reset(const T* counters, std::function getName)
+ {
+ m_counts = counters;
+ m_names.clear();
+
+ for (const auto& counts : *m_counts)
+ m_names.add(getName(counts.getGroupId()));
+ }
+
+ // PerformanceCounts implementation
+ unsigned getObjectCount()
+ {
+ return m_counts ? m_counts->getCount() : 0;
+ }
+
+ unsigned getMaxCounterIndex()
+ {
+ return T::getVectorCapacity() - 1;
+ }
+
+ unsigned getObjectId(unsigned index)
+ {
+ if (m_counts && index < m_counts->getCount())
+ {
+ const auto iter = m_counts->begin() + index;
+ return iter->getGroupId();
+ }
+
+ return 0;
+ }
+
+ const char* getObjectName(unsigned index)
+ {
+ if (index < m_names.getCount())
+ return m_names[index].c_str();
+
+ return nullptr;
+ }
+
+ const SINT64* getObjectCounters(unsigned index)
+ {
+ if (m_counts && index < m_counts->getCount())
+ {
+ const auto iter = m_counts->begin() + index;
+ return iter->getCounterVector();
+ }
+
+ return nullptr;
+ }
+
+ private:
+ Firebird::ObjectsArray m_names;
+ const T* m_counts = nullptr;
+ };
+
+ typedef GenericCounters PageCounters;
+ typedef GenericCounters TableCounters;
+
+public:
+ TraceRuntimeStats(Attachment* att, RuntimeStatistics* baseline, RuntimeStatistics* stats,
+ SINT64 clock, SINT64 recordsFetched);
+
+ // PerformanceStats implementation
+ FB_UINT64 getElapsedTime()
+ {
+ return m_info.pin_time;
+ }
+
+ FB_UINT64 getFetchedRecords()
+ {
+ return m_info.pin_records_fetched;
+ }
+
+ Firebird::IPerformanceCounters* getCounters(unsigned group)
+ {
+ Firebird::IPerformanceCounters* counters = nullptr;
+
+ switch (group)
+ {
+ case IPerformanceStats::COUNTER_GROUP_PAGES:
+ counters = &m_pageCounters;
+ break;
+
+ case IPerformanceStats::COUNTER_GROUP_TABLES:
+ counters = &m_tableCounters;
+ break;
+
+ default:
+ fb_assert(false);
+ }
+
+ return counters;
+ }
+
+ Firebird::PerformanceInfo* getInfo()
+ {
+ return &m_info;
+ }
+
+private:
+ Firebird::PerformanceInfo m_info;
+ PageCounters m_pageCounters;
+ TableCounters m_tableCounters;
+ SINT64 m_globalCounters[GLOBAL_COUNTERS];
+ Firebird::HalfStaticArray m_legacyCounts;
+};
+
+
class TraceConnectionImpl :
public Firebird::AutoIface >
{
@@ -127,10 +248,10 @@ class TraceTransactionImpl :
public Firebird::AutoIface >
{
public:
- TraceTransactionImpl(const jrd_tra* tran, Firebird::PerformanceInfo* perf = NULL, ISC_INT64 prevID = 0) :
+ TraceTransactionImpl(const jrd_tra* tran, TraceRuntimeStats* stats = nullptr, ISC_INT64 prevID = 0) :
m_tran(tran),
- m_perf(perf),
- m_prevID(prevID)
+ m_prevID(prevID),
+ m_stats(stats)
{}
// TraceTransaction implementation
@@ -138,14 +259,27 @@ class TraceTransactionImpl :
FB_BOOLEAN getReadOnly();
int getWait();
unsigned getIsolation();
- Firebird::PerformanceInfo* getPerf() { return m_perf; }
ISC_INT64 getInitialID();
- ISC_INT64 getPreviousID() { return m_prevID; }
+
+ ISC_INT64 getPreviousID()
+ {
+ return m_prevID;
+ }
+
+ Firebird::PerformanceInfo* getPerf()
+ {
+ return m_stats ? m_stats->getInfo() : nullptr;
+ }
+
+ Firebird::IPerformanceStats* getPerfStats()
+ {
+ return m_stats;
+ }
private:
const jrd_tra* const m_tran;
- Firebird::PerformanceInfo* const m_perf;
const ISC_INT64 m_prevID;
+ TraceRuntimeStats* const m_stats;
};
@@ -161,8 +295,16 @@ class BLRPrinter :
{}
// TraceBLRStatement implementation
- const unsigned char* getData() { return m_blr; }
- unsigned getDataLength() { return m_length; }
+ const unsigned char* getData()
+ {
+ return m_blr;
+ }
+
+ unsigned getDataLength()
+ {
+ return m_length;
+ }
+
const char* getText()
{
if (m_text.empty() && getDataLength())
@@ -189,18 +331,30 @@ class BLRPrinter :
class TraceBLRStatementImpl : public BLRPrinter
{
public:
- TraceBLRStatementImpl(const Statement* stmt, Firebird::PerformanceInfo* perf) :
+ TraceBLRStatementImpl(const Statement* stmt, TraceRuntimeStats* stats) :
BLRPrinter(stmt->blr.begin(), stmt->blr.getCount()),
m_stmt(stmt),
- m_perf(perf)
+ m_stats(stats)
{}
- ISC_INT64 getStmtID() { return m_stmt->getStatementId(); }
- Firebird::PerformanceInfo* getPerf() { return m_perf; }
+ ISC_INT64 getStmtID()
+ {
+ return m_stmt->getStatementId();
+ }
+
+ Firebird::PerformanceInfo* getPerf()
+ {
+ return m_stats ? m_stats->getInfo() : nullptr;
+ }
+
+ Firebird::IPerformanceStats* getPerfStats()
+ {
+ return m_stats;
+ }
private:
const Statement* const m_stmt;
- Firebird::PerformanceInfo* const m_perf;
+ TraceRuntimeStats* const m_stats;
};
@@ -211,8 +365,9 @@ class TraceFailedBLRStatement : public BLRPrinter
BLRPrinter(blr, length)
{}
- ISC_INT64 getStmtID() { return 0; }
- Firebird::PerformanceInfo* getPerf() { return NULL; }
+ ISC_INT64 getStmtID() { return 0; }
+ Firebird::PerformanceInfo* getPerf() { return nullptr; }
+ Firebird::IPerformanceStats* getPerfStats() { return nullptr; }
};
@@ -221,20 +376,23 @@ class TraceSQLStatementImpl :
public StatementHolder
{
public:
- TraceSQLStatementImpl(DsqlRequest* stmt, Firebird::PerformanceInfo* perf, const UCHAR* inputBuffer) :
+ TraceSQLStatementImpl(DsqlRequest* stmt, TraceRuntimeStats* stats, const UCHAR* inputBuffer) :
StatementHolder(stmt ? stmt->getStatement() : nullptr),
m_stmt(stmt),
- m_perf(perf),
- m_inputs(stmt, inputBuffer)
+ m_inputs(stmt, inputBuffer),
+ m_stats(stats)
{}
// TraceSQLStatement implementation
ISC_INT64 getStmtID();
- Firebird::PerformanceInfo* getPerf();
- Firebird::ITraceParams* getInputs();
const char* getText();
const char* getTextUTF8();
+ Firebird::ITraceParams* getInputs()
+ {
+ return &m_inputs;
+ }
+
const char* getPlan()
{
return ensurePlan(false);
@@ -245,6 +403,16 @@ class TraceSQLStatementImpl :
return ensurePlan(true);
}
+ Firebird::PerformanceInfo* getPerf()
+ {
+ return m_stats ? m_stats->getInfo() : nullptr;
+ }
+
+ Firebird::IPerformanceStats* getPerfStats()
+ {
+ return m_stats;
+ }
+
private:
class DSQLParamsImpl :
public Firebird::AutoIface >
@@ -252,8 +420,7 @@ class TraceSQLStatementImpl :
public:
explicit DSQLParamsImpl(DsqlRequest* const stmt, const UCHAR* const inputBuffer) :
m_stmt(stmt), m_buffer(inputBuffer)
- {
- }
+ {}
FB_SIZE_T getCount();
const paramdsc* getParam(FB_SIZE_T idx);
@@ -269,9 +436,9 @@ class TraceSQLStatementImpl :
};
DsqlRequest* const m_stmt;
- Firebird::PerformanceInfo* const m_perf;
DSQLParamsImpl m_inputs;
Firebird::string m_textUTF8;
+ TraceRuntimeStats* const m_stats;
};
@@ -284,13 +451,14 @@ class TraceFailedSQLStatement :
{}
// TraceSQLStatement implementation
- ISC_INT64 getStmtID() { return 0; }
- Firebird::PerformanceInfo* getPerf() { return NULL; }
- Firebird::ITraceParams* getInputs() { return NULL; }
- const char* getText() { return m_text.c_str(); }
- const char* getPlan() { return ""; }
+ ISC_INT64 getStmtID() { return 0; }
+ Firebird::ITraceParams* getInputs() { return nullptr; }
+ const char* getText() { return m_text.c_str(); }
+ const char* getPlan() { return ""; }
const char* getTextUTF8();
- const char* getExplainedPlan() { return ""; }
+ const char* getExplainedPlan() { return ""; }
+ Firebird::PerformanceInfo* getPerf() { return nullptr; }
+ Firebird::IPerformanceStats* getPerfStats() { return nullptr; }
private:
Firebird::string& m_text;
@@ -444,15 +612,15 @@ class TraceProcedureImpl :
TraceProcedureImpl(const Firebird::string& name, const Statement* statement) :
StatementHolder(statement),
m_name(name),
- m_perf(nullptr),
- m_inputs(nullptr, nullptr)
+ m_inputs(nullptr, nullptr),
+ m_stats(nullptr)
{}
- TraceProcedureImpl(Request* request, Firebird::PerformanceInfo* perf) :
+ TraceProcedureImpl(Request* request, TraceRuntimeStats* stats) :
StatementHolder(request),
m_name(getName()),
- m_perf(perf),
- m_inputs(request->req_proc_caller, request->req_proc_inputs)
+ m_inputs(request->req_proc_caller, request->req_proc_inputs),
+ m_stats(stats)
{}
// TraceProcedure implementation
@@ -466,11 +634,6 @@ class TraceProcedureImpl :
return m_inputs;
}
- Firebird::PerformanceInfo* getPerf()
- {
- return m_perf;
- };
-
ISC_INT64 getStmtID()
{
return getId();
@@ -486,10 +649,20 @@ class TraceProcedureImpl :
return ensurePlan(true);
}
+ Firebird::PerformanceInfo* getPerf()
+ {
+ return m_stats ? m_stats->getInfo() : nullptr;
+ }
+
+ Firebird::IPerformanceStats* getPerfStats()
+ {
+ return m_stats;
+ }
+
private:
const Firebird::string m_name;
- Firebird::PerformanceInfo* const m_perf;
TraceDscFromValues m_inputs;
+ TraceRuntimeStats* const m_stats;
};
@@ -501,18 +674,18 @@ class TraceFunctionImpl :
TraceFunctionImpl(const Firebird::string& name, const Statement* statement) :
StatementHolder(statement),
m_name(name),
- m_perf(nullptr),
m_inputs(nullptr),
- m_value(nullptr)
+ m_value(nullptr),
+ m_stats(nullptr)
{}
- TraceFunctionImpl(Request* request, Firebird::PerformanceInfo* perf,
+ TraceFunctionImpl(Request* request, TraceRuntimeStats* stats,
Firebird::ITraceParams* inputs, const dsc* value) :
StatementHolder(request),
m_name(getName()),
- m_perf(perf),
m_inputs(inputs),
- m_value(value)
+ m_value(value),
+ m_stats(stats)
{}
// TraceFunction implementation
@@ -531,11 +704,6 @@ class TraceFunctionImpl :
return m_value;
}
- Firebird::PerformanceInfo* getPerf()
- {
- return m_perf;
- };
-
ISC_INT64 getStmtID()
{
return getId();
@@ -551,11 +719,21 @@ class TraceFunctionImpl :
return ensurePlan(true);
}
+ Firebird::PerformanceInfo* getPerf()
+ {
+ return m_stats ? m_stats->getInfo() : nullptr;
+ };
+
+ Firebird::IPerformanceStats* getPerfStats()
+ {
+ return m_stats;
+ };
+
private:
Firebird::string m_name;
- Firebird::PerformanceInfo* const m_perf;
Firebird::ITraceParams* const m_inputs;
TraceDscFromDsc m_value;
+ TraceRuntimeStats* const m_stats;
};
@@ -571,17 +749,17 @@ class TraceTriggerImpl :
m_relationName(relationName),
m_which(which),
m_action(action),
- m_perf(nullptr)
+ m_stats(nullptr)
{}
- TraceTriggerImpl(int which, const Request* request, Firebird::PerformanceInfo* perf) :
+ TraceTriggerImpl(int which, const Request* request, TraceRuntimeStats* stats) :
StatementHolder(request),
m_name(getName()),
m_relationName((request->req_rpb.hasData() && request->req_rpb[0].rpb_relation) ?
request->req_rpb[0].rpb_relation->rel_name.toQuotedString() : ""),
m_which(which),
m_action(request->req_trigger_action),
- m_perf(perf)
+ m_stats(stats)
{}
// TraceTrigger implementation
@@ -605,11 +783,6 @@ class TraceTriggerImpl :
return m_action;
}
- Firebird::PerformanceInfo* getPerf()
- {
- return m_perf;
- }
-
ISC_INT64 getStmtID()
{
return getId();
@@ -625,12 +798,22 @@ class TraceTriggerImpl :
return ensurePlan(true);
}
+ Firebird::PerformanceInfo* getPerf()
+ {
+ return m_stats ? m_stats->getInfo() : nullptr;
+ };
+
+ Firebird::IPerformanceStats* getPerfStats()
+ {
+ return m_stats;
+ };
+
private:
const Firebird::string m_name;
const Firebird::string m_relationName;
const int m_which;
const int m_action;
- Firebird::PerformanceInfo* const m_perf;
+ TraceRuntimeStats* const m_stats;
};
@@ -662,22 +845,6 @@ class TraceServiceImpl :
};
-class TraceRuntimeStats
-{
-public:
- TraceRuntimeStats(Attachment* att, RuntimeStatistics* baseline, RuntimeStatistics* stats,
- SINT64 clock, SINT64 records_fetched);
-
- Firebird::PerformanceInfo* getPerf() { return &m_info; }
-
-private:
- Firebird::PerformanceInfo m_info;
- TraceCountsArray m_counts;
- Firebird::ObjectsArray m_tempNames;
- static SINT64 m_dummy_counts[RuntimeStatistics::GLOBAL_ITEMS]; // Zero-initialized array with zero counts
-};
-
-
class TraceInitInfoImpl :
public Firebird::AutoIface >
{
@@ -759,14 +926,7 @@ class TraceSweepImpl :
public Firebird::AutoIface >
{
public:
- TraceSweepImpl()
- {
- m_oit = 0;
- m_ost = 0;
- m_oat = 0;
- m_next = 0;
- m_perf = 0;
- }
+ TraceSweepImpl() = default;
void update(const Ods::header_page* header)
{
@@ -776,23 +936,32 @@ class TraceSweepImpl :
m_next = header->hdr_next_transaction;
}
- void setPerf(Firebird::PerformanceInfo* perf)
+ void setStats(TraceRuntimeStats* stats)
{
- m_perf = perf;
+ m_stats = stats;
}
ISC_INT64 getOIT() { return m_oit; };
ISC_INT64 getOST() { return m_ost; };
ISC_INT64 getOAT() { return m_oat; };
ISC_INT64 getNext() { return m_next; };
- Firebird::PerformanceInfo* getPerf() { return m_perf; };
+
+ Firebird::PerformanceInfo* getPerf()
+ {
+ return m_stats ? m_stats->getInfo() : nullptr;
+ };
+
+ Firebird::IPerformanceStats* getPerfStats()
+ {
+ return m_stats;
+ };
private:
- TraNumber m_oit;
- TraNumber m_ost;
- TraNumber m_oat;
- TraNumber m_next;
- Firebird::PerformanceInfo* m_perf;
+ TraNumber m_oit = 0;
+ TraNumber m_ost = 0;
+ TraNumber m_oat = 0;
+ TraNumber m_next = 0;
+ TraceRuntimeStats* m_stats = nullptr;
};
} // namespace Jrd
diff --git a/src/utilities/ntrace/TracePluginImpl.cpp b/src/utilities/ntrace/TracePluginImpl.cpp
index a962af94748..5447402550d 100644
--- a/src/utilities/ntrace/TracePluginImpl.cpp
+++ b/src/utilities/ntrace/TracePluginImpl.cpp
@@ -629,56 +629,78 @@ void TracePluginImpl::logRecordError(const char* action, ITraceConnection* conne
logRecord(action);
}
-void TracePluginImpl::appendGlobalCounts(const PerformanceInfo* info)
+void TracePluginImpl::appendGlobalCounts(IPerformanceStats* stats)
{
string temp;
- temp.printf("%7" QUADFORMAT"d ms", info->pin_time);
+ temp.printf("%7" QUADFORMAT"d ms", stats->getElapsedTime());
record.append(temp);
- ntrace_counter_t cnt;
+ const auto pageCounters = stats->getCounters(IPerformanceStats::COUNTER_GROUP_PAGES);
+ fb_assert(pageCounters);
- if ((cnt = info->pin_counters[PerformanceInfo::READS]) != 0)
+ if (const auto count = pageCounters->getObjectCount())
{
- temp.printf(", %" QUADFORMAT"d read(s)", cnt);
- record.append(temp);
- }
+ // Holds counters: IPerformanceCounters::PAGE_{FETCHES|READS|MARKS|WRITES}
+ static constexpr unsigned GLOBAL_COUNTERS = 4;
+ SINT64 globalCounters[GLOBAL_COUNTERS] = {0};
- if ((cnt = info->pin_counters[PerformanceInfo::WRITES]) != 0)
- {
- temp.printf(", %" QUADFORMAT"d write(s)", cnt);
- record.append(temp);
- }
+ for (unsigned i = 0; i < count; i++)
+ {
+ const auto counters = pageCounters->getObjectCounters(i);
+ for (unsigned j = 0; j < GLOBAL_COUNTERS; j++)
+ globalCounters[j] += counters[j];
+ }
- if ((cnt = info->pin_counters[PerformanceInfo::FETCHES]) != 0)
- {
- temp.printf(", %" QUADFORMAT"d fetch(es)", cnt);
- record.append(temp);
- }
+ if (const auto cnt = globalCounters[IPerformanceCounters::PAGE_READS])
+ {
+ temp.printf(", %" QUADFORMAT"d read(s)", cnt);
+ record.append(temp);
+ }
- if ((cnt = info->pin_counters[PerformanceInfo::MARKS]) != 0)
- {
- temp.printf(", %" QUADFORMAT"d mark(s)", cnt);
- record.append(temp);
+ if (const auto cnt = globalCounters[IPerformanceCounters::PAGE_WRITES])
+ {
+ temp.printf(", %" QUADFORMAT"d write(s)", cnt);
+ record.append(temp);
+ }
+
+ if (const auto cnt = globalCounters[IPerformanceCounters::PAGE_FETCHES])
+ {
+ temp.printf(", %" QUADFORMAT"d fetch(es)", cnt);
+ record.append(temp);
+ }
+
+ if (const auto cnt = globalCounters[IPerformanceCounters::PAGE_MARKS])
+ {
+ temp.printf(", %" QUADFORMAT"d mark(s)", cnt);
+ record.append(temp);
+ }
}
record.append(NEWLINE);
}
-void TracePluginImpl::appendTableCounts(const PerformanceInfo *info)
+void TracePluginImpl::appendTableCounts(IPerformanceStats* stats)
{
- if (!config.print_perf || info->pin_count == 0)
+ if (!config.print_perf)
return;
- const TraceCounts* trc = info->pin_tables;
- const TraceCounts* trc_end = trc + info->pin_count;
+ const auto tableCounters = stats->getCounters(IPerformanceStats::COUNTER_GROUP_TABLES);
+ fb_assert(tableCounters);
+
+ const auto count = tableCounters->getObjectCount();
+ if (!count)
+ return;
FB_SIZE_T max_len = 0;
- for (; trc < trc_end; trc++)
+ for (unsigned i = 0; i < count; i++)
{
- FB_SIZE_T len = fb_strlen(trc->trc_relation_name);
- if (max_len < len)
- max_len = len;
+ if (const auto relName = tableCounters->getObjectName(i))
+ {
+ const FB_SIZE_T len = fb_strlen(relName);
+ if (max_len < len)
+ max_len = len;
+ }
}
if (max_len < 32)
@@ -691,24 +713,45 @@ void TracePluginImpl::appendTableCounts(const PerformanceInfo *info)
record.append(NEWLINE);
string temp;
- for (trc = info->pin_tables; trc < trc_end; trc++)
+ for (unsigned i = 0; i < count; i++)
{
- record.append(trc->trc_relation_name);
- record.append(max_len - fb_strlen(trc->trc_relation_name), ' ');
- for (int j = 0; j <= TraceCounts::EXPUNGES; j++)
+ const auto relName = tableCounters->getObjectName(i);
+ if (relName && *relName)
+ {
+ record.append(relName);
+ record.append(max_len - fb_strlen(relName), ' ');
+ }
+ else
+ {
+ temp.printf("Table id <%u>", tableCounters->getObjectId(i));
+ record.append(temp);
+ record.append(max_len - temp.length(), ' ');
+ }
+
+ const auto counters = tableCounters->getObjectCounters(i);
+
+ string line;
+ bool nonZero = false;
+ for (unsigned j = IPerformanceCounters::RECORD_SEQ_READS;
+ j <= IPerformanceCounters::RECORD_EXPUNGES; j++)
{
- if (trc->trc_counters[j] == 0)
+ if (counters[j] == 0)
{
- record.append(10, ' ');
+ line.append(10, ' ');
}
else
{
- //fb_utils::exactNumericToStr(trc->trc_counters[j], 0, temp);
+ //fb_utils::exactNumericToStr(counterVector[j], 0, temp);
//record.append(' ', 10 - temp.length());
- temp.printf("%10" QUADFORMAT"d", trc->trc_counters[j]);
- record.append(temp);
+ temp.printf("%10" QUADFORMAT"d", counters[j]);
+ line.append(temp);
+ nonZero = true;
}
}
+
+ if (nonZero)
+ record.append(line);
+
record.append(NEWLINE);
}
}
@@ -1494,11 +1537,10 @@ void TracePluginImpl::log_event_transaction_end(ITraceDatabaseConnection* connec
}
}
- PerformanceInfo* info = transaction->getPerf();
- if (info)
+ if (const auto stats = transaction->getPerfStats())
{
- appendGlobalCounts(info);
- appendTableCounts(info);
+ appendGlobalCounts(stats);
+ appendTableCounts(stats);
}
const char* event_type;
@@ -1596,8 +1638,8 @@ void TracePluginImpl::log_event_proc_execute(ITraceDatabaseConnection* connectio
return;
// Do not log operation if it is below time threshold
- const PerformanceInfo* info = started ? NULL : procedure->getPerf();
- if (config.time_threshold && info && info->pin_time < config.time_threshold)
+ IPerformanceStats* const stats = started ? nullptr : procedure->getPerfStats();
+ if (config.time_threshold && stats && stats->getElapsedTime() < config.time_threshold)
return;
ITraceParams* params = procedure->getInputs();
@@ -1608,16 +1650,17 @@ void TracePluginImpl::log_event_proc_execute(ITraceDatabaseConnection* connectio
record.append(NEWLINE);
}
- if (info)
+ if (stats)
{
- if (info->pin_records_fetched)
+ if (const auto cnt = stats->getFetchedRecords())
{
string temp;
- temp.printf("%" QUADFORMAT"d records fetched" NEWLINE, info->pin_records_fetched);
+ temp.printf("%" QUADFORMAT"d records fetched" NEWLINE, cnt);
record.append(temp);
}
- appendGlobalCounts(info);
- appendTableCounts(info);
+
+ appendGlobalCounts(stats);
+ appendTableCounts(stats);
}
const char* event_type;
@@ -1677,8 +1720,8 @@ void TracePluginImpl::log_event_func_execute(ITraceDatabaseConnection* connectio
return;
// Do not log operation if it is below time threshold
- const PerformanceInfo* info = started ? NULL : function->getPerf();
- if (config.time_threshold && info && info->pin_time < config.time_threshold)
+ IPerformanceStats* const stats = started ? nullptr : function->getPerfStats();
+ if (config.time_threshold && stats && stats->getElapsedTime() < config.time_threshold)
return;
ITraceParams* params = function->getInputs();
@@ -1699,16 +1742,17 @@ void TracePluginImpl::log_event_func_execute(ITraceDatabaseConnection* connectio
}
}
- if (info)
+ if (stats)
{
- if (info->pin_records_fetched)
+ if (const auto cnt = stats->getFetchedRecords())
{
string temp;
- temp.printf("%" QUADFORMAT"d records fetched" NEWLINE, info->pin_records_fetched);
+ temp.printf("%" QUADFORMAT"d records fetched" NEWLINE, cnt);
record.append(temp);
}
- appendGlobalCounts(info);
- appendTableCounts(info);
+
+ appendGlobalCounts(stats);
+ appendTableCounts(stats);
}
const char* event_type;
@@ -1767,14 +1811,14 @@ void TracePluginImpl::log_event_trigger_execute(ITraceDatabaseConnection* connec
return;
// Do not log operation if it is below time threshold
- const PerformanceInfo* info = started ? NULL : trigger->getPerf();
- if (config.time_threshold && info && info->pin_time < config.time_threshold)
+ IPerformanceStats* const stats = started ? nullptr : trigger->getPerfStats();
+ if (config.time_threshold && stats && stats->getElapsedTime() < config.time_threshold)
return;
- if (info)
+ if (stats)
{
- appendGlobalCounts(info);
- appendTableCounts(info);
+ appendGlobalCounts(stats);
+ appendTableCounts(stats);
}
const char* event_type;
@@ -1920,8 +1964,8 @@ void TracePluginImpl::log_event_dsql_execute(ITraceDatabaseConnection* connectio
return;
// Do not log operation if it is below time threshold
- const PerformanceInfo* info = started ? NULL : statement->getPerf();
- if (config.time_threshold && info && info->pin_time < config.time_threshold)
+ IPerformanceStats* const stats = started ? nullptr : statement->getPerfStats();
+ if (config.time_threshold && stats && stats->getElapsedTime() < config.time_threshold)
return;
if (restart)
@@ -1939,14 +1983,14 @@ void TracePluginImpl::log_event_dsql_execute(ITraceDatabaseConnection* connectio
record.append(NEWLINE);
}
- if (info)
+ if (stats)
{
string temp;
- temp.printf("%" QUADFORMAT"d records fetched" NEWLINE, info->pin_records_fetched);
+ temp.printf("%" QUADFORMAT"d records fetched" NEWLINE, stats->getFetchedRecords());
record.append(temp);
- appendGlobalCounts(info);
- appendTableCounts(info);
+ appendGlobalCounts(stats);
+ appendTableCounts(stats);
}
string event_type;
@@ -2058,16 +2102,19 @@ void TracePluginImpl::log_event_blr_execute(ITraceDatabaseConnection* connection
ITraceTransaction* transaction, ITraceBLRStatement* statement,
ntrace_result_t req_result)
{
- PerformanceInfo *info = statement->getPerf();
+ const auto stats = statement->getPerfStats();
// Do not log operation if it is below time threshold
- if (config.time_threshold && info->pin_time < config.time_threshold)
+ if (config.time_threshold && stats && stats->getElapsedTime() < config.time_threshold)
return;
if (config.log_blr_requests)
{
- appendGlobalCounts(info);
- appendTableCounts(info);
+ if (stats)
+ {
+ appendGlobalCounts(stats);
+ appendTableCounts(stats);
+ }
const char* event_type;
switch (req_result)
@@ -2440,11 +2487,10 @@ void TracePluginImpl::log_event_sweep(ITraceDatabaseConnection* connection, ITra
);
}
- PerformanceInfo* info = sweep->getPerf();
- if (info)
+ if (const auto stats = sweep->getPerfStats())
{
- appendGlobalCounts(info);
- appendTableCounts(info);
+ appendGlobalCounts(stats);
+ appendTableCounts(stats);
}
const char* event_type = NULL;
diff --git a/src/utilities/ntrace/TracePluginImpl.h b/src/utilities/ntrace/TracePluginImpl.h
index e84330599b1..4025af881ff 100644
--- a/src/utilities/ntrace/TracePluginImpl.h
+++ b/src/utilities/ntrace/TracePluginImpl.h
@@ -178,8 +178,8 @@ class TracePluginImpl final :
GdsCodesArray include_codes;
GdsCodesArray exclude_codes;
- void appendGlobalCounts(const Firebird::PerformanceInfo* info);
- void appendTableCounts(const Firebird::PerformanceInfo* info);
+ void appendGlobalCounts(Firebird::IPerformanceStats* stats);
+ void appendTableCounts(Firebird::IPerformanceStats* stats);
void appendParams(Firebird::ITraceParams* params);
void appendServiceQueryParams(size_t send_item_length, const ntrace_byte_t* send_items,
size_t recv_item_length, const ntrace_byte_t* recv_items);