예제 #1
0
Value Filter::evaluate() const
{
    Value v = m_expr->evaluate();

    NodeSet& nodes = v.modifiableNodeSet();
    nodes.sort();

    EvaluationContext& evaluationContext = Expression::evaluationContext();
    for (unsigned i = 0; i < m_predicates.size(); i++) {
        OwnPtrWillBeRawPtr<NodeSet> newNodes(NodeSet::create());
        evaluationContext.size = nodes.size();
        evaluationContext.position = 0;

        for (unsigned j = 0; j < nodes.size(); j++) {
            Node* node = nodes[j];

            evaluationContext.node = node;
            ++evaluationContext.position;

            if (m_predicates[i]->evaluate())
                newNodes->append(node);
        }
        nodes.swap(*newNodes);
    }

    return v;
}
예제 #2
0
void Step::evaluate(EvaluationContext& evaluationContext, Node* context, NodeSet& nodes) const
{
    evaluationContext.position = 0;

    nodesInAxis(evaluationContext, context, nodes);

    // Check predicates that couldn't be merged into node test.
    for (unsigned i = 0; i < m_predicates.size(); i++) {
        Predicate* predicate = m_predicates[i].get();

        OwnPtrWillBeRawPtr<NodeSet> newNodes(NodeSet::create());
        if (!nodes.isSorted())
            newNodes->markSorted(false);

        for (unsigned j = 0; j < nodes.size(); j++) {
            Node* node = nodes[j];

            evaluationContext.node = node;
            evaluationContext.size = nodes.size();
            evaluationContext.position = j + 1;
            if (predicate->evaluate(evaluationContext))
                newNodes->append(node);
        }

        nodes.swap(*newNodes);
    }
}
예제 #3
0
void LocationPath::evaluate(NodeSet& nodes) const
{
    bool resultIsSorted = nodes.isSorted();

    for (unsigned i = 0; i < m_steps.size(); i++) {
        Step* step = m_steps[i];
        OwnPtrWillBeRawPtr<NodeSet> newNodes(NodeSet::create());
        HashSet<Node*> newNodesSet;

        bool needToCheckForDuplicateNodes = !nodes.subtreesAreDisjoint() || (step->axis() != Step::ChildAxis && step->axis() != Step::SelfAxis
            && step->axis() != Step::DescendantAxis && step->axis() != Step::DescendantOrSelfAxis && step->axis() != Step::AttributeAxis);

        if (needToCheckForDuplicateNodes)
            resultIsSorted = false;

        // This is a simplified check that can be improved to handle more cases.
        if (nodes.subtreesAreDisjoint() && (step->axis() == Step::ChildAxis || step->axis() == Step::SelfAxis))
            newNodes->markSubtreesDisjoint(true);

        for (unsigned j = 0; j < nodes.size(); j++) {
            OwnPtrWillBeRawPtr<NodeSet> matches(NodeSet::create());
            step->evaluate(nodes[j], *matches);

            if (!matches->isSorted())
                resultIsSorted = false;

            for (size_t nodeIndex = 0; nodeIndex < matches->size(); ++nodeIndex) {
                Node* node = (*matches)[nodeIndex];
                if (!needToCheckForDuplicateNodes || newNodesSet.add(node).isNewEntry)
                    newNodes->append(node);
            }
        }

        nodes.swap(*newNodes);
    }

    nodes.markSorted(resultIsSorted);
}
예제 #4
0
  int DA_blockPartStage3(std::vector<TreeNode> &nodes, std::vector<TreeNode>& globalCoarse,
      std::vector<ot::TreeNode>& minsAllBlocks, unsigned int dim,
      unsigned int maxDepth, MPI_Comm commActive) {
#ifdef __PROF_WITH_BARRIER__
    MPI_Barrier(commActive);
#endif
    PROF_BLKPART3_BEGIN

      int npesActive, rankActive;

    MPI_Comm_rank(commActive, &rankActive);
    MPI_Comm_size(commActive, &npesActive);

    int *sendCnt = new int[npesActive];
    int *recvCnt = new int[npesActive];
    int *sendOffsets = new int[npesActive];
    int *recvOffsets = new int[npesActive];

    TreeNode rootNode (dim,maxDepth);

    // Now communicate the nodes ...

    //7. Determine locally which keys to send to which proc ...
    //Compute Dist on globalCoarse....

    TreeNode *sendMin;
    std::vector<ot::TreeNode> vtkDist(npesActive);
    if (!globalCoarse.empty()) {
      sendMin = (TreeNode *)&(*(globalCoarse.begin()));
    } else {
      sendMin = &(rootNode);
    }

    par::Mpi_Allgather<ot::TreeNode>(sendMin, &(* vtkDist.begin()), 1, commActive);

    minsAllBlocks.clear();
    for(int j = 0; j < npesActive; j++) {
      if(vtkDist[j] != rootNode) {
        minsAllBlocks.push_back(vtkDist[j]);
      }
    }//end for j

    for (unsigned int j = 1; j < npesActive ; j++) {
      if (vtkDist[j] == rootNode) {
        vtkDist[j] = vtkDist[j-1];
      }
    }//end for j

    // correct dist ...
    if (npesActive > 1) {
      if (vtkDist[npesActive - 1] == vtkDist[npesActive - 2]) {
        vtkDist[npesActive - 1] = rootNode;
      }//end if

      for (int i = npesActive - 2; i > 0; i--) {
        if (vtkDist[i] == vtkDist[i-1]) {
          vtkDist[i] = vtkDist[i+1];
        }//end if
      }//end for
    }//end if npes > 1

    unsigned int *part = NULL;
    if(!nodes.empty()) {
      part = new unsigned int[nodes.size()];
    }

    if (npesActive > 1) {
      unsigned int pCnt=0;
      for (unsigned int i=0; i< nodes.size(); i++) {
#ifdef __DEBUG_DA__
        assert(pCnt < npesActive);
#endif
        if ( (nodes[i] >= vtkDist[pCnt]) && ( (pCnt == (npesActive - 1)) ||
              ( nodes[i] < vtkDist[pCnt+1] ) || (vtkDist[pCnt+1] == rootNode) ) ) {
          part[i] = pCnt;
        } else {
          while ( (pCnt < (npesActive -1)) && (nodes[i] >= vtkDist[pCnt+1])
              && (vtkDist[pCnt+1] != rootNode)  ) {
            pCnt++;
          }//end while
          part[i] = pCnt;
        }//end if-else
      }//end for i
    }//end if np>1

    vtkDist.clear();
    //_________________________________________________________________________
    // Now the partitions should be contiguous since the two lists are globally
    // sorted ... and it's simply a shift between the two.
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    //compute the total number of nodes being sent to each proc ...
    for (int i = 0; i < npesActive; i++) {
      sendCnt[i]=0;
      recvCnt[i]=0;
    }

    if (npesActive > 1) {
      for (unsigned int i=0; i<nodes.size(); i++) {
#ifdef __DEBUG_DA__
        assert(part[i] < npesActive);
#endif
        sendCnt[part[i]]++;
      }//end for i
    } else {
      sendCnt[0] += (nodes.size());
    }//end if-else

    if(part) {
      delete [] part;
      part = NULL;
    }

    // communicate with other procs how many you shall be sending and get how
    // many to recieve from whom.

    par::Mpi_Alltoall<int>( sendCnt, recvCnt, 1, commActive);

    unsigned int totalRecv = 0;
    for (unsigned int i = 0; i < npesActive; i++) {
      totalRecv += recvCnt[i];
    }//end for i

    sendOffsets[0] = 0;
    recvOffsets[0] = 0;

    // compute offsets ...
    for (int i=1; i < npesActive; i++) {
      sendOffsets[i] = sendOffsets[i-1] + sendCnt[i-1];
      recvOffsets[i] = recvOffsets[i-1] + recvCnt[i-1];
    }//end for i

    // Allocate for new array ...
    std::vector<ot::TreeNode > newNodes(totalRecv);

    // perform All2Allv
    ot::TreeNode* nodesPtr = NULL;
    ot::TreeNode* newNodesPtr = NULL;
    if(!nodes.empty()) {
      nodesPtr = &(*(nodes.begin()));
    }
    if(!newNodes.empty()) {
      newNodesPtr = &(*(newNodes.begin()));
    }
    par::Mpi_Alltoallv_sparse<ot::TreeNode>( nodesPtr, sendCnt, sendOffsets,
        newNodesPtr, recvCnt, recvOffsets, commActive);

    // reset the pointer ...
    nodes = newNodes;

    // clean up ...
    delete [] sendCnt;
    sendCnt = NULL;

    delete [] recvCnt;
    recvCnt = NULL;

    delete [] sendOffsets;
    sendOffsets = NULL;

    delete [] recvOffsets;
    recvOffsets = NULL;

    newNodes.clear();

    PROF_BLKPART3_END
  } // end blockPart