Use sets of members in CFXA_Node node shuffling code.

This is not essential for the first versions of cppgc, since we
are not GCing while the stack is still active.

-- avoid some indirection while at it.

Change-Id: I1bacdb3b21d6cd9a5bbc5b3f19666d8b22594a3c
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/73851
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index 212d7b0..c675844 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -546,12 +546,19 @@
   return true;
 }
 
-std::vector<CXFA_Node*> NodesSortedByDocumentIdx(
-    const std::set<CXFA_Node*>& rgNodeSet) {
-  if (rgNodeSet.empty())
-    return std::vector<CXFA_Node*>();
+// Stack allocated. Using containers of members would be correct here
+// if advanced GC worked with STL.
+using NodeSet = std::set<cppgc::Member<CXFA_Node>>;
+using NodeSetPair = std::pair<NodeSet, NodeSet>;
+using NodeSetPairMap = std::map<uint32_t, NodeSetPair>;
+using NodeSetPairMapMap = std::map<CXFA_Node*, NodeSetPairMap>;
+using NodeVector = std::vector<cppgc::Member<CXFA_Node>>;
 
-  std::vector<CXFA_Node*> rgNodeArray;
+NodeVector NodesSortedByDocumentIdx(const NodeSet& rgNodeSet) {
+  if (rgNodeSet.empty())
+    return NodeVector();
+
+  NodeVector rgNodeArray;
   CXFA_Node* pCommonParent = (*rgNodeSet.begin())->GetParent();
   for (CXFA_Node* pNode = pCommonParent->GetFirstChild(); pNode;
        pNode = pNode->GetNextSibling()) {
@@ -561,40 +568,26 @@
   return rgNodeArray;
 }
 
-using CXFA_NodeSetPair = std::pair<std::set<CXFA_Node*>, std::set<CXFA_Node*>>;
-using CXFA_NodeSetPairMap =
-    std::map<uint32_t, std::unique_ptr<CXFA_NodeSetPair>>;
-using CXFA_NodeSetPairMapMap =
-    std::map<CXFA_Node*, std::unique_ptr<CXFA_NodeSetPairMap>>;
-
-CXFA_NodeSetPair* NodeSetPairForNode(CXFA_Node* pNode,
-                                     CXFA_NodeSetPairMapMap* pMap) {
+NodeSetPair* NodeSetPairForNode(CXFA_Node* pNode, NodeSetPairMapMap* pMap) {
   CXFA_Node* pParentNode = pNode->GetParent();
   uint32_t dwNameHash = pNode->GetNameHash();
   if (!pParentNode || !dwNameHash)
     return nullptr;
 
-  if (!(*pMap)[pParentNode])
-    (*pMap)[pParentNode] = std::make_unique<CXFA_NodeSetPairMap>();
-
-  CXFA_NodeSetPairMap* pNodeSetPairMap = (*pMap)[pParentNode].get();
-  if (!(*pNodeSetPairMap)[dwNameHash])
-    (*pNodeSetPairMap)[dwNameHash] = std::make_unique<CXFA_NodeSetPair>();
-
-  return (*pNodeSetPairMap)[dwNameHash].get();
+  return &((*pMap)[pParentNode][dwNameHash]);
 }
 
-void ReorderDataNodes(const std::set<CXFA_Node*>& sSet1,
-                      const std::set<CXFA_Node*>& sSet2,
+void ReorderDataNodes(const NodeSet& sSet1,
+                      const NodeSet& sSet2,
                       bool bInsertBefore) {
-  CXFA_NodeSetPairMapMap rgMap;
+  NodeSetPairMapMap rgMap;
   for (CXFA_Node* pNode : sSet1) {
-    CXFA_NodeSetPair* pNodeSetPair = NodeSetPairForNode(pNode, &rgMap);
+    NodeSetPair* pNodeSetPair = NodeSetPairForNode(pNode, &rgMap);
     if (pNodeSetPair)
       pNodeSetPair->first.insert(pNode);
   }
   for (CXFA_Node* pNode : sSet2) {
-    CXFA_NodeSetPair* pNodeSetPair = NodeSetPairForNode(pNode, &rgMap);
+    NodeSetPair* pNodeSetPair = NodeSetPairForNode(pNode, &rgMap);
     if (pNodeSetPair) {
       if (pdfium::Contains(pNodeSetPair->first, pNode))
         pNodeSetPair->first.erase(pNode);
@@ -602,19 +595,13 @@
         pNodeSetPair->second.insert(pNode);
     }
   }
-  for (const auto& iter1 : rgMap) {
-    CXFA_NodeSetPairMap* pNodeSetPairMap = iter1.second.get();
-    if (!pNodeSetPairMap)
-      continue;
-
-    for (const auto& iter2 : *pNodeSetPairMap) {
-      CXFA_NodeSetPair* pNodeSetPair = iter2.second.get();
-      if (!pNodeSetPair)
-        continue;
+  for (auto& iter1 : rgMap) {
+    NodeSetPairMap* pNodeSetPairMap = &iter1.second;
+    for (auto& iter2 : *pNodeSetPairMap) {
+      NodeSetPair* pNodeSetPair = &iter2.second;
       if (!pNodeSetPair->first.empty() && !pNodeSetPair->second.empty()) {
-        std::vector<CXFA_Node*> rgNodeArray1 =
-            NodesSortedByDocumentIdx(pNodeSetPair->first);
-        std::vector<CXFA_Node*> rgNodeArray2 =
+        NodeVector rgNodeArray1 = NodesSortedByDocumentIdx(pNodeSetPair->first);
+        NodeVector rgNodeArray2 =
             NodesSortedByDocumentIdx(pNodeSetPair->second);
         CXFA_Node* pParentNode = nullptr;
         CXFA_Node* pBeforeNode = nullptr;
@@ -626,7 +613,7 @@
           pParentNode = pLastNode->GetParent();
           pBeforeNode = pLastNode->GetNextSibling();
         }
-        for (auto* pCurNode : rgNodeArray1) {
+        for (auto& pCurNode : rgNodeArray1) {
           pParentNode->RemoveChildAndNotify(pCurNode, true);
           pParentNode->InsertChildAndNotify(pCurNode, pBeforeNode);
         }
@@ -1926,29 +1913,25 @@
         iCount > 0 ? item->GetNextSibling() : GetNextSibling();
     GetParent()->InsertChildAndNotify(pNewInstance, pNextSibling);
     if (bMoveDataBindingNodes) {
-      std::set<CXFA_Node*> sNew;
-      std::set<CXFA_Node*> sAfter;
+      NodeSet sNew;
       CXFA_NodeIteratorTemplate<CXFA_Node,
                                 CXFA_TraverseStrategy_XFAContainerNode>
           sIteratorNew(pNewInstance);
       for (CXFA_Node* pNode = sIteratorNew.GetCurrent(); pNode;
            pNode = sIteratorNew.MoveToNext()) {
         CXFA_Node* pDataNode = pNode->GetBindData();
-        if (!pDataNode)
-          continue;
-
-        sNew.insert(pDataNode);
+        if (pDataNode)
+          sNew.insert(pDataNode);
       }
+      NodeSet sAfter;
       CXFA_NodeIteratorTemplate<CXFA_Node,
                                 CXFA_TraverseStrategy_XFAContainerNode>
           sIteratorAfter(pNextSibling);
       for (CXFA_Node* pNode = sIteratorAfter.GetCurrent(); pNode;
            pNode = sIteratorAfter.MoveToNext()) {
         CXFA_Node* pDataNode = pNode->GetBindData();
-        if (!pDataNode)
-          continue;
-
-        sAfter.insert(pDataNode);
+        if (pDataNode)
+          sAfter.insert(pDataNode);
       }
       ReorderDataNodes(sNew, sAfter, false);
     }
@@ -1961,29 +1944,25 @@
 
     GetParent()->InsertChildAndNotify(pNewInstance, pBeforeInstance);
     if (bMoveDataBindingNodes) {
-      std::set<CXFA_Node*> sNew;
-      std::set<CXFA_Node*> sBefore;
+      NodeSet sNew;
       CXFA_NodeIteratorTemplate<CXFA_Node,
                                 CXFA_TraverseStrategy_XFAContainerNode>
           sIteratorNew(pNewInstance);
       for (CXFA_Node* pNode = sIteratorNew.GetCurrent(); pNode;
            pNode = sIteratorNew.MoveToNext()) {
         CXFA_Node* pDataNode = pNode->GetBindData();
-        if (!pDataNode)
-          continue;
-
-        sNew.insert(pDataNode);
+        if (pDataNode)
+          sNew.insert(pDataNode);
       }
+      NodeSet sBefore;
       CXFA_NodeIteratorTemplate<CXFA_Node,
                                 CXFA_TraverseStrategy_XFAContainerNode>
           sIteratorBefore(pBeforeInstance);
       for (CXFA_Node* pNode = sIteratorBefore.GetCurrent(); pNode;
            pNode = sIteratorBefore.MoveToNext()) {
         CXFA_Node* pDataNode = pNode->GetBindData();
-        if (!pDataNode)
-          continue;
-
-        sBefore.insert(pDataNode);
+        if (pDataNode)
+          sBefore.insert(pDataNode);
       }
       ReorderDataNodes(sNew, sBefore, true);
     }