/*
 * Small Prime Implementation
 *
 * using trial primes
 * generate all primes p with m <= p < m+k 
 */

import java.rmi.*;
import java.rmi.server.*;

public class SmallPrimeImpl 
       extends UnicastRemoteObject
       implements SmallPrimeInf {

  private boolean p[];
  private int m, k, ms;

  public SmallPrimeImpl() throws RemoteException {
     super();
  }

  public int[] genSmallPrimes(int mpp, int kp) throws RemoteException {

    // from constructor
    ms = mpp;
    if ( ms <= 0 ) { ms = 1; }
    m = ms;
    if ( m % 2 == 0 ) { m++; }
    k = kp/2; 
//    System.out.println("m=" + m + " kp=" + kp+ " k=" + k);
    p = new boolean[k];

    // generator
    /* init */
    int h = 2*(k-1); 
    int mp = m + h;    
    for (int i=0; i<k; i++) { p[i] = true; }

//    System.out.println("h=" + h + " mp=" + mp+ " k=" + k);

    /* compute */
    int q, r, i;
    int c = 0, d = 0; 

    while (true) { 
      switch (c) {
           /* mark multiples of d for d=3 and d=6n-/+1 with d**2<=mp */
         case 2: d += 2; c = 3; break;
         case 3: d += 4; c = 2; break;
         case 0: d = 3; c = 1; break;
         case 1: d = 5; c = 2; break;
      }
      if ( d > (mp/d) ) { break; }

      r = m % d; 
      if ( r+h >= d || r == 0 ) {
         if ( r == 0 ) { i = 0; }
            else {
            if ( r % 2 == 0 ) { i = d-r/2; } else { i = (d-r)/2; }
         }
         if ( m < d ) { i += d; }
         while ( i < k ) { p[i] = false; i += d; }
      }
    }

    /* output */
    int l=0;
    for (i=0; i<k; i++) { if (p[i] == true) { l++;} }
    if (ms == 2) { l++; }
    int[] po = new int[l];
    if (l == 0) { return po; }

    int pl=m; l=0;
    if (ms == 2) { po[l] = 2; l++; }
    for (i=0; i<k; i++) { 
        if (p[i] == true) { po[l] = pl; l++; } 
        pl += 2; }
    if (ms == 1) { po[0] = 2; }

    return po;
  }

}
