/**
 * Uses Sieve of Erastosthenes to generate primes via streams implemented
 * using bounded buffers.
 * 
 * Taken from a sample solution from Kim Bruce's Programming Languages course.
 * Modified and commented by Scot Drysdale
 * @author Unknown
 */

public class Sieve extends Thread {

  private BoundedBuffer in, out;
  private int myprime;

  public Sieve ( BoundedBuffer store ) {
    in = store;
  }

  public void run() {
    int n;
    try {
      // First int seen will be a prime, because it passed all previous filters
      myprime = in.get();  

      if ( myprime < 0 ) {
        return;    // Done with input (base case)
      } else {
        System.out.println(myprime);  // Note each filter prints one prime only!

        out = new BoundedBuffer ( 5 );  

        Sieve s = new Sieve ( out );  // Set up next filter in the chain
        s.start();

        n = in.get();
        while ( n >= 0 ) {
          if ( n % myprime != 0 ) {  // Filter out multiples of myprime
            out.put(n);
          }
          n = in.get();
        }
        out.put(n);  // output the negative to signal end

      }
    } catch (InterruptedException e) {}
  }  


  public static void main ( String[] args ) {

    BoundedBuffer b = new BoundedBuffer(5);
    try { 
      Sieve s = new Sieve(b);
      s.start();

      for ( int i = 2; i <= 100; i++ ) {
        b.put(i);
      }
      b.put(-1);   // Signal that the steam of number is done
    } catch (InterruptedException e) {} 
  }
}
