Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HPCC-30949 Ensure that duplicate statistics are not added to a CStatsCollection #18097

Merged
merged 1 commit into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 59 additions & 2 deletions roxie/ccd/ccdserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,60 @@ class IndirectAgentContext : implements IRoxieAgentContext, public CInterface

//=================================================================================

class MergingStatsGatherer : implements CUnsharedInterfaceOf<IStatisticGatherer>
{
public:
MergingStatsGatherer(IStatisticGatherer * _gatherer) : gatherer(_gatherer)
{
}

virtual void beginScope(const StatsScopeId & id) override
{
gatherer->beginScope(id);
}
virtual void beginSubGraphScope(unsigned id) override
{
gatherer->beginSubGraphScope(id);
}
virtual void beginActivityScope(unsigned id) override
{
gatherer->beginActivityScope(id);
}
virtual void beginEdgeScope(unsigned id, unsigned oid) override
{
gatherer->beginEdgeScope(id, oid);
}
virtual void beginChildGraphScope(unsigned id) override
{
gatherer->beginChildGraphScope(id);
}
virtual void beginChannelScope(unsigned id) override
{
gatherer->beginChannelScope(id);
}
virtual void endScope() override
{
gatherer->endScope();
}
virtual void addStatistic(StatisticKind kind, unsigned __int64 value) override
{
//Always merge rather than add (otherwise it may create duplicate entries)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: merge rather than "add"

gatherer->updateStatistic(kind, value, queryMergeMode(kind));
}
virtual void updateStatistic(StatisticKind kind, unsigned __int64 value, StatsMergeAction mergeAction) override
{
gatherer->updateStatistic(kind, value, mergeAction);
}
virtual IStatisticCollection * getResult() override
{
return gatherer->getResult();
}

private:
IStatisticGatherer * gatherer;
};

//=================================================================================
#define RESULT_FLUSH_THRESHOLD 10000u

#ifdef _DEBUG
Expand Down Expand Up @@ -16532,8 +16586,9 @@ class CRoxieServerParallelGraphLoopActivity : public CRoxieServerGraphLoopActivi
resultStream = NULL;
resultJunction.clear();

MergingStatsGatherer mergeStats(childStats);
ForEachItemIn(i, iterationGraphs)
iterationGraphs.item(i).gatherStatistics(childStats);
iterationGraphs.item(i).gatherStatistics(childStats ? &mergeStats : nullptr);

outputs.kill();
iterationGraphs.kill(); // must be done after all activities killed
Expand Down Expand Up @@ -28506,9 +28561,11 @@ class CProxyActivityGraph : implements IActivityGraph, implements IThorChildGrap
virtual const char *queryName() const override { throwUnexpected(); }
virtual void gatherStatistics(IStatisticGatherer * statsBuilder) const override
{
//Merge the stats from multiple graph instances.
MergingStatsGatherer mergeStatsBuilder(statsBuilder);
CriticalBlock b(graphCrit);
ForEachItemIn(i, stack)
stack.item(i).gatherStatistics(statsBuilder);
stack.item(i).gatherStatistics(statsBuilder ? &mergeStatsBuilder : nullptr);
}
virtual IEclGraphResults * evaluate(unsigned parentExtractSize, const byte * parentExtract) override
{
Expand Down
7 changes: 7 additions & 0 deletions system/jlib/jstats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1917,8 +1917,15 @@ class CStatisticCollection : public CInterfaceOf<IStatisticCollection>
}

//other public interface functions
// addStatistic() should only be used if it is known that the kind is not already there
void addStatistic(StatisticKind kind, unsigned __int64 value)
{
#ifdef _DEBUG
// In debug builds check that a value for this kind has not already been added.
// We do not want the O(N) overhead in release mode, especially as N is beginning to get larger
unsigned __int64 debugTest;
assertex(getStatistic(kind,debugTest)==false);
#endif
Statistic s(kind, value);
stats.append(s);
}
Expand Down
2 changes: 1 addition & 1 deletion system/jlib/jstats.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ interface IStatisticGatherer : public IInterface
virtual void beginChildGraphScope(unsigned id) = 0;
virtual void beginChannelScope(unsigned id) = 0;
virtual void endScope() = 0;
virtual void addStatistic(StatisticKind kind, unsigned __int64 value) = 0;
virtual void addStatistic(StatisticKind kind, unsigned __int64 value) = 0; // use updateStatistic() if kind could already be defined for the active scope
virtual void updateStatistic(StatisticKind kind, unsigned __int64 value, StatsMergeAction mergeAction) = 0;
virtual IStatisticCollection * getResult() = 0;
};
Expand Down
Loading