package simpledb.test;

import java.util.*;
import java.io.*;
import simpledb.*;

public class Benchmark extends Test {
    private static final int OUTER_COLS=115;
    private static final int INNER_COLS=2;
    
    public boolean runTest(String args[]) {
        int tupleCount = 0;
        
        TransactionId tid = new TransactionId();
        Query q;
        Type typeAr1[] = new Type[OUTER_COLS];
        for (int i = 0; i < OUTER_COLS; i++) {
            typeAr1[i] = Type.INT_TYPE;
        }
        TupleDesc td1 = new TupleDesc(typeAr1);
        Type typeAr2[] = new Type[INNER_COLS];
        for (int i = 0; i < INNER_COLS; i++) {
            typeAr2[i] = Type.INT_TYPE;
        }
        TupleDesc td2 = new TupleDesc(typeAr2);
    

        if (args[1].equals("seq")) {
            System.out.println("Running NL join");
            HeapFile table1 = new HeapFile(new File(args[2]));
            Database.getCatalog().addTable(table1, td1);
            HeapFile table2 = new HeapFile(new File(args[3]));
            Database.getCatalog().addTable(table2, td2);
            
            SeqScan ss1 = new SeqScan(tid, table1.id());
            SeqScan ss2 = new SeqScan(tid, table2.id());
            JoinPredicate p = new JoinPredicate(Integer.parseInt(args[4]),
                                                Predicate.Op.getOp(args[5]),
                                                Integer.parseInt(args[6]));
            Join j = new Join(p, ss1, ss2);

            q = new Query(j, tid);
        } else {
            System.out.println("Running Index NL join");
            HeapFile table1 = new HeapFile(new File(args[2]));
            Database.getCatalog().addTable(table1, td1);
            ExHashFile table2 = new ExHashFile(new File(args[3]), 0);
            Database.getCatalog().addTable(table2, td2);

            SeqScan ss1 = new SeqScan(tid, table1.id());
            IndexPredicate ipred = null;
            HashScan hs2 = new HashScan(tid, table2.id(), ipred);
            INLJoin j = new INLJoin(ss1, Integer.parseInt(args[4]), hs2);

            q = new Query(j, tid);
        }

        long startTime = System.currentTimeMillis();
        // print out the joined table
        try {
            q.start();

            try {
                while (true) {
                    Tuple tup = q.getNext();
                    tupleCount++;
                }
            } catch(NoSuchElementException e) {
                q.close();
            }
        } catch (TransactionAbortedException te) {
            te.printStackTrace();
            return false;

        } catch (DbException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

        // XXX hack for testing purposes
        try {
            Database.getBufferPool().flushAllPages();
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("Tuples: " + tupleCount);
        long endTime = System.currentTimeMillis();

        Database.getBufferPool().dumpStats();

        System.out.println("Elapsed wall-clock time: " +
                           (endTime - startTime));
        return true;
    }
}
