
import jdbm.RecordManager;
import jdbm.RecordManagerFactory;
import jdbm.RecordManagerOptions;

import jdbm.btree.BTree;

import jdbm.helper.LongComparator;
import jdbm.helper.Tuple;
import jdbm.helper.TupleBrowser;

import java.util.Properties;
import java.util.Random;
import java.io.IOException;

/**
 * Example program dealing with B+Trees and Prime numbers.
 */
public class Primes
{

    /**
     * Default number of prime number to populate in the database (if not specified on command-line)
     */
    public static int DEFAULT_POPULATE = 100;


    /**
     * Default number of random lookups (if not specified on command-line)
     */
    public static int DEFAULT_LOOKUPS = 100;

    
    /**
     * Record Manager used for persistence.
     */
    private RecordManager _recman;

    
    /**
     * B+Tree holding prime numbers.
     */
    private BTree _primes;
    
    
    /**
     * Random number generator.
     */
    private static Random  _random = new Random();


    /**
     * Main constructor
     */
    public Primes( String[] args ) 
        throws IOException 
    {
        long        recid;
        Properties  props;
        
        // open database and setup an object cache
        props = new Properties();
        props.put( RecordManagerOptions.CACHE_SIZE, "10000" );
        _recman = RecordManagerFactory.createRecordManager( "primes", props );

        recid = _recman.getNamedObject( "primes" );
        if ( recid == 0 ) {
            System.out.println( "Creating a new primes B+Tree." );
            _primes = BTree.createInstance( _recman, new LongComparator() );
            _recman.setNamedObject( "primes", _primes.getRecid() );
        } else {
            _primes = BTree.load( _recman, recid );
            System.out.println( "B+Tree already contains " + _primes.size() + " primes." );
        }
        _recman.commit();
    }

    
    /**
     * Get the largest prime number in the database.
     */
    public Long getLargestPrime()
        throws IOException
     {
        Tuple         tuple;
        TupleBrowser  browser;
        Long          largest = null;

        tuple = new Tuple();
        browser = _primes.browse( null );
        if ( browser.getPrevious( tuple ) ) {
            largest = (Long) tuple.getValue();
            System.out.println( "Largest prime: " + largest );
        } else {
            System.out.println( "No prime number in the database." );
        }
        return largest;
    }

    
    /**
     * Populate the database with more prime numbers.
     *
     * @param count Number of primes to add to database.
     */
    void populate( int count ) 
        throws IOException 
    {
        Long current;
        Long largest;

        System.out.println( "Populating prime B+Tree..." );
        
        // start after the largest known prime
        largest = getLargestPrime();
        if ( largest == null ) {
            largest = new Long( 0 );
        }

        current = new Long( largest.longValue() + 1L ); 
        while ( count > 0 ) {
            if ( isPrime( current ) ) {
                _primes.insert( current, current, false );
                System.out.println( "Found prime #" + _primes.size() + ": " + current );
                count--;
            }
            current = new Long( current.longValue() + 1 );
        }
        _recman.commit();
    }

    
    /**
     * Returns true if a number is prime.
     */
    boolean isPrime( Long number )
        throws IOException
    {
        Tuple         tuple;
        TupleBrowser  browser;
        Long          largest;
        Long          current;

        if ( number.longValue() <= 0L ) {
            throw new IllegalArgumentException( "Number must be greater than zero" );
        }
        if ( number.longValue() == 1 ) {
            return true;
        }
        tuple = new Tuple();
        browser = _primes.browse();
        while ( browser.getNext( tuple ) ) {
            current = (Long) tuple.getValue();
            if ( current.longValue() != 1 && ( number.longValue() % current.longValue() ) == 0 ) {
                // not a prime because it is divisibe by a prime
                return false;
            }
        }           
        // this is a prime
        return true;
    }

        
    /**
     * Display a number of random prime numbers.
     */
    void random( int count ) 
        throws IOException
    {
        Tuple         tuple;
        TupleBrowser  browser;
        Long          largest;
        Long          number;

        tuple = new Tuple();
        largest = getLargestPrime();

        System.out.println( "Looking up " + count + " random primes...." );
        long start = System.currentTimeMillis();
        for ( int i=0; i<count; i++ ) {
            number = new Long( random( 0, largest.longValue() ) );
            browser = _primes.browse( number );
            if ( browser.getNext( tuple ) ) {
                number = (Long) tuple.getValue();
                System.out.print( number );
                System.out.print( ", " );
            }
        }
        long stop = System.currentTimeMillis();
        System.out.println();
        System.out.println( "Time: " + (stop-start)/count + " millis/lookup " );
    }


    /**
     * Return true if number is a prime.
     */
    public static boolean isPrimeCompute( long number )
    {
        for ( int i=2; i<number/2; i++ ) {
            if ( ( number % i ) == 0 ) {
                return false;
            }
        }
        return true;
    }


    /**
     * Get random number between "low" and "high" (inclusively)
     */
    public static long random( long low, long high )
    {
        return ( (long) ( _random.nextDouble() * (high-low) ) + low );
    }


    /**
     * Static program entrypoint.
     */
    public static void main( String[] args )
    {
        Primes  primes;
        int     count;
        Long    number;
        Long    largest;
            
        try {
            primes = new Primes( args );
            
            for ( int i=0; i<args.length; i++ ) {
                if ( args[i].equalsIgnoreCase( "-populate" ) ) {
                    if ( ++i < args.length ) {
                        count = Integer.parseInt( args[i] );
                    } else {
                        count = DEFAULT_POPULATE;
                    }
                    primes.populate( count );
                } else if ( args[i].equalsIgnoreCase( "-check" ) ) {
                    if ( ++i < args.length ) {
                        number = new Long( Long.parseLong( args[i] ) );
                    } else {
                        number = new Long( _random.nextLong() );
                    }
                    largest = primes.getLargestPrime();
                    if ( number.longValue() > primes.getLargestPrime().longValue() ) {
                        throw new IllegalArgumentException( "Number is larger than largest known prime in database." );
                    }
                    if ( primes.isPrime( number ) ) {
                        System.out.println( "The number " + number + " is a prime." );
                    } else {
                        System.out.println( "The number " + number + " is not a prime." );
                    }
                } else if ( args[i].equalsIgnoreCase( "-random" ) ) {
                    if ( ++i < args.length ) {
                        count = Integer.parseInt( args[i] );
                    } else {
                        count = DEFAULT_LOOKUPS;
                    }
                    primes.random( count );
                }
            }
            if ( args.length == 0 ) {
                System.out.println( "Usage:   java Prime [action] [args]" );
                System.out.println( "" );
                System.out.println( "Actions:" );
                System.out.println( "           -populate [number]   Populate database with prime numbers" );
                System.out.println( "           -check [number]      Check if a number is a prime" );
                System.out.println( "           -random [number]     Display random prime numbers" );
                System.out.println( "" );
            }
        } catch ( IOException except ) {
            except.printStackTrace();
        }
    }
}
