Пример #1
0
  /**
   * Returns true if the constraint is associated with the given FromElement.
   *
   * @param constraint the constraint in question
   * @param fromElement the FromElement to check
   * @return true if associated
   */
  public static boolean isRelatedTo(Constraint constraint, FromElement fromElement) {
    if (isAssociatedWith(constraint, fromElement)) {
      return true;
    }

    // also want to find out if this is referred to in a Contains or Subquery
    // constraint that is associated with another fromElement.

    if (constraint instanceof ContainsConstraint) {
      if (fromElement == ((ContainsConstraint) constraint).getQueryClass()) {
        return true;
      }
    } else if (constraint instanceof SubqueryConstraint) {
      if (fromElement == ((SubqueryConstraint) constraint).getQuery()) {
        return true;
      }
    } else if (constraint instanceof SimpleConstraint) {
      SimpleConstraint sc = (SimpleConstraint) constraint;
      Set<QueryField> qFields = getQueryFields(sc.getArg1());
      qFields.addAll(getQueryFields(sc.getArg2()));
      for (QueryField qf : qFields) {
        if (fromElement == qf.getFromElement()) {
          return true;
        }
      }
    }
    return false;
  }
Пример #2
0
 /**
  * Returns true if the given constraint is related to no FromElement. This should only return true
  * if c is a SimpleConstraint that only references constants.
  *
  * @param c the constraint to examine
  * @return true if constraint is not associated with a FromElement
  */
 public static boolean isRelatedToNothing(Constraint c) {
   if (c instanceof SimpleConstraint) {
     SimpleConstraint sc = (SimpleConstraint) c;
     Set<QueryField> fields = getQueryFields(sc.getArg1());
     fields.addAll(getQueryFields(sc.getArg2()));
     if (fields.size() == 0) {
       return true;
     }
   }
   return false;
 }
Пример #3
0
  @Override
  public String toString() {

    StringBuilder sb = new StringBuilder();
    sb.append('[').append('\n');

    for (BaseConstraint bc : getBaseConstraints()) {
      sb.append('{').append(bc.getSubVar()).append("} \u2286 ");
      sb.append(bc.getSuperVar()).append('\n');
    }

    for (SimpleConstraint bc : getSimpleConstraints()) {
      sb.append(bc.getSubVar()).append(" \u2286 ");
      sb.append(bc.getSuperVar()).append('\n');
    }

    for (ComplexConstraint bc : getComplexConstraints()) {
      sb.append(bc.getSubVar()).append(" \u2286 ");
      sb.append(bc.getSuperVar()).append('\n');
    }

    int size =
        getBaseConstraints().size()
            + getSimpleConstraints().size()
            + getComplexConstraints().size();

    sb.append("] size->  ").append(size);

    // points-to sets
    sb.append('\n');
    sb.append('[').append('\n');

    Map<String, String[]> ptSet = getPointsToSets();
    for (String key : ptSet.keySet()) {

      sb.append(key).append(" -> {");
      String[] vals = ptSet.get(key);

      for (String val : vals) {
        sb.append(val).append(',');
      }

      if (vals.length > 0) {
        sb.setLength(sb.length() - 1);
      }

      sb.append('}').append('\n');
    }

    sb.append(']').append('\n');

    return sb.toString();
  }
Пример #4
0
  /**
   * Constructs the online graph for the analysis. Additionally an offline graph for HCD is
   * constructed to speed up the computation of the dynamic transitive closure with it.
   *
   * @param bConstr List of all {@link BaseConstraint}s that should be considered.<br>
   *     A {@link BaseConstraint} leads to an entry in a nodes points-to set.
   * @param sConstr List of all {@link SimpleConstraint}s that should be considered.<br>
   *     A {@link SimpleConstraint} represents an edge in the graph.
   * @param cConstr List of all {@link ComplexConstraint}s that should be considered.<br>
   *     {@link ComplexConstraint}s are stored in nodes, so they can be accessed faster when
   *     computing the dynamic transitive closure.
   * @param g The resulting graph. Should be empty.
   */
  private static void buildGraph(
      Set<BaseConstraint> bConstr,
      Set<SimpleConstraint> sConstr,
      Set<ComplexConstraint> cConstr,
      DirectedGraph g) {

    // HCD offline - build offline graph
    List<List<String>> sccs = buildOfflineGraphAndFindSCCs(sConstr, cConstr);

    // build online graph
    for (BaseConstraint bc : bConstr) {

      DirectedGraph.Node n = g.getNode(bc.getSuperVar());
      n.addPointerTarget(bc.getSubVar());
    }

    for (SimpleConstraint sc : sConstr) {

      DirectedGraph.Node src = g.getNode(sc.getSubVar());
      DirectedGraph.Node dest = g.getNode(sc.getSuperVar());
      g.addEdge(src, dest);
    }

    for (ComplexConstraint cc : cConstr) {

      DirectedGraph.Node n;

      if (cc.isSubDerefed()) {

        n = g.getNode(cc.getSubVar());
        n.complexConstrMeSub.add(cc.getSuperVar());

      } else {

        n = g.getNode(cc.getSuperVar());
        n.complexConstrMeSuper.add(cc.getSubVar());
      }
    }

    // for HCD
    mergeOrMarkSCCs(g, sccs); // ... in online graph
  }
Пример #5
0
  /**
   * Builds an offline graph for HCD and finds all SCCs in it.<br>
   * For the offline version {@link BaseConstraint}s are not relevant and {@link SimpleConstraint}s
   * and {@link ComplexConstraint}s represents an edge in graph.
   *
   * @param sConstr List of all {@link SimpleConstraint}s that should be considered.
   * @param cConstr List of all {@link ComplexConstraint}s that should be considered.
   * @return a list of all SCCs. One SCC is represented as a list of all variables it contains.
   */
  private static List<List<String>> buildOfflineGraphAndFindSCCs(
      Collection<SimpleConstraint> sConstr, Collection<ComplexConstraint> cConstr) {

    HashSet<DirectedGraph.Node> workset = new HashSet<>();
    DirectedGraph g = new DirectedGraph();

    HashMap<DirectedGraph.Node, String> nodeStrMap = new HashMap<>();

    for (SimpleConstraint sc : sConstr) {

      String srcStr = sc.getSubVar();
      String destStr = sc.getSuperVar();

      DirectedGraph.Node src = g.getNode(srcStr);
      DirectedGraph.Node dest = g.getNode(destStr);
      g.addEdge(src, dest);

      workset.add(src);
      workset.add(dest);

      nodeStrMap.put(src, srcStr);
      nodeStrMap.put(dest, destStr);
    }

    for (ComplexConstraint cc : cConstr) {

      String srcStr, destStr;

      if (cc.isSubDerefed()) {

        srcStr = '*' + cc.getSubVar();
        destStr = cc.getSuperVar();

      } else {

        srcStr = cc.getSubVar();
        destStr = '*' + cc.getSuperVar();
      }

      DirectedGraph.Node src = g.getNode(srcStr);
      DirectedGraph.Node dest = g.getNode(destStr);
      g.addEdge(src, dest);

      workset.add(src);
      workset.add(dest);

      nodeStrMap.put(src, srcStr);
      nodeStrMap.put(dest, destStr);
    }

    // find strongly-connected components (using tarjans linear algorithm)
    int maxdfs = 1;
    LinkedList<DirectedGraph.Node> stack = new LinkedList<>();
    List<List<String>> sccs = new LinkedList<>();
    while (!workset.isEmpty()) {

      DirectedGraph.Node n = workset.iterator().next();

      maxdfs = tarjan(maxdfs, n, workset, stack, nodeStrMap, sccs);
    }

    return sccs;
  }