예제 #1
0
 @Override
 public <T> void eval(
     QueryEnvironment<T> env,
     VariableContext<T> context,
     QueryExpression expression,
     List<Argument> args,
     final Callback<T> callback)
     throws QueryException, InterruptedException {
   final AtomicBoolean someFound = new AtomicBoolean(false);
   env.eval(
       args.get(0).getExpression(),
       context,
       new Callback<T>() {
         @Override
         public void process(Iterable<T> partialResult)
             throws QueryException, InterruptedException {
           if (someFound.get() || Iterables.isEmpty(partialResult)) {
             return;
           }
           callback.process(ImmutableSet.of(partialResult.iterator().next()));
           someFound.set(true);
         }
       });
   if (!someFound.get()) {
     throw new QueryException(expression, "argument set is empty");
   }
 }
예제 #2
0
 @Override
 public <T> void eval(QueryEnvironment<T> env, VariableContext<T> context, Callback<T> callback)
     throws QueryException, InterruptedException {
   for (TargetLiteral expr : words) {
     env.eval(expr, context, callback);
   }
 }
예제 #3
0
  /**
   * Compute the transitive closure of the universe, then breadth-first search from the argument
   * towards the universe while staying within the transitive closure.
   */
  @Override
  public <T> Set<T> eval(QueryEnvironment<T> env, QueryExpression expression, List<Argument> args)
      throws QueryException {
    Set<T> universeValue = args.get(0).getExpression().eval(env);
    Set<T> argumentValue = args.get(1).getExpression().eval(env);
    int depthBound = args.size() > 2 ? args.get(2).getInteger() : Integer.MAX_VALUE;

    env.buildTransitiveClosure(expression, universeValue, Integer.MAX_VALUE);

    Set<T> visited = new LinkedHashSet<>();
    Set<T> reachableFromUniverse = env.getTransitiveClosure(universeValue);
    Collection<T> current = argumentValue;

    // We need to iterate depthBound + 1 times.
    for (int i = 0; i <= depthBound; i++) {
      List<T> next = new ArrayList<>();
      for (T node : current) {
        if (!reachableFromUniverse.contains(node)) {
          // Traversed outside the transitive closure of the universe.
          continue;
        }

        if (!visited.add(node)) {
          // Already visited; if we see a node in a later round, then we don't need to visit it
          // again, because the depth at which we see it at must be greater than or equal to the
          // last visit.
          continue;
        }

        next.addAll(env.getReverseDeps(node));
      }
      if (next.isEmpty()) {
        // Exit when there are no more nodes to visit.
        break;
      }
      current = next;
    }

    return visited;
  }