@SuppressWarnings("unchecked") public static void main(String[] args) { String dbname; Properties props = new Properties(); Properties fileprops = new Properties(); boolean dotransactions = true; int threadcount = 1; int target = 0; boolean status = false; String label = ""; // parse arguments int argindex = 0; if (args.length == 0) { usageMessage(); System.exit(0); } while (args[argindex].startsWith("-")) { if (args[argindex].compareTo("-threads") == 0) { argindex++; if (argindex >= args.length) { usageMessage(); System.exit(0); } int tcount = Integer.parseInt(args[argindex]); props.setProperty("threadcount", tcount + ""); argindex++; } else if (args[argindex].compareTo("-target") == 0) { argindex++; if (argindex >= args.length) { usageMessage(); System.exit(0); } int ttarget = Integer.parseInt(args[argindex]); props.setProperty("target", ttarget + ""); argindex++; } else if (args[argindex].compareTo("-load") == 0) { dotransactions = false; argindex++; } else if (args[argindex].compareTo("-t") == 0) { dotransactions = true; argindex++; } else if (args[argindex].compareTo("-s") == 0) { status = true; argindex++; } else if (args[argindex].compareTo("-db") == 0) { argindex++; if (argindex >= args.length) { usageMessage(); System.exit(0); } props.setProperty("db", args[argindex]); argindex++; } else if (args[argindex].compareTo("-l") == 0) { argindex++; if (argindex >= args.length) { usageMessage(); System.exit(0); } label = args[argindex]; argindex++; } else if (args[argindex].compareTo("-P") == 0) { argindex++; if (argindex >= args.length) { usageMessage(); System.exit(0); } String propfile = args[argindex]; argindex++; Properties myfileprops = new Properties(); try { myfileprops.load(new FileInputStream(propfile)); } catch (IOException e) { System.out.println(e.getMessage()); System.exit(0); } // Issue #5 - remove call to stringPropertyNames to make compilable under Java 1.5 for (Enumeration e = myfileprops.propertyNames(); e.hasMoreElements(); ) { String prop = (String) e.nextElement(); fileprops.setProperty(prop, myfileprops.getProperty(prop)); } } else if (args[argindex].compareTo("-p") == 0) { argindex++; if (argindex >= args.length) { usageMessage(); System.exit(0); } int eq = args[argindex].indexOf('='); if (eq < 0) { usageMessage(); System.exit(0); } String name = args[argindex].substring(0, eq); String value = args[argindex].substring(eq + 1); props.put(name, value); // System.out.println("["+name+"]=["+value+"]"); argindex++; } else { System.out.println("Unknown option " + args[argindex]); usageMessage(); System.exit(0); } if (argindex >= args.length) { break; } } if (argindex != args.length) { usageMessage(); System.exit(0); } // set up logging // BasicConfigurator.configure(); // overwrite file properties with properties from the command line // Issue #5 - remove call to stringPropertyNames to make compilable under Java 1.5 for (Enumeration e = props.propertyNames(); e.hasMoreElements(); ) { String prop = (String) e.nextElement(); fileprops.setProperty(prop, props.getProperty(prop)); } props = fileprops; if (!checkRequiredProperties(props)) { System.exit(0); } long maxExecutionTime = Integer.parseInt(props.getProperty(MAX_EXECUTION_TIME, "0")); // get number of threads, target and db threadcount = Integer.parseInt(props.getProperty("threadcount", "1")); dbname = props.getProperty("db", "com.yahoo.ycsb.BasicDB"); target = Integer.parseInt(props.getProperty("target", "0")); // compute the target throughput double targetperthreadperms = -1; if (target > 0) { double targetperthread = ((double) target) / ((double) threadcount); targetperthreadperms = targetperthread / 1000.0; } System.out.println("YCSB Client 0.1"); System.out.print("Command line:"); for (int i = 0; i < args.length; i++) { System.out.print(" " + args[i]); } System.out.println(); System.err.println("Loading workload..."); // show a warning message that creating the workload is taking a while // but only do so if it is taking longer than 2 seconds // (showing the message right away if the setup wasn't taking very long was confusing people) Thread warningthread = new Thread() { public void run() { try { sleep(2000); } catch (InterruptedException e) { return; } System.err.println(" (might take a few minutes for large data sets)"); } }; warningthread.start(); // set up measurements Measurements.setProperties(props); // load the workload ClassLoader classLoader = Client.class.getClassLoader(); Workload workload = null; try { Class workloadclass = classLoader.loadClass(props.getProperty(WORKLOAD_PROPERTY)); workload = (Workload) workloadclass.newInstance(); } catch (Exception e) { e.printStackTrace(); e.printStackTrace(System.out); System.exit(0); } try { workload.init(props); } catch (WorkloadException e) { e.printStackTrace(); e.printStackTrace(System.out); System.exit(0); } warningthread.interrupt(); // run the workload System.err.println("Starting test."); int opcount; if (dotransactions) { opcount = Integer.parseInt(props.getProperty(OPERATION_COUNT_PROPERTY, "0")); } else { if (props.containsKey(INSERT_COUNT_PROPERTY)) { opcount = Integer.parseInt(props.getProperty(INSERT_COUNT_PROPERTY, "0")); } else { opcount = Integer.parseInt(props.getProperty(RECORD_COUNT_PROPERTY, "0")); } } Vector<Thread> threads = new Vector<Thread>(); for (int threadid = 0; threadid < threadcount; threadid++) { DB db = null; try { db = DBFactory.newDB(dbname, props); } catch (UnknownDBException e) { System.out.println("Unknown DB " + dbname); System.exit(0); } Thread t = new ClientThread( db, dotransactions, workload, threadid, threadcount, props, opcount / threadcount, targetperthreadperms); threads.add(t); // t.start(); } StatusThread statusthread = null; if (status) { boolean standardstatus = false; if (props.getProperty("measurementtype", "").compareTo("timeseries") == 0) { standardstatus = true; } statusthread = new StatusThread(threads, label, standardstatus); statusthread.start(); } long st = System.currentTimeMillis(); for (Thread t : threads) { t.start(); } Thread terminator = null; if (maxExecutionTime > 0) { terminator = new TerminatorThread(maxExecutionTime, threads, workload); terminator.start(); } int opsDone = 0; for (Thread t : threads) { try { t.join(); opsDone += ((ClientThread) t).getOpsDone(); } catch (InterruptedException e) { } } long en = System.currentTimeMillis(); if (terminator != null && !terminator.isInterrupted()) { terminator.interrupt(); } if (status) { statusthread.interrupt(); } try { workload.cleanup(); } catch (WorkloadException e) { e.printStackTrace(); e.printStackTrace(System.out); System.exit(0); } try { exportMeasurements(props, opsDone, en - st); } catch (IOException e) { System.err.println("Could not export measurements, error: " + e.getMessage()); e.printStackTrace(); System.exit(-1); } System.exit(0); }
public void run() { try { _db.init(); } catch (DBException e) { e.printStackTrace(); e.printStackTrace(System.out); return; } try { _workloadstate = _workload.initThread(_props, _threadid, _threadcount); } catch (WorkloadException e) { e.printStackTrace(); e.printStackTrace(System.out); return; } // spread the thread operations out so they don't all hit the DB at the same time try { // GH issue 4 - throws exception if _target>1 because random.nextInt argument must be >0 // and the sleep() doesn't make sense for granularities < 1 ms anyway if ((_target > 0) && (_target <= 1.0)) { sleep(Utils.random().nextInt((int) (1.0 / _target))); } } catch (InterruptedException e) { // do nothing. } try { if (_dotransactions) { long st = System.currentTimeMillis(); while (((_opcount == 0) || (_opsdone < _opcount)) && !_workload.isStopRequested()) { if (!_workload.doTransaction(_db, _workloadstate)) { break; } _opsdone++; // throttle the operations if (_target > 0) { // this is more accurate than other throttling approaches we have tried, // like sleeping for (1/target throughput)-operation latency, // because it smooths timing inaccuracies (from sleep() taking an int, // current time in millis) over many operations while (System.currentTimeMillis() - st < ((double) _opsdone) / _target) { try { sleep(1); } catch (InterruptedException e) { // do nothing. } } } } } else { long st = System.currentTimeMillis(); while (((_opcount == 0) || (_opsdone < _opcount)) && !_workload.isStopRequested()) { if (!_workload.doInsert(_db, _workloadstate)) { break; } _opsdone++; // throttle the operations if (_target > 0) { // this is more accurate than other throttling approaches we have tried, // like sleeping for (1/target throughput)-operation latency, // because it smooths timing inaccuracies (from sleep() taking an int, // current time in millis) over many operations while (System.currentTimeMillis() - st < ((double) _opsdone) / _target) { try { sleep(1); } catch (InterruptedException e) { // do nothing. } } } } } } catch (Exception e) { e.printStackTrace(); e.printStackTrace(System.out); System.exit(0); } try { _db.cleanup(); } catch (DBException e) { e.printStackTrace(); e.printStackTrace(System.out); return; } }