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 = { ...@@ -76,6 +76,7 @@ DATABASES = {
"mongodb-async": "com.yahoo.ycsb.db.AsyncMongoDbClient", "mongodb-async": "com.yahoo.ycsb.db.AsyncMongoDbClient",
"nosqldb" : "com.yahoo.ycsb.db.NoSqlDbClient", "nosqldb" : "com.yahoo.ycsb.db.NoSqlDbClient",
"orientdb" : "com.yahoo.ycsb.db.OrientDBClient", "orientdb" : "com.yahoo.ycsb.db.OrientDBClient",
"rados" : "com.yahoo.ycsb.db.RadosClient",
"redis" : "com.yahoo.ycsb.db.RedisClient", "redis" : "com.yahoo.ycsb.db.RedisClient",
"s3" : "com.yahoo.ycsb.db.S3Client", "s3" : "com.yahoo.ycsb.db.S3Client",
"solr" : "com.yahoo.ycsb.db.SolrClient", "solr" : "com.yahoo.ycsb.db.SolrClient",
......
...@@ -93,7 +93,8 @@ LICENSE file. ...@@ -93,7 +93,8 @@ LICENSE file.
<tarantool.version>1.6.5</tarantool.version> <tarantool.version>1.6.5</tarantool.version>
<aerospike.version>3.1.2</aerospike.version> <aerospike.version>3.1.2</aerospike.version>
<solr.version>5.4.0</solr.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> </properties>
<modules> <modules>
......
...@@ -24,5 +24,10 @@ ...@@ -24,5 +24,10 @@
<version>${project.version}</version> <version>${project.version}</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>${json.version}</version>
</dependency>
</dependencies> </dependencies>
</project> </project>
package com.yahoo.ycsb.db; 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.ByteIterator;
import com.yahoo.ycsb.DB; import com.yahoo.ycsb.DB;
import com.yahoo.ycsb.DBException; import com.yahoo.ycsb.DBException;
import com.yahoo.ycsb.Status; import com.yahoo.ycsb.Status;
import com.yahoo.ycsb.StringByteIterator; import com.yahoo.ycsb.StringByteIterator;
import redis.clients.jedis.Jedis; import java.io.File;
import redis.clients.jedis.Protocol;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.Vector; import java.util.Vector;
import org.json.JSONObject;
/** /**
* YCSB binding for <a href="http://redis.io/">Redis</a>. * YCSB binding for <a href="http://redis.io/">Redis</a>.
* *
...@@ -23,114 +28,99 @@ import java.util.Vector; ...@@ -23,114 +28,99 @@ import java.util.Vector;
*/ */
public class RadosClient extends DB { public class RadosClient extends DB {
private static String ENV_CONFIG_FILE = System.getenv("RADOS_JAVA_CONFIG_FILE"); // TODO: use conf file
private static String ENV_ID = System.getenv("RADOS_JAVA_ID"); private static String envCONFIGFILE = System.getenv("RADOS_JAVA_CONFIG_FILE");
private static String ENV_POOL = System.getenv("RADOS_JAVA_POOL"); 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 CONFIG_FILE = envCONFIGFILE == null ? "/etc/ceph/ceph.conf" : envCONFIGFILE;
private static final String ID = ENV_ID == null ? "admin" : ENV_ID; private static final String ID = envID == null ? "admin" : envID;
private static final String POOL = ENV_POOL == null ? "data" : ENV_POOL; private static final String POOL = envPOOL == null ? "data" : envPOOL;
private static Rados rados; private static Rados rados;
private static IoCTX ioctx; private static IoCTX ioctx;
public void init() throws DBException { public void init() throws DBException {
Properties props = getProperties(); rados = new Rados(ID);
int port; try {
rados.confReadFile(new File(CONFIG_FILE));
String portString = props.getProperty(PORT_PROPERTY); rados.connect();
if (portString != null) { ioctx = rados.ioCtxCreate(POOL);
port = Integer.parseInt(portString); } catch (RadosException e) {
} else { throw new DBException(e.getMessage() + ": " + e.getReturnValue());
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);
} }
} }
public void cleanup() throws DBException { public void cleanup() throws DBException {
jedis.disconnect(); rados.shutDown();
} rados.ioCtxDestroy(ioctx);
/*
* 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();
} }
// XXX jedis.select(int index) to switch to `table`
@Override @Override
public Status read(String table, String key, Set<String> fields, public Status read(String table, String key, Set<String> fields, HashMap<String, ByteIterator> result) {
HashMap<String, ByteIterator> result) { byte[] buffer;
if (fields == null) {
StringByteIterator.putAllAsByteIterators(result, jedis.hgetAll(key)); try {
} else { RadosObjectInfo info = ioctx.stat(key);
String[] fieldArray = buffer = new byte[(int)info.getSize()];
(String[]) fields.toArray(new String[fields.size()]);
List<String> values = jedis.hmget(key, fieldArray); ReadOp rop = ioctx.readOpCreate();
ReadResult readResult = rop.queueRead(0, info.getSize());
Iterator<String> fieldIterator = fields.iterator(); // TODO: more size than byte length possible;
Iterator<String> valueIterator = values.iterator(); rop.operate(key, Rados.OPERATION_NOFLAG);
readResult.raiseExceptionOnError("Error ReadOP(%d)", readResult.getRVal());
while (fieldIterator.hasNext() && valueIterator.hasNext()) { if (info.getSize() != readResult.getBytesRead()) {
result.put(fieldIterator.next(), return new Status("ERROR", "Error the object size read");
new StringByteIterator(valueIterator.next()));
} }
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; return result.isEmpty() ? Status.ERROR : Status.OK;
} }
@Override @Override
public Status insert(String table, String key, public Status insert(String table, String key, HashMap<String, ByteIterator> values) {
HashMap<String, ByteIterator> values) { JSONObject json = new JSONObject(values);
if (jedis.hmset(key, StringByteIterator.getStringMap(values))
.equals("OK")) { try {
jedis.zadd(INDEX_KEY, hash(key), key); ioctx.write(key, json.toString());
return Status.OK; } catch (RadosException e) {
return new Status("ERROR-" + e.getReturnValue(), e.getMessage());
} }
return Status.ERROR; return Status.OK;
} }
@Override @Override
public Status delete(String table, String key) { public Status delete(String table, String key) {
return jedis.del(key) == 0 && jedis.zrem(INDEX_KEY, key) == 0 ? Status.ERROR try {
: Status.OK; ioctx.remove(key);
} catch (RadosException e) {
return new Status("ERROR-" + e.getReturnValue(), e.getMessage());
}
return Status.OK;
} }
@Override @Override
public Status update(String table, String key, public Status update(String table, String key, HashMap<String, ByteIterator> values) {
HashMap<String, ByteIterator> values) { Status rtn = delete(table, key);
return jedis.hmset(key, StringByteIterator.getStringMap(values)) if (rtn.equals(Status.OK)) {
.equals("OK") ? Status.OK : Status.ERROR; return insert(table, key, values);
}
return rtn;
} }
@Override @Override
public Status scan(String table, String startkey, int recordcount, public Status scan(String table, String startkey, int recordcount, Set<String> fields,
Set<String> fields, Vector<HashMap<String, ByteIterator>> result) { Vector<HashMap<String, ByteIterator>> result) {
Set<String> keys = jedis.zrangeByScore(INDEX_KEY, hash(startkey), return Status.NOT_IMPLEMENTED;
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;
} }
} }
/**
* 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; 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