Skip to content

Commit 8f20634

Browse files
committed
Refactor RuntimeStatistics to make it more extendable for future counters (including grouped ones)
1 parent 6b73fa8 commit 8f20634

File tree

12 files changed

+391
-326
lines changed

12 files changed

+391
-326
lines changed

src/jrd/Attachment.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -632,10 +632,12 @@ void Jrd::Attachment::signalShutdown(ISC_STATUS code)
632632
void Jrd::Attachment::mergeStats(bool pageStatsOnly)
633633
{
634634
MutexLockGuard guard(att_database->dbb_stats_mutex, FB_FUNCTION);
635-
att_database->dbb_stats.adjustPageStats(att_base_stats, att_stats);
636-
if (!pageStatsOnly)
635+
636+
if (pageStatsOnly)
637+
att_database->dbb_stats.adjustPageStats(att_base_stats, att_stats);
638+
else
637639
{
638-
att_database->dbb_stats.adjust(att_base_stats, att_stats, true);
640+
att_database->dbb_stats.adjust(att_base_stats, att_stats);
639641
att_base_stats.assign(att_stats);
640642
}
641643
}

src/jrd/Monitoring.cpp

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,36 +1422,36 @@ void Monitoring::putStatistics(SnapshotData::DumpRecord& record, const RuntimeSt
14221422
record.reset(rel_mon_io_stats);
14231423
record.storeGlobalId(f_mon_io_stat_id, id);
14241424
record.storeInteger(f_mon_io_stat_group, stat_group);
1425-
record.storeInteger(f_mon_io_page_reads, statistics.getValue(RuntimeStatistics::PAGE_READS));
1426-
record.storeInteger(f_mon_io_page_writes, statistics.getValue(RuntimeStatistics::PAGE_WRITES));
1427-
record.storeInteger(f_mon_io_page_fetches, statistics.getValue(RuntimeStatistics::PAGE_FETCHES));
1428-
record.storeInteger(f_mon_io_page_marks, statistics.getValue(RuntimeStatistics::PAGE_MARKS));
1425+
record.storeInteger(f_mon_io_page_reads, statistics[PageStatType::READS]);
1426+
record.storeInteger(f_mon_io_page_writes, statistics[PageStatType::WRITES]);
1427+
record.storeInteger(f_mon_io_page_fetches, statistics[PageStatType::FETCHES]);
1428+
record.storeInteger(f_mon_io_page_marks, statistics[PageStatType::MARKS]);
14291429
record.write();
14301430

14311431
// logical I/O statistics (global)
14321432
record.reset(rel_mon_rec_stats);
14331433
record.storeGlobalId(f_mon_rec_stat_id, id);
14341434
record.storeInteger(f_mon_rec_stat_group, stat_group);
1435-
record.storeInteger(f_mon_rec_seq_reads, statistics.getValue(RuntimeStatistics::RECORD_SEQ_READS));
1436-
record.storeInteger(f_mon_rec_idx_reads, statistics.getValue(RuntimeStatistics::RECORD_IDX_READS));
1437-
record.storeInteger(f_mon_rec_inserts, statistics.getValue(RuntimeStatistics::RECORD_INSERTS));
1438-
record.storeInteger(f_mon_rec_updates, statistics.getValue(RuntimeStatistics::RECORD_UPDATES));
1439-
record.storeInteger(f_mon_rec_deletes, statistics.getValue(RuntimeStatistics::RECORD_DELETES));
1440-
record.storeInteger(f_mon_rec_backouts, statistics.getValue(RuntimeStatistics::RECORD_BACKOUTS));
1441-
record.storeInteger(f_mon_rec_purges, statistics.getValue(RuntimeStatistics::RECORD_PURGES));
1442-
record.storeInteger(f_mon_rec_expunges, statistics.getValue(RuntimeStatistics::RECORD_EXPUNGES));
1443-
record.storeInteger(f_mon_rec_locks, statistics.getValue(RuntimeStatistics::RECORD_LOCKS));
1444-
record.storeInteger(f_mon_rec_waits, statistics.getValue(RuntimeStatistics::RECORD_WAITS));
1445-
record.storeInteger(f_mon_rec_conflicts, statistics.getValue(RuntimeStatistics::RECORD_CONFLICTS));
1446-
record.storeInteger(f_mon_rec_bkver_reads, statistics.getValue(RuntimeStatistics::RECORD_BACKVERSION_READS));
1447-
record.storeInteger(f_mon_rec_frg_reads, statistics.getValue(RuntimeStatistics::RECORD_FRAGMENT_READS));
1448-
record.storeInteger(f_mon_rec_rpt_reads, statistics.getValue(RuntimeStatistics::RECORD_RPT_READS));
1449-
record.storeInteger(f_mon_rec_imgc, statistics.getValue(RuntimeStatistics::RECORD_IMGC));
1435+
record.storeInteger(f_mon_rec_seq_reads, statistics[RecordStatType::SEQ_READS]);
1436+
record.storeInteger(f_mon_rec_idx_reads, statistics[RecordStatType::IDX_READS]);
1437+
record.storeInteger(f_mon_rec_inserts, statistics[RecordStatType::INSERTS]);
1438+
record.storeInteger(f_mon_rec_updates, statistics[RecordStatType::UPDATES]);
1439+
record.storeInteger(f_mon_rec_deletes, statistics[RecordStatType::DELETES]);
1440+
record.storeInteger(f_mon_rec_backouts, statistics[RecordStatType::BACKOUTS]);
1441+
record.storeInteger(f_mon_rec_purges, statistics[RecordStatType::PURGES]);
1442+
record.storeInteger(f_mon_rec_expunges, statistics[RecordStatType::EXPUNGES]);
1443+
record.storeInteger(f_mon_rec_locks, statistics[RecordStatType::LOCKS]);
1444+
record.storeInteger(f_mon_rec_waits, statistics[RecordStatType::WAITS]);
1445+
record.storeInteger(f_mon_rec_conflicts, statistics[RecordStatType::CONFLICTS]);
1446+
record.storeInteger(f_mon_rec_bkver_reads, statistics[RecordStatType::BACK_READS]);
1447+
record.storeInteger(f_mon_rec_frg_reads, statistics[RecordStatType::FRAGMENT_READS]);
1448+
record.storeInteger(f_mon_rec_rpt_reads, statistics[RecordStatType::RPT_READS]);
1449+
record.storeInteger(f_mon_rec_imgc, statistics[RecordStatType::IMGC]);
14501450
record.write();
14511451

14521452
// logical I/O statistics (table wise)
14531453

1454-
for (RuntimeStatistics::Iterator iter = statistics.begin(); iter != statistics.end(); ++iter)
1454+
for (auto iter(statistics.getRelCounters()); iter; ++iter)
14551455
{
14561456
const auto rec_stat_id = getGlobalId(fb_utils::genUniqueId());
14571457

@@ -1466,21 +1466,21 @@ void Monitoring::putStatistics(SnapshotData::DumpRecord& record, const RuntimeSt
14661466
record.reset(rel_mon_rec_stats);
14671467
record.storeGlobalId(f_mon_rec_stat_id, rec_stat_id);
14681468
record.storeInteger(f_mon_rec_stat_group, stat_group);
1469-
record.storeInteger(f_mon_rec_seq_reads, (*iter).getCounter(RuntimeStatistics::RECORD_SEQ_READS));
1470-
record.storeInteger(f_mon_rec_idx_reads, (*iter).getCounter(RuntimeStatistics::RECORD_IDX_READS));
1471-
record.storeInteger(f_mon_rec_inserts, (*iter).getCounter(RuntimeStatistics::RECORD_INSERTS));
1472-
record.storeInteger(f_mon_rec_updates, (*iter).getCounter(RuntimeStatistics::RECORD_UPDATES));
1473-
record.storeInteger(f_mon_rec_deletes, (*iter).getCounter(RuntimeStatistics::RECORD_DELETES));
1474-
record.storeInteger(f_mon_rec_backouts, (*iter).getCounter(RuntimeStatistics::RECORD_BACKOUTS));
1475-
record.storeInteger(f_mon_rec_purges, (*iter).getCounter(RuntimeStatistics::RECORD_PURGES));
1476-
record.storeInteger(f_mon_rec_expunges, (*iter).getCounter(RuntimeStatistics::RECORD_EXPUNGES));
1477-
record.storeInteger(f_mon_rec_locks, (*iter).getCounter(RuntimeStatistics::RECORD_LOCKS));
1478-
record.storeInteger(f_mon_rec_waits, (*iter).getCounter(RuntimeStatistics::RECORD_WAITS));
1479-
record.storeInteger(f_mon_rec_conflicts, (*iter).getCounter(RuntimeStatistics::RECORD_CONFLICTS));
1480-
record.storeInteger(f_mon_rec_bkver_reads, (*iter).getCounter(RuntimeStatistics::RECORD_BACKVERSION_READS));
1481-
record.storeInteger(f_mon_rec_frg_reads, (*iter).getCounter(RuntimeStatistics::RECORD_FRAGMENT_READS));
1482-
record.storeInteger(f_mon_rec_rpt_reads, (*iter).getCounter(RuntimeStatistics::RECORD_RPT_READS));
1483-
record.storeInteger(f_mon_rec_imgc, (*iter).getCounter(RuntimeStatistics::RECORD_IMGC));
1469+
record.storeInteger(f_mon_rec_seq_reads, (*iter)[RecordStatType::SEQ_READS]);
1470+
record.storeInteger(f_mon_rec_idx_reads, (*iter)[RecordStatType::IDX_READS]);
1471+
record.storeInteger(f_mon_rec_inserts, (*iter)[RecordStatType::INSERTS]);
1472+
record.storeInteger(f_mon_rec_updates, (*iter)[RecordStatType::UPDATES]);
1473+
record.storeInteger(f_mon_rec_deletes, (*iter)[RecordStatType::DELETES]);
1474+
record.storeInteger(f_mon_rec_backouts, (*iter)[RecordStatType::BACKOUTS]);
1475+
record.storeInteger(f_mon_rec_purges, (*iter)[RecordStatType::PURGES]);
1476+
record.storeInteger(f_mon_rec_expunges, (*iter)[RecordStatType::EXPUNGES]);
1477+
record.storeInteger(f_mon_rec_locks, (*iter)[RecordStatType::LOCKS]);
1478+
record.storeInteger(f_mon_rec_waits, (*iter)[RecordStatType::WAITS]);
1479+
record.storeInteger(f_mon_rec_conflicts, (*iter)[RecordStatType::CONFLICTS]);
1480+
record.storeInteger(f_mon_rec_bkver_reads, (*iter)[RecordStatType::BACK_READS]);
1481+
record.storeInteger(f_mon_rec_frg_reads, (*iter)[RecordStatType::FRAGMENT_READS]);
1482+
record.storeInteger(f_mon_rec_rpt_reads, (*iter)[RecordStatType::RPT_READS]);
1483+
record.storeInteger(f_mon_rec_imgc, (*iter)[RecordStatType::IMGC]);
14841484
record.write();
14851485
}
14861486
}

src/jrd/RuntimeStatistics.cpp

Lines changed: 77 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -33,47 +33,58 @@ namespace Jrd {
3333

3434
GlobalPtr<RuntimeStatistics> RuntimeStatistics::dummy;
3535

36-
void RuntimeStatistics::findAndBumpRelValue(const StatType index, SLONG relation_id, SINT64 delta)
36+
void RuntimeStatistics::adjustRelStats(const RuntimeStatistics& baseStats, const RuntimeStatistics& newStats)
3737
{
38-
if (rel_counts.find(relation_id, rel_last_pos))
39-
rel_counts[rel_last_pos].bumpCounter(index, delta);
40-
else
41-
{
42-
RelationCounts counts(relation_id);
43-
counts.bumpCounter(index, delta);
44-
rel_counts.insert(rel_last_pos, counts);
45-
}
46-
}
47-
48-
void RuntimeStatistics::addRelCounts(const RelCounters& other, bool add)
49-
{
50-
if (other.isEmpty())
38+
if (baseStats.relChgNumber == newStats.relChgNumber)
5139
return;
5240

53-
RelCounters::const_iterator src(other.begin());
54-
const RelCounters::const_iterator end(other.end());
41+
relChgNumber++;
5542

56-
FB_SIZE_T pos;
57-
rel_counts.find(src->getRelationId(), pos);
58-
for (; src != end; ++src)
43+
auto locate = [this](SLONG relId) -> FB_SIZE_T
5944
{
60-
const FB_SIZE_T cnt = rel_counts.getCount();
45+
FB_SIZE_T pos;
46+
if (!rel_counts.find(relId, pos))
47+
rel_counts.insert(pos, RelationCounts(relId));
48+
return pos;
49+
};
6150

62-
while (pos < cnt && rel_counts[pos].getRelationId() < src->getRelationId())
63-
pos++;
51+
auto baseIter = baseStats.rel_counts.begin(), newIter = newStats.rel_counts.begin();
52+
const auto baseEnd = baseStats.rel_counts.end(), newEnd = newStats.rel_counts.end();
6453

65-
if (pos >= cnt || rel_counts[pos].getRelationId() > src->getRelationId())
54+
// The loop below assumes that newStats cannot miss relations existing in baseStats,
55+
// this must be always the case as long as newStats is an incremented version of baseStats
56+
57+
while (newIter != newEnd || baseIter != baseEnd)
58+
{
59+
if (baseIter == baseEnd)
6660
{
67-
RelationCounts counts(src->getRelationId());
68-
rel_counts.insert(pos, counts);
61+
// Relation exists in newStats but missing in baseStats
62+
const auto newRelId = newIter->getRelationId();
63+
rel_counts[locate(newRelId)] += *newIter++;
6964
}
65+
else if (newIter != newEnd)
66+
{
67+
const auto baseRelId = baseIter->getRelationId();
68+
const auto newRelId = newIter->getRelationId();
7069

71-
fb_assert(pos >= 0 && pos < rel_counts.getCount());
72-
73-
if (add)
74-
rel_counts[pos] += *src;
70+
if (newRelId == baseRelId)
71+
{
72+
// Relation exists in both newStats and baseStats
73+
fb_assert(baseRelId == newRelId);
74+
const auto pos = locate(baseRelId);
75+
rel_counts[pos] -= *baseIter++;
76+
rel_counts[pos] += *newIter++;
77+
}
78+
else if (newRelId < baseRelId)
79+
{
80+
// Relation exists in newStats but missing in baseStats
81+
rel_counts[locate(newRelId)] += *newIter++;
82+
}
83+
else
84+
fb_assert(false); // should never happen
85+
}
7586
else
76-
rel_counts[pos] -= *src;
87+
fb_assert(false); // should never happen
7788
}
7889
}
7990

@@ -86,7 +97,7 @@ PerformanceInfo* RuntimeStatistics::computeDifference(Attachment* att,
8697
// NOTE: we do not initialize dest.pin_time. This must be done by the caller
8798

8899
// Calculate database-level statistics
89-
for (int i = 0; i < TOTAL_ITEMS; i++)
100+
for (size_t i = 0; i < GLOBAL_ITEMS; i++)
90101
values[i] = new_stat.values[i] - values[i];
91102

92103
dest.pin_counters = values;
@@ -99,16 +110,14 @@ PerformanceInfo* RuntimeStatistics::computeDifference(Attachment* att,
99110
RelCounters::iterator base_cnts = rel_counts.begin();
100111
bool base_found = (base_cnts != rel_counts.end());
101112

102-
RelCounters::const_iterator new_cnts = new_stat.rel_counts.begin();
103-
const RelCounters::const_iterator end = new_stat.rel_counts.end();
104-
for (; new_cnts != end; ++new_cnts)
113+
for (const auto& new_cnts : new_stat.rel_counts)
105114
{
106-
const SLONG rel_id = new_cnts->getRelationId();
115+
const SLONG rel_id = new_cnts.getRelationId();
107116

108117
if (base_found && base_cnts->getRelationId() == rel_id)
109118
{
110119
// Point TraceCounts to counts array from baseline object
111-
if (base_cnts->setToDiff(*new_cnts))
120+
if (base_cnts->setToDiff(new_cnts))
112121
{
113122
jrd_rel* const relation =
114123
rel_id < static_cast<SLONG>(att->att_relations->count()) ?
@@ -142,7 +151,7 @@ PerformanceInfo* RuntimeStatistics::computeDifference(Attachment* att,
142151
// Point TraceCounts to counts array from object with updated counters
143152
TraceCounts traceCounts;
144153
traceCounts.trc_relation_id = rel_id;
145-
traceCounts.trc_counters = new_cnts->getCounterVector();
154+
traceCounts.trc_counters = new_cnts.getCounterVector();
146155

147156
if (relation)
148157
{
@@ -163,14 +172,42 @@ PerformanceInfo* RuntimeStatistics::computeDifference(Attachment* att,
163172
return &dest;
164173
}
165174

166-
RuntimeStatistics::Accumulator::Accumulator(thread_db* tdbb, const jrd_rel* relation, StatType type)
167-
: m_tdbb(tdbb), m_type(type), m_id(relation->rel_id), m_counter(0)
175+
void RuntimeStatistics::adjust(const RuntimeStatistics& baseStats, const RuntimeStatistics& newStats)
176+
{
177+
if (baseStats.allChgNumber == newStats.allChgNumber)
178+
return;
179+
180+
allChgNumber++;
181+
for (size_t i = 0; i < GLOBAL_ITEMS; ++i)
182+
values[i] += newStats.values[i] - baseStats.values[i];
183+
184+
adjustRelStats(baseStats, newStats);
185+
}
186+
187+
void RuntimeStatistics::adjustPageStats(RuntimeStatistics& baseStats, const RuntimeStatistics& newStats)
188+
{
189+
if (baseStats.allChgNumber == newStats.allChgNumber)
190+
return;
191+
192+
allChgNumber++;
193+
for (size_t i = 0; i < PAGE_TOTAL_ITEMS; ++i)
194+
{
195+
const SINT64 delta = newStats.values[i] - baseStats.values[i];
196+
197+
values[i] += delta;
198+
baseStats.values[i] += delta;
199+
}
200+
}
201+
202+
RuntimeStatistics::Accumulator::Accumulator(thread_db* tdbb, const jrd_rel* relation,
203+
const RecordStatType type)
204+
: m_tdbb(tdbb), m_type(type), m_id(relation->rel_id)
168205
{}
169206

170207
RuntimeStatistics::Accumulator::~Accumulator()
171208
{
172209
if (m_counter)
173-
m_tdbb->bumpRelStats(m_type, m_id, m_counter);
210+
m_tdbb->bumpStats(m_type, m_id, m_counter);
174211
}
175212

176213
} // namespace

0 commit comments

Comments
 (0)