Skip to content

Commit

Permalink
KVStore updates
Browse files Browse the repository at this point in the history
  • Loading branch information
lukemartinlogan committed May 1, 2023
1 parent cf1c35f commit e9ebbac
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 39 deletions.
2 changes: 1 addition & 1 deletion adapter/kvstore/java/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ dependencies {
// 'test.useTestNG()' to your build script.
testCompile 'junit:junit:4.12'

compile files('../../../wrapper/java/build/libs/hermes.jar')
compile files('../../../wrapper/java/build/libs/hermes-1.0.0.jar')
}

sourceSets {
Expand Down
2 changes: 1 addition & 1 deletion adapter/kvstore/java/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ include 'api'
include 'services:webservice'
*/

rootProject.name = 'kvstore'
rootProject.name = 'hermes_kvstore-1.0.0'
4 changes: 2 additions & 2 deletions adapter/kvstore/java/src/kvstore/java/KVStore.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package kvstore.java;
import kvstore.java.KVTable;
package hermes_kvstore.java;
import hermes_kvstore.java.KVTable;
import hermes.java.Hermes;

public class KVStore {
Expand Down
82 changes: 61 additions & 21 deletions adapter/kvstore/java/src/kvstore/java/KVTable.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package kvstore.java;
package hermes_kvstore.java;

import java.nio.ByteBuffer;
import java.util.Map;
Expand Down Expand Up @@ -27,60 +27,87 @@ public class KVTable {
}

/** Serialize a Map into a blob */
private <T> Blob mapToBlob(Map<String, T> map) {
private <T> Blob blobSerialize(T obj) throws IOException {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(map);
oos.writeObject(obj);
oos.close();
byte[] bytes = baos.toByteArray();
return new Blob(ByteBuffer.wrap(bytes));
} catch (IOException e) {
e.printStackTrace();
return Blob.fromString("");
throw e;
}
}

/** Deserialize a Map from a blob */
private <T> Map<String, T> blobToMap(Blob blob) {
private <T> T blobDeserialize(Blob blob) throws IOException, ClassNotFoundException {
try {
byte[] bytes = blob.array();
ByteArrayInputStream istream = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(istream);
Map<String, T> map = (Map<String, T>) ois.readObject();
T obj = (T) ois.readObject();
ois.close();
blob.close();
return map;
return obj;
} catch (IOException e) {
e.printStackTrace();
return new HashMap<String, T>();
throw e;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return new HashMap<String, T>();
throw e;
}
}

public String getFieldKey(String key, String field_name) {
return String.format("%s-%s", key, field_name);
}

public String getKvMetadataKey() {
return "hermes-kvmetadata";
}

/**
* Insert a new record into the table
* */
public <T> void insert(String key, Map<String, T> val) throws IOException {
/*UniqueId md_id = bkt_.getBlobId(getKvMetadataKey());
if (md_id.isNull()) {
Set<String> keys = new HashSet<String>(val.keySet());
Blob md_blob = blobSerialize(keys);
bkt_.put(getKvMetadataKey(), md_blob);
md_blob.close();
}
for (Map.Entry<String, T> entry : val.entrySet()) {
String field_key = getFieldKey(key, entry.getKey());
Blob blob = blobSerialize(entry.getValue());
bkt_.put(field_key, blob);
blob.close();
}*/
Blob blob = blobSerialize(val);
bkt_.put(key, blob);
blob.close();
}

/**
* Create or insert a record into the table
*
* @param key the record key
* @param val the values to update in the record
* @return None
* */
public <T> void update(String key, Map<String, T> val) {
public <T> void update(String key, Map<String, T> val) throws IOException, ClassNotFoundException {
/*insert(key, val);*/
UniqueId blob_id = bkt_.getBlobId(key);
if (blob_id.isNull()) {
Blob blob = mapToBlob(val);
bkt_.put(key, blob);
blob.close();
insert(key, val);
} else {
bkt_.lockBlob(blob_id, MdLockType.kExternalWrite);
Blob orig_blob = bkt_.get(blob_id);
Map<String, T> old_val = blobToMap(orig_blob);
for (Map.Entry<String, T> entry : val.entrySet()) {
old_val.put(entry.getKey(), entry.getValue());
}
Blob new_blob = mapToBlob(old_val);
Map<String, T> old_val = blobDeserialize(orig_blob);
old_val.putAll(val);
Blob new_blob = blobSerialize(old_val);
bkt_.put(key, new_blob);
bkt_.unlockBlob(blob_id, MdLockType.kExternalWrite);
new_blob.close();
Expand All @@ -94,16 +121,29 @@ public <T> void update(String key, Map<String, T> val) {
* @param field_set the field in the record to update
* @return The blob containing only the field's data
* */
public <T> Map<String, T> read(String key, Set<String> field_set) {
public <T> Map<String, T> read(String key, Set<String> field_set) throws IOException, ClassNotFoundException {
/*HashMap<String, T> map = new HashMap<String, T>();
if (field_set.isEmpty()) {
UniqueId md_id = bkt_.getBlobId(getKvMetadataKey());
Blob md_blob = bkt_.get(md_id);
field_set = (HashSet<String>)blobDeserialize(md_blob);
}
for (String field_name : field_set) {
UniqueId blob_id = bkt_.getBlobId(getFieldKey(key, field_name));
Blob blob = bkt_.get(blob_id);
map.put(field_name, blobDeserialize(blob));
}
return map;*/

UniqueId blob_id = bkt_.getBlobId(key);
bkt_.lockBlob(blob_id, MdLockType.kExternalRead);
Blob orig_blob = bkt_.get(blob_id);
Map<String, T> old_val = blobToMap(orig_blob);
Map<String, T> old_val = blobDeserialize(orig_blob);
bkt_.unlockBlob(blob_id, MdLockType.kExternalRead);
return old_val;
}

public <T> Map<String, T> read(String key) {
public <T> Map<String, T> read(String key) throws IOException, ClassNotFoundException {
return read(key, new HashSet<String>());
}

Expand Down
28 changes: 16 additions & 12 deletions adapter/kvstore/java/src/test/java/KvstoreJniTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,33 @@
import static org.junit.Assert.*;
import java.nio.*;
import java.util.*;
import kvstore.java.KVStore;
import kvstore.java.KVTable;
import hermes_kvstore.java.KVStore;
import hermes_kvstore.java.KVTable;

import java.lang.management.ManagementFactory;

public class KvstoreJniTest {
@Test
public void testKvPutGet() {
public void testKvPutGet() throws Exception {
String pid = ManagementFactory.getRuntimeMXBean().getName();
System.out.println(pid);
KVStore.connect();
KVTable table = KVStore.getTable("hello");/**/

HashMap<String, String> record = new HashMap<String, String>();
record.put("f0", "abcde");
record.put("f1", "12345");
record.put("f2", "ABCDE");
table.update("0", record);
table.update("0", record);
Map<String, String> read_record = table.read("0");

for (Map.Entry<String, String> entry : read_record.entrySet()) {
assertTrue(entry.getValue().equals(record.get(entry.getKey())));
try {
record.put("f0", "abcde");
record.put("f1", "12345");
record.put("f2", "ABCDE");
table.update("0", record);
table.update("0", record);
Map<String, String> read_record = table.read("0");
for (Map.Entry<String, String> entry : read_record.entrySet()) {
assertTrue(entry.getValue().equals(record.get(entry.getKey())));
}
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}
2 changes: 1 addition & 1 deletion test/data/hermes_server.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ devices:

# The maximum buffering capacity in MiB of each device. Here we say that all 4
# devices get 50 MiB of buffering capacity.
capacity: 50MB
capacity: 1000MB

# The size of the smallest available buffer in KiB. In general this should be
# the page size of your system for byte addressable storage, and the block size
Expand Down
2 changes: 1 addition & 1 deletion wrapper/java/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ include 'api'
include 'services:webservice'
*/

rootProject.name = 'hermes'
rootProject.name = 'hermes-1.0.0'

0 comments on commit e9ebbac

Please sign in to comment.