jdbc-protolib/src/main/java/com/streamsets/pipeline/lib/jdbc/multithread/util/TopologicalSorter.java
public SortedSet<V> sort() {
    Utils.checkState(!new CycleDetector<>(directedGraph).isGraphCyclic(), "Cycles found in the graph");
    final Map<V, Integer> vertexToSortedNumber = new HashMap<>();
    Map<V, Integer> inEdgesCount = new TreeMap<>();

    SortedSet<V> sortedSet = new TreeSet<>((o1, o2) -> {
      Integer sortedNumber1 = vertexToSortedNumber.get(o1);
      Integer sortedNumber2 = vertexToSortedNumber.get(o2);
      if (sortedNumber1.intValue() == sortedNumber2.intValue()) {
        //If there is no tie comparator and there is a tie, arrange o1 before o2.
        return (tieComparator != null)? tieComparator.compare(o1, o2) : -1;
      }
      return sortedNumber1.compareTo(sortedNumber2);
    });

    final AtomicInteger startNumber = new AtomicInteger(1);

    directedGraph.vertices().forEach(vertex -> {
      Collection<V> inwardVertices = directedGraph.getInwardEdgeVertices(vertex);
      inEdgesCount.put(vertex, inwardVertices.size());
    });

    while (!inEdgesCount.isEmpty()) {
      Set<V> nextVertices = nextVerticesForProcessing(inEdgesCount);
      nextVertices.forEach(vertexForProcessing -> {
        inEdgesCount.remove(vertexForProcessing);
        updateCounts(vertexForProcessing, inEdgesCount);
        vertexToSortedNumber.put(vertexForProcessing, startNumber.getAndIncrement());
      });
    }
    sortedSet.addAll(vertexToSortedNumber.keySet());
    return sortedSet;
  }
public SortedSet<V> sort() {
    Utils.checkState(!new CycleDetector<>(directedGraph).isGraphCyclic(), "Cycles found in the graph");
    final Map<V, Integer> vertexToSortedNumber = new HashMap<>();
    Map<V, Integer> inEdgesCount = new TreeMap<>();

    SortedSet<V> sortedSet = new TreeSet<>((o1, o2) -> {
      Integer sortedNumber1 = vertexToSortedNumber.get(o1);
      Integer sortedNumber2 = vertexToSortedNumber.get(o2);
      if (sortedNumber1.intValue() == sortedNumber2.intValue()) {
        //If there is no tie comparator and there is a tie, arrange o1 before o2.
        return (tieComparator != null)? tieComparator.compare(o1, o2) : -1;
      }
      return sortedNumber1.compareTo(sortedNumber2);
    });

    final AtomicInteger startNumber = new AtomicInteger(1);

    directedGraph.vertices().forEach(vertex -> {
      Collection<V> inwardVertices = directedGraph.getInwardEdgeVertices(vertex);
      inEdgesCount.put(vertex, inwardVertices.size());
    });

    while (!inEdgesCount.isEmpty()) {
      Set<V> nextVertices = nextVerticesForProcessing(inEdgesCount);
      nextVertices.forEach(vertexForProcessing -> {
        inEdgesCount.remove(vertexForProcessing);
        updateCounts(vertexForProcessing, inEdgesCount);
        vertexToSortedNumber.put(vertexForProcessing, startNumber.getAndIncrement());
      });
    }
    sortedSet.addAll(vertexToSortedNumber.keySet());
    return sortedSet;
  }
public SortedSet < V > sort ( ) { Utils . checkState ( ! new CycleDetector <> ( directedGraph ) . isGraphCyclic ( ) , "Cycles found in the graph" ) ; final Map < V , Integer > vertexToSortedNumber = new HashMap <> ( ) ; Map < V , Integer > inEdgesCount = new TreeMap <> ( ) ; SortedSet < V > sortedSet = new TreeSet <> ( ( o1 , o2 ) -> { Integer sortedNumber1 = vertexToSortedNumber . get ( o1 ) ; Integer sortedNumber2 = vertexToSortedNumber . get ( o2 ) ; if ( sortedNumber1 . intValue ( ) == sortedNumber2 . intValue ( ) ) { //If there is no tie comparator and there is a tie, arrange o1 before o2. return ( tieComparator != null ) ? tieComparator . compare ( o1 , o2 ) : - 1 ; } return sortedNumber1 . compareTo ( sortedNumber2 ) ; } ) ; final AtomicInteger startNumber = new AtomicInteger ( 1 ) ; directedGraph . vertices ( ) . forEach ( vertex -> { Collection < V > inwardVertices = directedGraph . getInwardEdgeVertices ( vertex ) ; inEdgesCount . put ( vertex , inwardVertices . size ( ) ) ; } ) ; while ( ! inEdgesCount . isEmpty ( ) ) { Set < V > nextVertices = nextVerticesForProcessing ( inEdgesCount ) ; nextVertices . forEach ( vertexForProcessing -> { inEdgesCount . remove ( vertexForProcessing ) ; updateCounts ( vertexForProcessing , inEdgesCount ) ; vertexToSortedNumber . put ( vertexForProcessing , startNumber . getAndIncrement ( ) ) ; } ) ; } sortedSet . addAll ( vertexToSortedNumber . keySet ( ) ) ; return sortedSet ; }
Sorts the vertices in the topological order using {@link #tieComparator} if needed to break ties.
Throws {@link IllegalStateException} if there is a cycle detected.

@return Topological sorted order for the @{@link DirectedGraph}
Sorts the vertices in the topological order using { @link #tieComparator } if needed to break ties . Throws { @link IllegalStateException } if there is a cycle detected .