package net.rubyeye.xmemcached.pressure;

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicInteger;

import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClient;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.command.BinaryCommandFactory;
import net.rubyeye.xmemcached.test.unittest.commands.binary.BinaryCommandAllTests;
import net.rubyeye.xmemcached.utils.AddrUtil;

public class MemcachedClientPressureTest {
	private static final class ClockWatch implements Runnable {
		private long startTime;
		private long stopTime;

		public synchronized void run() {
			if (this.startTime == -1) {
				this.startTime = System.nanoTime();
			} else {
				this.stopTime = System.nanoTime();
			}

		}

		public synchronized void start() {
			this.startTime = -1;
		}

		public synchronized long getDurationInNano() {
			return this.stopTime - this.startTime;
		}

		public synchronized long getDurationInMillis() {
			return (this.stopTime - this.startTime) / 1000000;
		}
	}

	static class TestThread extends Thread {
		int repeat;
		int start;
		int size;
		MemcachedClient client;
		AtomicInteger failure;
		AtomicInteger success;
		CyclicBarrier barrier;

		public TestThread(int repeat, int start, int size,
				MemcachedClient client, AtomicInteger failure,
				AtomicInteger success, CyclicBarrier barrier) {
			super();
			this.repeat = repeat;
			this.start = start;
			this.size = size;
			this.client = client;
			this.failure = failure;
			this.success = success;
			this.barrier = barrier;
		}

		public void run() {
			byte[] value = new byte[size];
			try {
				barrier.await();
				for (int i = 0; i < repeat; i++) {
					String key = String.valueOf(start + i);
					try {
						if (!client.set(key, 10, value))
							throw new RuntimeException("set failed");
						byte[] v = client.get(key);
						if (v == null || v.length != size)
							throw new RuntimeException("get failed");
						if (!client.touch(key, 10))
							throw new RuntimeException("touch failed");
						if (!client.delete(key, 10))
							throw new RuntimeException("delete failed");
						success.incrementAndGet();
					} catch (Exception e) {
						e.printStackTrace();
						failure.incrementAndGet();
					}
				}
				barrier.await();
			} catch (Exception e) {
				// ignore;
			}
		}

	}

	public static void main(String[] args) throws Exception {
		if (args.length < 1) {
			throw new RuntimeException("Please provide memcached servers.");
		}
		final int threads = 100;
		final int repeat = 50000;
		int size = 1024;

		String servers = args[0];
		final AtomicInteger failure = new AtomicInteger();
		final AtomicInteger success = new AtomicInteger();
		MemcachedClientBuilder builder = new XMemcachedClientBuilder(
				AddrUtil.getAddresses(servers));
		//builder.setCommandFactory(new BinaryCommandFactory());
		MemcachedClient client = builder.build();
		ClockWatch watch = new ClockWatch();
		CyclicBarrier barrier = new CyclicBarrier(threads + 1, watch);
		for (int i = 0; i < threads; i++) {
			new TestThread(repeat, i * repeat * 2, size, client, failure,
					success, barrier).start();
		}
		new Thread() {
			public void run() {
				try {
					while (success.get() + failure.get() < repeat * threads) {
						Thread.sleep(1000);
						System.out.println("success:" + success.get()
								+ ",failure:" + failure.get());
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}.start();
		watch.start();
		barrier.await();
		barrier.await();

		long secs = watch.getDurationInMillis() / 1000;
		int total = 4 * repeat * threads;
		long tps = total / secs;
		client.shutdown();
		System.out.println("duration:" + secs + " seconds,tps:" + tps
				+ " op/seconds,total:" + total + " ops");

	}
}

@@ -280,206 +280,15 @@
 ient
-;%0Aimport net.rubyeye.xmemcached.XMemcachedClientBuilder;%0Aimport net.rubyeye.xmemcached.command.BinaryCommandFactory;%0Aimport net.rubyeye.xmemcached.test.unittest.commands.binary.BinaryCommandAllTests
+Builder
 ;%0Aim

Remove error imports