Beispiel #1
0
  /**
   * Algorithm of Tarjan for computing the strongly connected components of a graph.
   *
   * @param v current node
   * @throws QueryException if a variable directly calls itself
   */
  private void tarjan(final int v) throws QueryException {
    final int ixv = 2 * v, llv = ixv + 1, idx = next++;
    while (list.size() <= llv) list.add(-1);
    list.set(ixv, idx);
    list.set(llv, idx);

    stack.push(v);

    for (final int w : adjacentTo(v)) {
      final int ixw = 2 * w, llw = ixw + 1;
      if (list.size() <= ixw || list.get(ixw) < 0) {
        // Successor w has not yet been visited; recurse on it
        tarjan(w);
        list.set(llv, Math.min(list.get(llv), list.get(llw)));
      } else if (stack.contains(w)) {
        // Successor w is in stack S and hence in the current SCC
        list.set(llv, Math.min(list.get(llv), list.get(ixw)));
      }
    }

    // If v is a root node, pop the stack and generate an SCC
    if (list.get(llv) == list.get(ixv)) {
      int w;
      Scope[] out = null;
      do {
        w = stack.pop();
        final Scope scp = scopes.get(w);
        out = out == null ? new Scope[] {scp} : Array.add(out, scp);
      } while (w != v);
      result.add(out);
    }
  }
Beispiel #2
0
  @Override
  public Value value(final QueryContext qc) throws QueryException {
    final FItem getKey = checkArity(exprs[1], 1, qc);
    final long k = Math.min(toLong(exprs[2], qc), Integer.MAX_VALUE);
    if (k < 1) return Empty.SEQ;

    final Iter iter = exprs[0].iter(qc);
    final MinHeap<Item, Item> heap =
        new MinHeap<>(
            new Comparator<Item>() {
              @Override
              public int compare(final Item it1, final Item it2) {
                try {
                  return OpV.LT.eval(it1, it2, sc.collation, sc, info) ? -1 : 1;
                } catch (final QueryException qe) {
                  throw new QueryRTException(qe);
                }
              }
            });

    try {
      for (Item it; (it = iter.next()) != null; ) {
        heap.insert(checkNoEmpty(getKey.invokeItem(qc, info, it)), it);
        if (heap.size() > k) heap.removeMin();
      }
    } catch (final QueryRTException ex) {
      throw ex.getCause();
    }

    final ValueBuilder vb = new ValueBuilder();
    while (!heap.isEmpty()) vb.addFront(heap.removeMin());
    return vb.value();
  }
Beispiel #3
0
 /**
  * Rounds values.
  *
  * @param qc query context
  * @param even half-to-even flag
  * @return number
  * @throws QueryException query exception
  */
 ANum round(final QueryContext qc, final boolean even) throws QueryException {
   final ANum num = toNumber(exprs[0], qc);
   final long p = exprs.length == 1 ? 0 : Math.max(Integer.MIN_VALUE, toLong(exprs[1], qc));
   return num == null ? null : p > Integer.MAX_VALUE ? num : num.round((int) p, even);
 }