/**
* Copyright (c) 2010 Yahoo! Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you
* may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License. See accompanying
* LICENSE file.
*/
package com.couchbase.loadgen.memcached;
import com.couchbase.loadgen.exception.DataStoreException;
import com.couchbase.loadgen.measurements.Measurements;
/**
* Wrapper around a "real" DB that measures latencies and counts return codes.
*/
public class MemcachedImpl extends Memcached {
Memcached _db;
Measurements _measurements;
public MemcachedImpl(Memcached memcached) {
_db = memcached;
_measurements = Measurements.getMeasurements();
}
/**
* Initialize any state for this Memcached. Called once per Memcached instance; there is
* one Memcached instance per client thread.
*/
public void init() throws DataStoreException {
_db.init();
}
/**
* Cleanup any state for this Memcached. Called once per Memcached instance; there is one
* Memcached instance per client thread.
*/
public void cleanup() throws DataStoreException {
_db.cleanup();
}
/**
* Adds a keys value in the database if the key doesn't already exist
*
* @param key
* The key to add to the database
* @param value
* The Object that will be the value of the key
* @return Zero on success, a non-zero error code on error
*/
public int add(String key, Object value) {
long st = System.nanoTime();
int res = _db.add(key, value);
long en = System.nanoTime();
_measurements.measure("ADD", (int) ((en - st) / 1000));
_measurements.reportReturnCode("ADD", res);
return res;
}
/**
* Appends a value to a keys current value
*
* @param key
* The key who's value will be appended.
* @param
* The unique cas value to do the append with
* @param value
* The Object to append to the end of the keys current value
* @return Zero on success, a non-zero error code on error
*/
public int append(String key, long cas, Object value) {
long st = System.nanoTime();
int res = _db.append(key, cas, value);
long en = System.nanoTime();
_measurements.measure("APPEND", (int) ((en - st) / 1000));
_measurements.reportReturnCode("APPEND", res);
return res;
}
/**
* Stores a new value if the operation has the correct cas value
*
* @param key
* The key whose value will be replace in the database
* @param cas
* The unique cas value to do the operation with
* @param value
* The Object to replace the keys old value with.
* @return Zero on success, a non-zero error code on error
*/
public int cas(String key, long cas, Object value) {
long st = System.nanoTime();
int res = _db.cas(key, cas, value);
long en = System.nanoTime();
_measurements.measure("CAS", (int) ((en - st) / 1000));
_measurements.reportReturnCode("CAS", res);
return res;
}
/**
* Decrement a keys value in the database
*
* @param key
* The key whose value will be decremented
* @param value
* The Object that the key should contain after decrementing
* @return Zero on success, a non-zero error code on error
*/
public int decr(String key, Object value) {
long st = System.nanoTime();
int res = _db.decr(key, value);
long en = System.nanoTime();
_measurements.measure("DECR", (int) ((en - st) / 1000));
_measurements.reportReturnCode("DECR", res);
return res;
}
/**
* Delete a key from the database
*
* @param key
* The key to delete
* @return Zero on success, a non-zero error code on error
*/
public int delete(String key) {
long st = System.nanoTime();
int res = _db.delete(key);
long en = System.nanoTime();
_measurements.measure("DELETE", (int) ((en - st) / 1000));
_measurements.reportReturnCode("DELETE", res);
return res;
}
/**
* Increment a keys value in the database
*
* @param key
* The key whose value will be incremented
* @param value
* The Object that the key should contain after incrementing
* @return Zero on success, a non-zero error code on error
*/
public int incr(String key, Object value) {
long st = System.nanoTime();
int res = _db.incr(key, value);
long en = System.nanoTime();
_measurements.measure("INCR", (int) ((en - st) / 1000));
_measurements.reportReturnCode("INCR", res);
return res;
}
/**
* Get a key's value from the database.
*
* @param key
* The key to get a value for.
* @param value
* The Object that the key should contain
* @return Zero on success, a non-zero error code on error
*/
public int get(String key, Object value) {
long st = System.nanoTime();
int res = _db.get(key, value);
//int res = 0;
long en = System.nanoTime();
//long en = ((SpymemcachedClient)_db).qGet(key, value);
//System.out.println(en + " : " + st + " : " + (en - st));
if (en > 0) {
_measurements.measure("GET", (int) ((en - st) / 1000));
_measurements.reportReturnCode("GET", res);
}
return res;
}
/**
* Gets a unique cas value for a key.
*
* @param key
* The key to get a cas value for
* @return The cas value on success, a non-zero error code on error
*/
public long gets(String key) {
long st = System.nanoTime();
long res = _db.gets(key);
long en = System.nanoTime();
_measurements.measure("GETS", (int) ((en - st) / 1000));
if (res > 0)
_measurements.reportReturnCode("GETS", 0);
else
_measurements.reportReturnCode("GETS", -1);
return res;
}
/**
* Prepends a value to a keys current value
*
* @param key
* The key who's value will be prepended.
* @param
* The unique cas value to do the prepend with
* @param value
* The Object to prepend to the front of the keys current value
* @return Zero on success, a non-zero error code on error
*/
public int prepend(String key, long cas, Object value) {
long st = System.nanoTime();
int res = _db.prepend(key, cas, value);
long en = System.nanoTime();
_measurements.measure("PREPEND", (int) ((en - st) / 1000));
_measurements.reportReturnCode("PREPEND", 0);
return res;
}
/**
* Replaces the value of a key already in the database. If a key doesn't
* exist this operation fails.
*
* @param key
* The key who's value will be replaced.
* @param value
* The Object that will replace the old key value.
* @return Zero on success, a non-zero error code on error
*/
public int replace(String key, Object value) {
long st = System.nanoTime();
int res = _db.replace(key, value);
long en = System.nanoTime();
_measurements.measure("REPLACE", (int) ((en - st) / 1000));
_measurements.reportReturnCode("REPLACE", res);
return res;
}
/**
* Insert a record in the database. Any field/value pairs in the specified
* values HashMap will be written into the record with the specified record
* key.
*
* @param key
* The record key of the record to set.
* @param value
* The Object to use as the keys value
* @return Zero on success, a non-zero error code on error
*/
public int set(String key, Object value) {
long st = System.nanoTime();
int res = _db.set(key, value);
long en = System.nanoTime();
_measurements.measure("SET", (int) ((en - st) / 1000));
_measurements.reportReturnCode("SET", res);
return res;
}
public int update(String key, Object value) {
long st = System.nanoTime();
int res = _db.set(key, value);
long en = System.nanoTime();
_measurements.measure("UPDATE", (int) ((en - st) / 1000));
_measurements.reportReturnCode("UPDATE", res);
return res;
}
}