Linear implementation of Tarjan's algorithm
Remi Forax
forax at univ-mlv.fr
Sun Oct 22 18:06:03 UTC 2017
Please do not add a new class just for that, for a code as simple as this one, you can inline every methods.
Also, i think the compiler will create 8 methods for your class HashStack, you should declare the class and all the method package private (or wait for the compiler using the 18.3 as bootstrap JDK).
regards,
Rémi
----- Mail original -----
> De: "B. Blaser" <bsrbnd at gmail.com>
> À: "compiler-dev" <compiler-dev at openjdk.java.net>
> Envoyé: Dimanche 22 Octobre 2017 19:36:12
> Objet: Linear implementation of Tarjan's algorithm
> Hi,
>
> As briefly mentioned in [1], the current implementation of Tarjan's
> algorithm performs a linear scan of the stack while iterating on the
> node dependencies which might be avoided...
>
> Next is an attempt to make the whole implementation more linear using
> a 'HashStack' that provides all operations in constant time,
> especially 'contains()'.
>
> What do you think?
>
> Thanks,
> Bernard
>
>
> [1] http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011226.html
>
>
> diff --git
> a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java
> b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java
> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java
> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java
> @@ -28,6 +28,7 @@
> import java.util.ArrayList;
> import java.util.Collection;
> import java.util.Properties;
> +import java.util.HashSet;
>
> /** <p><b>This is NOT part of any supported API.
> * If you write code that depends on this, you do so at your own risk.
> @@ -164,7 +165,28 @@
> ListBuffer<List<N>> sccs = new ListBuffer<>();
>
> /** Stack of all reacheable nodes from given root. */
> - ListBuffer<N> stack = new ListBuffer<>();
> + HashStack<N> stack = new HashStack<>();
> + //where
> + private static class HashStack<N> {
> + HashSet<N> set = new HashSet<>();
> + List<N> stack = List.nil();
> +
> + private void push(N n) {
> + set.add(n);
> + stack = stack.prepend(n);
> + }
> +
> + private N pop() {
> + N n = stack.head;
> + set.remove(n);
> + stack = stack.tail;
> + return n;
> + }
> +
> + private boolean contains(N n) {
> + return set.contains(n);
> + }
> + }
>
> private List<? extends List<? extends N>> findSCC(Iterable<?
> extends N> nodes) {
> for (N node : nodes) {
> @@ -197,7 +219,7 @@
> n.index = index;
> n.lowlink = index;
> index++;
> - stack.prepend(n);
> + stack.push(n);
> n.active = true;
> }
>
> @@ -205,7 +227,7 @@
> N n;
> ListBuffer<N> cycle = new ListBuffer<>();
> do {
> - n = stack.remove();
> + n = stack.pop();
> n.active = false;
> cycle.add(n);
> } while (n != v);
More information about the compiler-dev
mailing list