Browse Source

HPCC-19731 Improve wuStats filter checking

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday 7 years ago
parent
commit
c0fd9b3632
3 changed files with 54 additions and 2 deletions
  1. 2 0
      common/workunit/workunit.cpp
  2. 47 2
      system/jlib/jstats.cpp
  3. 5 0
      system/jlib/jstats.h

+ 2 - 0
common/workunit/workunit.cpp

@@ -2877,6 +2877,8 @@ bool WuScopeFilter::matchOnly(StatisticScopeType scopeType) const
 //Called once the filter has been updated to optimize the filter
 void WuScopeFilter::finishedFilter()
 {
+    scopeFilter.finishedFilter();
+
     assertex(!optimized);
     optimized = true;
 

+ 47 - 2
system/jlib/jstats.cpp

@@ -2725,7 +2725,9 @@ void ScopeFilter::addScope(const char * scope)
         return;
     }
 
-    dbgassertex(!ids && !scopeTypes); // Illegal to specify scopes and ids or scope Types.
+    if (ids)
+        throw makeStringExceptionV(0, "Cannot filter by id and scope in the same request");
+
     unsigned depth = queryScopeDepth(scope);
     if ((scopes.ordinality() == 0) || (depth < minDepth))
         minDepth = depth;
@@ -2752,7 +2754,9 @@ void ScopeFilter::addScopeType(StatisticScopeType scopeType)
 
 void ScopeFilter::addId(const char * id)
 {
-    dbgassertex(!scopes && !scopeTypes);
+    if (scopes)
+        throw makeStringExceptionV(0, "Cannot filter by id and scope in the same request");
+
     ids.append(id);
 }
 
@@ -2766,6 +2770,18 @@ void ScopeFilter::setDepth(unsigned low, unsigned high)
 }
 
 
+void ScopeFilter::intersectDepth(const unsigned low, const unsigned high)
+{
+    if (low > high)
+        throw makeStringExceptionV(0, "Depth parameters in wrong order %u..%u", low, high);
+
+    if (minDepth < low)
+        minDepth = low;
+    if (maxDepth > high)
+        maxDepth = high;
+}
+
+
 ScopeCompare ScopeFilter::compare(const char * scope) const
 {
     ScopeCompare result = SCunknown;
@@ -2837,6 +2853,35 @@ int ScopeFilter::compareDepth(unsigned depth) const
     return 0;
 }
 
+void ScopeFilter::finishedFilter()
+{
+    //If scopeTypes are provided, then this code ensure that any scopes and ids match them
+    //but that would have little benefit, and would cause complications if the only id was removed
+
+    //Some scope types can only exist at a single level.
+    if (scopeTypes.ordinality() == 1)
+    {
+        switch (scopeTypes.item(0))
+        {
+        case SSTglobal:
+            intersectDepth(0, 0);
+            break;
+        case SSTworkflow:
+            intersectDepth(1, 1);
+            break;
+        case SSTgraph:
+            intersectDepth(2, 2);
+            break;
+        case SSTsubgraph:
+            intersectDepth(3, UINT_MAX);
+            break;
+        case SSTactivity:
+            intersectDepth(4, UINT_MAX);
+            break;
+        }
+    }
+}
+
 bool ScopeFilter::hasSingleMatch() const
 {
     return scopes.ordinality() == 1 || ids.ordinality() == 1;

+ 5 - 0
system/jlib/jstats.h

@@ -300,10 +300,15 @@ public:
     int compareDepth(unsigned depth) const; // -1 too shallow, 0 a match, +1 too deep
     bool hasSingleMatch() const;
     bool canAlwaysPreFilter() const;
+    void finishedFilter();
+
     const StringArray & queryScopes() const { return scopes; }
     bool matchOnly(StatisticScopeType scopeType) const;
 
 protected:
+    void intersectDepth(unsigned _minDepth, unsigned _maxDepth);
+
+protected:
     UnsignedArray scopeTypes;
     StringArray scopes;
     StringArray ids;