package com.couchbase.loadgen.memcached; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.util.Arrays; import java.util.Random; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.couchbase.loadgen.Config; import com.couchbase.loadgen.cluster.ClusterManager; import net.spy.memcached.BinaryConnectionFactory; import net.spy.memcached.CASResponse; import net.spy.memcached.MemcachedClient; public class SpymemcachedClient extends Memcached { private static final Logger LOG = LoggerFactory.getLogger(SpymemcachedClient.class); public static final String CLASSNAME = "com.couchbase.loadgen.memcached.SpymemcachedClient"; public static final String PROTO_ASCII = "ascii"; public static final String PROTO_BINARY = "binary"; MemcachedClient client; public static long endtime; Random random; boolean verbose; int todelay; public SpymemcachedClient() { random = new Random(); todelay = 0; } /** * Initialize any state for this DB. Called once per DB instance; there is * one DB instance per client thread. */ public void init() { int membaseport = ((Integer) Config.getConfig().get(Config.MEMCACHED_PORT)).intValue(); String addr = (String) Config.getConfig().get(Config.MEMCACHED_ADDRESS); String protocol = (String) Config.getConfig().get(Config.PROTOCOL); try { InetSocketAddress ia = new InetSocketAddress(InetAddress.getByAddress(ipv4AddressToByte(addr)), membaseport); if (protocol.equals(PROTO_BINARY)) { client = new MemcachedClient(new BinaryConnectionFactory(), Arrays.asList(ia)); } else if (protocol.equals(PROTO_ASCII)) { client = new MemcachedClient(ia); } else { LOG.info("ERROR: BAD PROTOCOL"); ClusterManager.getManager().finishedLoadGeneration(); } } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } } public void cleanup() { if (client.isAlive()) client.shutdown(); } @Override public int add(String key, Object value) { try { if (!client.add(key, 0, value).get().booleanValue()) { System.out.println("ADD: error getting data"); return -1; } } catch (InterruptedException e) { System.out.println("ADD Interrupted"); } catch (ExecutionException e) { System.out.println("ADD Execution"); } catch (RuntimeException e) { System.out.println("ADD Runtime"); } return 0; } @Override public int get(String key, Object value) { Future<Object> f = client.asyncGet(key); try { if (f.get() == null) { System.out.println("GET: error getting data"); return -1; } } catch (InterruptedException e) { System.out.println("GET Interrupted"); } catch (ExecutionException e) { System.out.println("GET Execution"); e.printStackTrace(); return -2; } catch (RuntimeException e) { System.out.println("GET Runtime"); return -3; } return 0; } /*public long qGet(String key, Object value) { return client.ag(key); }*/ @Override public int set(String key, Object value) { try { if (!client.set(key, 0, value).get().booleanValue()) { System.out.println("SET: error getting data"); return -1; } } catch (InterruptedException e) { System.out.println("SET Interrupted"); } catch (ExecutionException e) { System.out.println("SET Execution"); } catch (RuntimeException e) { System.out.println("SET Runtime"); } return 0; } private byte[] ipv4AddressToByte(String address) { byte[] b = new byte[4]; String[] str = address.split("\\."); b[0] = Integer.valueOf(str[0]).byteValue(); b[1] = Integer.valueOf(str[1]).byteValue(); b[2] = Integer.valueOf(str[2]).byteValue(); b[3] = Integer.valueOf(str[3]).byteValue(); return b; } @Override public int append(String key, long cas, Object value) { try { if (!client.append(cas, key, value).get().booleanValue()) System.out.println("APPEND: error getting data"); return -1; } catch (InterruptedException e) { System.out.println("APPEND Interrupted"); } catch (ExecutionException e) { System.out.println("APPEND Execution"); } catch (RuntimeException e) { System.out.println("APPEND Runtime"); } return 0; } @Override public int cas(String key, long cas, Object value) { if (!client.cas(key, cas, value).equals(CASResponse.OK)) { System.out.println("CAS: error getting data"); return -1; } return 0; } @Override public int decr(String key, Object value) { return 0; } @Override public int delete(String key) { return 0; } @Override public int incr(String key, Object value) { return 0; } @Override public long gets(String key) { long cas = client.gets(key).getCas(); if (cas < 0) { System.out.println("GETS: error getting data"); return -1; } return cas; } @Override public int prepend(String key, long cas, Object value) { try { if (!client.prepend(cas, key, value).get().booleanValue()) return -1; } catch (InterruptedException e) { System.out.println("PREPEND Interrupted"); } catch (ExecutionException e) { System.out.println("PREPEND Execution"); } catch (RuntimeException e) { System.out.println("PREPEND Runtime"); } return 0; } @Override public int replace(String key, Object value) { try { if (!client.replace(key, 0, value).get().booleanValue()) { System.out.println("REPLACE: error getting data"); return -1; } } catch (InterruptedException e) { System.out.println("REPLACE Interrupted"); } catch (ExecutionException e) { System.out.println("REPLACE Execution"); } catch (RuntimeException e) { System.out.println("REPLACE Runtime"); } return 0; } @Override public int update(String key, Object value) { return set(key, value); } }