瀏覽代碼

HPCC-26788 Add support for visitor to IStatisticCollection

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday 3 年之前
父節點
當前提交
d5119f1e80
共有 2 個文件被更改,包括 72 次插入1 次删除
  1. 62 1
      system/jlib/jstats.cpp
  2. 10 0
      system/jlib/jstats.h

+ 62 - 1
system/jlib/jstats.cpp

@@ -1832,7 +1832,7 @@ public:
 
     CStatisticCollection * ensureSubScope(const StatsScopeId & search, bool hasChildren)
     {
-        //Once the CStatisicCollection is created it should not be replaced - so that returned pointers remain valid.
+        //Once the CStatisticCollection is created it should not be replaced - so that returned pointers remain valid.
         CStatisticCollection * match = children.find(&search);
         if (match)
             return match;
@@ -1869,6 +1869,21 @@ public:
             cur.mergeInto(target);
     }
 
+    virtual void visit(IStatisticVisitor & visitor) const
+    {
+        if (visitor.visitScope(*this))
+        {
+            for (auto const & cur : children)
+                cur.visit(visitor);
+        }
+    }
+
+    virtual void visitChildren(IStatisticVisitor & visitor) const
+    {
+        for (auto const & cur : children)
+            cur.visit(visitor);
+    }
+
 private:
     StatsScopeId id;
     CStatisticCollection * parent;
@@ -1988,6 +2003,52 @@ public:
     unsigned __int64 whenCreated;
 };
 
+
+class StatAggregator : implements IStatisticVisitor
+{
+public:
+    StatAggregator(StatisticKind _kind) : kind(_kind) {}
+
+    virtual bool visitScope(const IStatisticCollection & cur)
+    {
+        switch (cur.queryScopeType())
+        {
+        //If there is a match for the stat in any of these containers, then avoid summing any child scopes
+        case SSTglobal:
+        case SSTgraph:
+        case SSTsubgraph:
+        case SSTsection:
+        case SSTchildgraph:
+        case SSTworkflow:
+        {
+            stat_type value;
+            if (cur.getStatistic(kind, value))
+            {
+                total += value;
+                return false;
+            }
+            return true;
+        }
+        //Default is to sum the value for this scope and children => recurse.  E.g. activity and any child activities.
+        default:
+            total += cur.queryStatistic(kind);
+            return true;
+        }
+    }
+    stat_type getTotal() const { return total; }
+private:
+    stat_type total = 0;
+    StatisticKind kind;
+};
+
+
+stat_type aggregateStatistic(StatisticKind kind, IStatisticCollection * statsCollection)
+{
+    StatAggregator aggregator(kind);
+    statsCollection->visit(aggregator);
+    return aggregator.getTotal();
+}
+
 //---------------------------------------------------------------------------------------------------------------------
 
 void serializeStatisticCollection(MemoryBuffer & out, IStatisticCollection * collection)

+ 10 - 0
system/jlib/jstats.h

@@ -102,6 +102,8 @@ protected:
 
 interface IStatisticCollectionIterator;
 interface IStatisticGatherer;
+interface IStatisticVisitor;
+
 interface IStatisticCollection : public IInterface
 {
 public:
@@ -119,12 +121,19 @@ public:
     virtual unsigned __int64 queryWhenCreated() const = 0;
     virtual void mergeInto(IStatisticGatherer & target) const = 0;
     virtual StringBuffer &toXML(StringBuffer &out) const = 0;
+    virtual void visit(IStatisticVisitor & target) const = 0;
+    virtual void visitChildren(IStatisticVisitor & target) const = 0;
 };
 
 interface IStatisticCollectionIterator : public IIteratorOf<IStatisticCollection>
 {
 };
 
+interface IStatisticVisitor
+{
+    virtual bool visitScope(const IStatisticCollection & cur) = 0;        // return true to iterate through children
+};
+
 enum StatsMergeAction
 {
     StatsMergeKeepNonZero,
@@ -853,5 +862,6 @@ public:
 };
 
 extern jlib_decl StringBuffer & formatMoney(StringBuffer &out, unsigned __int64 value);
+extern jlib_decl stat_type aggregateStatistic(StatisticKind kind, IStatisticCollection * statsCollection);
 
 #endif