فهرست منبع

Merge branch 'candidate-7.8.x' into candidate-7.10.x

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 4 سال پیش
والد
کامیت
020876ca22
3فایلهای تغییر یافته به همراه77 افزوده شده و 22 حذف شده
  1. 46 21
      common/workunit/workunit.cpp
  2. 30 1
      system/jlib/jptree.cpp
  3. 1 0
      system/jlib/jptree.hpp

+ 46 - 21
common/workunit/workunit.cpp

@@ -1575,20 +1575,13 @@ private:
                 return true;
             case SChildGraph:
             {
+#ifdef _DEBUG
+                assertex(treeIters.tos().query().getPropInt("att[@name='_kind']/@value") == TAKsubgraph);
                 unsigned numIters = treeIters.ordinality();
-                //This should really be implemented by a filter on the node - but it would require _kind/_parentActivity to move to the node tag
-                if (treeIters.tos().query().getPropInt("att[@name='_kind']/@value") != TAKsubgraph)
-                {
-                    state = SChildGraphNext;
-                    break;
-                }
                 unsigned parentActivityId = treeIters.item(numIters-2).query().getPropInt("@id");
                 unsigned parentId = treeIters.tos().query().getPropInt("att[@name='_parentActivity']/@value");
-                if (parentId != parentActivityId)
-                {
-                    state = SChildGraphNext;
-                    break;
-                }
+                assertex(parentId == parentActivityId);
+#endif
                 scopeId.set(ChildGraphScopePrefix).append(treeIters.tos().query().getPropInt("@id"));
                 pushScope(scopeId);
                 scopeType = SSTchildgraph;
@@ -1694,11 +1687,27 @@ private:
             }
             case SSubGraphFirstActivity:
             {
+                //Walk the contents of each subgraph once, splitting the entries into activities and child graphs
+                IArrayOf<IPropertyTree> activities;
+                IArrayOf<IPropertyTree> childGraphs;
                 Owned<IPropertyTreeIterator> treeIter = treeIters.tos().query().getElements("att/graph/node");
-                if (treeIter && treeIter->first())
+                ForEach(*treeIter)
+                {
+                    IPropertyTree & cur = treeIter->get();
+                    if (cur.getPropInt("att[@name='_kind']/@value") != TAKsubgraph)
+                        activities.append(cur);
+                    else
+                        childGraphs.append(cur);
+                }
+                if (activities.ordinality())
                 {
-                    treeIter.setown(createSortedIterator(*treeIter, compareActivityNode));
-                    pushIterator(treeIter, SSubGraphEnd);
+                    //Create an iterator for the child graphs in this subgraph which is iterated in order as the activities are processed
+                    Owned<IPropertyTreeIterator> graphIter = createSortedIterator(childGraphs, compareSubGraphNode);
+                    graphIter->first();
+                    childGraphIters.append(*graphIter.getClear());
+
+                    Owned<IPropertyTreeIterator> activityIter = createSortedIterator(activities, compareActivityNode);
+                    pushIterator(activityIter, SSubGraphEnd);
                     state = SActivity;
                 }
                 else
@@ -1727,7 +1736,11 @@ private:
                 if (treeIters.tos().next())
                     state = SActivity;
                 else
+                {
+                    assertex(!childGraphIters.tos().isValid());
+                    childGraphIters.pop();
                     state = popIterator();
+                }
                 break;
             case SChildGraphNext:
                 if (treeIters.tos().next())
@@ -1737,13 +1750,22 @@ private:
                 break;
             case SChildGraphFirst:
             {
-                unsigned numIters = treeIters.ordinality();
-                IPropertyTreeIterator & graphIter = treeIters.item(numIters-2);
-                Owned<IPropertyTreeIterator> treeIter = graphIter.query().getElements("att/graph/node");
-                //Really want to filter by <att name="_parentActivity" value="<parentid>">
-                if (treeIter && treeIter->first())
+                unsigned parentActivityId = treeIters.tos().query().getPropInt("@id");
+                IArrayOf<IPropertyTree> childGraphs;
+                IPropertyTreeIterator & allGraphs = childGraphIters.tos();
+                while (allGraphs.isValid())
                 {
-                    treeIter.setown(createSortedIterator(*treeIter, compareSubGraphNode));
+                    IPropertyTree & cur = allGraphs.query();
+                    unsigned parentId = cur.getPropInt("att[@name='_parentActivity']/@value");
+                    if (parentId != parentActivityId)
+                        break;
+                    childGraphs.append(OLINK(cur));
+                    allGraphs.next();
+                }
+
+                if (childGraphs.ordinality())
+                {
+                    Owned<IPropertyTreeIterator> treeIter = createSortedIterator(childGraphs, compareSubGraphNode);
                     pushIterator(treeIter, SActivityEnd);
                     state = SChildGraph;
                 }
@@ -1839,10 +1861,12 @@ private:
         case SGraph:
             state = SDone;
             break;
+        case SActivity:
+            childGraphIters.pop();
+            //fall through
         case SChildGraph:
         case SSubGraph:
         case SEdge:
-        case SActivity:
             popScope();
             state = popIterator();
             break;
@@ -1859,6 +1883,7 @@ protected:
     Owned<IConstWUGraphIterator> graphIter;
     Owned<IPropertyTree> curGraph;
     IArrayOf<IPropertyTreeIterator> treeIters;
+    IArrayOf<IPropertyTreeIterator> childGraphIters;
     UnsignedArray scopeLengths;
     UnsignedArray stateStack;
     StringBuffer curScopeName;

+ 30 - 1
system/jlib/jptree.cpp

@@ -211,6 +211,11 @@ public:
             elems.append(iter.get());
         elems.sort(compare);
     }
+    CPTArrayIterator(IArrayOf<IPropertyTree> & ownedElems, TreeCompareFunc compare) : ArrayIIteratorOf<IArrayOf<IPropertyTree>, IPropertyTree, IPropertyTreeIterator>(elems)
+    {
+        elems.swapWith(ownedElems);
+        elems.sort(compare);
+    }
 };
 IPropertyTreeIterator * createSortedIterator(IPropertyTreeIterator & iter)
 {
@@ -220,6 +225,10 @@ IPropertyTreeIterator * createSortedIterator(IPropertyTreeIterator & iter, TreeC
 {
     return new CPTArrayIterator(iter, compare);
 }
+IPropertyTreeIterator * createSortedIterator(IArrayOf<IPropertyTree> & ownedElems, TreeCompareFunc compare)
+{
+    return new CPTArrayIterator(ownedElems, compare);
+}
 //////////////////
 
 unsigned ChildMap::getHashFromElement(const void *e) const
@@ -1018,8 +1027,10 @@ aindex_t PTree::getChildMatchPos(const char *xpath)
     if (!childIter->first())
         return (aindex_t)-1;
     IPropertyTree &childMatch = childIter->query();
+#ifdef _DEBUG
     if (childIter->next())
         AMBIGUOUS_PATH("addPropX", xpath);
+#endif
 
     if (value)
         if (value->isArray())
@@ -1056,7 +1067,9 @@ void PTree::resolveParentChild(const char *xpath, IPropertyTree *&parent, IPrope
         if (this != &pathIter->query())
         {
             IPropertyTree *currentPath = NULL;
+#ifdef _DEBUG
             bool multiplePaths = false;
+#endif
             bool multipleChildMatches = false;
             for (;;)
             {
@@ -1066,21 +1079,30 @@ void PTree::resolveParentChild(const char *xpath, IPropertyTree *&parent, IPrope
                 if (childIter->first())
                 {
                     child = &childIter->query();
+#ifdef _DEBUG
                     if (parent)
                         AMBIGUOUS_PATH("resolveParentChild", xpath);
+#endif
                     if (!multipleChildMatches && childIter->next())
                         multipleChildMatches = true;
 
                     parent = currentPath;
                 }
                 if (pathIter->next())
+                {
+#ifdef _DEBUG
                     multiplePaths = true;
-                else break;
+#endif
+                }
+                else
+                    break;
             }
             if (!parent)
             {
+#ifdef _DEBUG
                 if (multiplePaths) // i.e. no unique path to child found and multiple parent paths
                     AMBIGUOUS_PATH("resolveParentChild", xpath);
+#endif
                 parent = currentPath;
             }
             if (multipleChildMatches)
@@ -1387,8 +1409,10 @@ bool PTree::renameProp(const char *xpath, const char *newName)
             if (!iter->first())
                 return false;
             IPropertyTree &branch = iter->query();
+#ifdef _DEBUG
             if (iter->next())
                 AMBIGUOUS_PATH("renameProp", xpath);
+#endif
             return branch.renameProp(prop, newName);
         }
         else
@@ -1514,8 +1538,11 @@ IPropertyTree *PTree::queryPropTree(const char *xpath) const
     if (iter->first())
     {
         element = &iter->query();
+#ifdef _DEBUG
+        //The following call can double the cost of finding a match from an IPropertyTree
         if (iter->next())
             AMBIGUOUS_PATH("getProp",xpath);
+#endif
     }
     return element;
 }
@@ -1596,8 +1623,10 @@ bool PTree::isArray(const char *xpath) const
                 if (!iter->first())
                     return false;
                 IPropertyTree &branch = iter->query();
+#ifdef _DEBUG
                 if (iter->next())
                     AMBIGUOUS_PATH("isArray", xpath);
+#endif
                 return branch.isArray(prop);
             }
             else

+ 1 - 0
system/jlib/jptree.hpp

@@ -239,6 +239,7 @@ jlib_decl bool checkParseUrlPathNodeValue(const char *s, StringBuffer &name, Str
 
 typedef int (*TreeCompareFunc)(IInterface * const *ll, IInterface * const *rr);
 jlib_decl IPropertyTreeIterator * createSortedIterator(IPropertyTreeIterator & iter, TreeCompareFunc compare);
+jlib_decl IPropertyTreeIterator * createSortedIterator(IArrayOf<IPropertyTree> & ownedElems, TreeCompareFunc compare);
 
 
 #define XML_SortTags 0x01