8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 23:23:03 +01:00
firebird-mirror/src/jrd/RuntimeStatistics.cpp

157 lines
4.4 KiB
C++

/*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Dmitry Yemanov
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2006 Dmitry Yemanov <dimitr@users.sf.net>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#include "firebird.h"
#include "../common/gdsassert.h"
#include "../jrd/req.h"
#include "../jrd/RuntimeStatistics.h"
#include "../jrd/ntrace.h"
using namespace Firebird;
namespace Jrd {
GlobalPtr<RuntimeStatistics> RuntimeStatistics::dummy;
void RuntimeStatistics::findAndBumpRelValue(const StatType index, SLONG relation_id, SINT64 delta)
{
if (rel_counts.find(relation_id, rel_last_pos))
rel_counts[rel_last_pos].bumpCounter(index, delta);
else
{
RelationCounts counts(relation_id);
counts.bumpCounter(index, delta);
rel_counts.insert(rel_last_pos, counts);
}
}
void RuntimeStatistics::addRelCounts(const RelCounters& other, bool add)
{
if (other.isEmpty())
return;
RelCounters::const_iterator src(other.begin());
const RelCounters::const_iterator end(other.end());
FB_SIZE_T pos;
rel_counts.find(src->getRelationId(), pos);
for (; src != end; ++src)
{
const FB_SIZE_T cnt = rel_counts.getCount();
while (pos < cnt && rel_counts[pos].getRelationId() < src->getRelationId())
pos++;
if (pos >= cnt || rel_counts[pos].getRelationId() > src->getRelationId())
{
RelationCounts counts(src->getRelationId());
rel_counts.insert(pos, counts);
}
fb_assert(pos >= 0 && pos < rel_counts.getCount());
if (add)
rel_counts[pos] += *src;
else
rel_counts[pos] -= *src;
}
}
PerformanceInfo* RuntimeStatistics::computeDifference(Attachment* att,
const RuntimeStatistics& new_stat,
PerformanceInfo& dest,
TraceCountsArray& temp)
{
// NOTE: we do not initialize dest.pin_time. This must be done by the caller
// Calculate database-level statistics
for (int i = 0; i < TOTAL_ITEMS; i++)
values[i] = new_stat.values[i] - values[i];
dest.pin_counters = values;
// Calculate relation-level statistics
temp.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());
RelCounters::const_iterator new_cnts = new_stat.rel_counts.begin();
const RelCounters::const_iterator end = new_stat.rel_counts.end();
for (; new_cnts != end; ++new_cnts)
{
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<SLONG>(att->att_relations->count()) ?
(*att->att_relations)[rel_id] : NULL;
TraceCounts traceCounts;
traceCounts.trc_relation_id = rel_id;
traceCounts.trc_counters = base_cnts->getCounterVector();
traceCounts.trc_relation_name = relation ? relation->rel_name.c_str() : NULL;
temp.add(traceCounts);
}
++base_cnts;
base_found = (base_cnts != rel_counts.end());
}
else
{
jrd_rel* const relation =
rel_id < static_cast<SLONG>(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();
traceCounts.trc_relation_name = relation ? relation->rel_name.c_str() : NULL;
temp.add(traceCounts);
}
};
dest.pin_count = temp.getCount();
dest.pin_tables = temp.begin();
return &dest;
}
RuntimeStatistics::Accumulator::Accumulator(thread_db* tdbb, const jrd_rel* relation, StatType type)
: m_tdbb(tdbb), m_type(type), m_id(relation->rel_id), m_counter(0)
{}
RuntimeStatistics::Accumulator::~Accumulator()
{
if (m_counter)
m_tdbb->bumpRelStats(m_type, m_id, m_counter);
}
} // namespace