Skip to content
Snippets Groups Projects
Commit 661a76d1 authored by Jaemyoun's avatar Jaemyoun
Browse files

first completing rados-binding

parent a75f602d
No related branches found
No related tags found
No related merge requests found
......@@ -76,6 +76,7 @@ DATABASES = {
"mongodb-async": "com.yahoo.ycsb.db.AsyncMongoDbClient",
"nosqldb" : "com.yahoo.ycsb.db.NoSqlDbClient",
"orientdb" : "com.yahoo.ycsb.db.OrientDBClient",
"rados" : "com.yahoo.ycsb.db.RadosClient",
"redis" : "com.yahoo.ycsb.db.RedisClient",
"s3" : "com.yahoo.ycsb.db.S3Client",
"solr" : "com.yahoo.ycsb.db.SolrClient",
......
......@@ -93,7 +93,8 @@ LICENSE file.
<tarantool.version>1.6.5</tarantool.version>
<aerospike.version>3.1.2</aerospike.version>
<solr.version>5.4.0</solr.version>
<rados.version>0.2.0</rados.version>
<rados.version>0.3.0-SNAPSHOT</rados.version>
<json.version>20160212</json.version>
</properties>
<modules>
......
......@@ -24,5 +24,10 @@
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>${json.version}</version>
</dependency>
</dependencies>
</project>
package com.yahoo.ycsb.db;
import com.ceph.rados.Rados;
import com.ceph.rados.IoCTX;
import com.ceph.rados.jna.RadosObjectInfo;
import com.ceph.rados.ReadOp;
import com.ceph.rados.ReadOp.ReadResult;
import com.ceph.rados.exceptions.RadosException;
import com.yahoo.ycsb.ByteIterator;
import com.yahoo.ycsb.DB;
import com.yahoo.ycsb.DBException;
import com.yahoo.ycsb.Status;
import com.yahoo.ycsb.StringByteIterator;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Protocol;
import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.Vector;
import org.json.JSONObject;
/**
* YCSB binding for <a href="http://redis.io/">Redis</a>.
*
......@@ -23,114 +28,99 @@ import java.util.Vector;
*/
public class RadosClient extends DB {
private static String ENV_CONFIG_FILE = System.getenv("RADOS_JAVA_CONFIG_FILE");
private static String ENV_ID = System.getenv("RADOS_JAVA_ID");
private static String ENV_POOL = System.getenv("RADOS_JAVA_POOL");
// TODO: use conf file
private static String envCONFIGFILE = System.getenv("RADOS_JAVA_CONFIG_FILE");
private static String envID = System.getenv("RADOS_JAVA_ID");
private static String envPOOL = System.getenv("RADOS_JAVA_POOL");
private static final String CONFIG_FILE = ENV_CONFIG_FILE == null ? "/etc/ceph/ceph.conf" : ENV_CONFIG_FILE;
private static final String ID = ENV_ID == null ? "admin" : ENV_ID;
private static final String POOL = ENV_POOL == null ? "data" : ENV_POOL;
private static final String CONFIG_FILE = envCONFIGFILE == null ? "/etc/ceph/ceph.conf" : envCONFIGFILE;
private static final String ID = envID == null ? "admin" : envID;
private static final String POOL = envPOOL == null ? "data" : envPOOL;
private static Rados rados;
private static IoCTX ioctx;
public void init() throws DBException {
Properties props = getProperties();
int port;
String portString = props.getProperty(PORT_PROPERTY);
if (portString != null) {
port = Integer.parseInt(portString);
} else {
port = Protocol.DEFAULT_PORT;
}
String host = props.getProperty(HOST_PROPERTY);
jedis = new Jedis(host, port);
jedis.connect();
String password = props.getProperty(PASSWORD_PROPERTY);
if (password != null) {
jedis.auth(password);
rados = new Rados(ID);
try {
rados.confReadFile(new File(CONFIG_FILE));
rados.connect();
ioctx = rados.ioCtxCreate(POOL);
} catch (RadosException e) {
throw new DBException(e.getMessage() + ": " + e.getReturnValue());
}
}
public void cleanup() throws DBException {
jedis.disconnect();
}
/*
* Calculate a hash for a key to store it in an index. The actual return value
* of this function is not interesting -- it primarily needs to be fast and
* scattered along the whole space of doubles. In a real world scenario one
* would probably use the ASCII values of the keys.
*/
private double hash(String key) {
return key.hashCode();
rados.shutDown();
rados.ioCtxDestroy(ioctx);
}
// XXX jedis.select(int index) to switch to `table`
@Override
public Status read(String table, String key, Set<String> fields,
HashMap<String, ByteIterator> result) {
if (fields == null) {
StringByteIterator.putAllAsByteIterators(result, jedis.hgetAll(key));
} else {
String[] fieldArray =
(String[]) fields.toArray(new String[fields.size()]);
List<String> values = jedis.hmget(key, fieldArray);
Iterator<String> fieldIterator = fields.iterator();
Iterator<String> valueIterator = values.iterator();
while (fieldIterator.hasNext() && valueIterator.hasNext()) {
result.put(fieldIterator.next(),
new StringByteIterator(valueIterator.next()));
public Status read(String table, String key, Set<String> fields, HashMap<String, ByteIterator> result) {
byte[] buffer;
try {
RadosObjectInfo info = ioctx.stat(key);
buffer = new byte[(int)info.getSize()];
ReadOp rop = ioctx.readOpCreate();
ReadResult readResult = rop.queueRead(0, info.getSize());
// TODO: more size than byte length possible;
rop.operate(key, Rados.OPERATION_NOFLAG);
readResult.raiseExceptionOnError("Error ReadOP(%d)", readResult.getRVal());
if (info.getSize() != readResult.getBytesRead()) {
return new Status("ERROR", "Error the object size read");
}
assert !fieldIterator.hasNext() && !valueIterator.hasNext();
readResult.getBuffer().get(buffer);
} catch (RadosException e) {
return new Status("ERROR-" + e.getReturnValue(), e.getMessage());
}
JSONObject json = new JSONObject(new String(buffer, java.nio.charset.StandardCharsets.UTF_8));
Set<String> fieldsToReturn = (fields == null ? json.keySet() : fields);
for (String name : fieldsToReturn) {
result.put(name, new StringByteIterator(json.getString(name)));
}
return result.isEmpty() ? Status.ERROR : Status.OK;
}
@Override
public Status insert(String table, String key,
HashMap<String, ByteIterator> values) {
if (jedis.hmset(key, StringByteIterator.getStringMap(values))
.equals("OK")) {
jedis.zadd(INDEX_KEY, hash(key), key);
return Status.OK;
public Status insert(String table, String key, HashMap<String, ByteIterator> values) {
JSONObject json = new JSONObject(values);
try {
ioctx.write(key, json.toString());
} catch (RadosException e) {
return new Status("ERROR-" + e.getReturnValue(), e.getMessage());
}
return Status.ERROR;
return Status.OK;
}
@Override
public Status delete(String table, String key) {
return jedis.del(key) == 0 && jedis.zrem(INDEX_KEY, key) == 0 ? Status.ERROR
: Status.OK;
try {
ioctx.remove(key);
} catch (RadosException e) {
return new Status("ERROR-" + e.getReturnValue(), e.getMessage());
}
return Status.OK;
}
@Override
public Status update(String table, String key,
HashMap<String, ByteIterator> values) {
return jedis.hmset(key, StringByteIterator.getStringMap(values))
.equals("OK") ? Status.OK : Status.ERROR;
public Status update(String table, String key, HashMap<String, ByteIterator> values) {
Status rtn = delete(table, key);
if (rtn.equals(Status.OK)) {
return insert(table, key, values);
}
return rtn;
}
@Override
public Status scan(String table, String startkey, int recordcount,
Set<String> fields, Vector<HashMap<String, ByteIterator>> result) {
Set<String> keys = jedis.zrangeByScore(INDEX_KEY, hash(startkey),
Double.POSITIVE_INFINITY, 0, recordcount);
HashMap<String, ByteIterator> values;
for (String key : keys) {
values = new HashMap<String, ByteIterator>();
read(table, key, fields, values);
result.add(values);
}
return Status.OK;
public Status scan(String table, String startkey, int recordcount, Set<String> fields,
Vector<HashMap<String, ByteIterator>> result) {
return Status.NOT_IMPLEMENTED;
}
}
/**
* Copyright (c) 2016 YCSB contributors. 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.
*/
/**
* YCSB binding for RADOS of Ceph.
*/
package com.yahoo.ycsb.db;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment