diff --git a/cloudspanner/dependency-reduced-pom.xml b/cloudspanner/dependency-reduced-pom.xml new file mode 100644 index 0000000000..c52b90b3f9 --- /dev/null +++ b/cloudspanner/dependency-reduced-pom.xml @@ -0,0 +1,53 @@ + + + + binding-parent + site.ycsb + 0.18.0-SNAPSHOT + ../binding-parent/pom.xml + + 4.0.0 + cloudspanner-binding + Cloud Spanner DB Binding + + + + maven-shade-plugin + + + package + + shade + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + org.example.Main + + + + + + + + + + + + site.ycsb + core + 0.18.0-SNAPSHOT + provided + + + diff --git a/mapdb/file.db b/mapdb/file.db new file mode 100644 index 0000000000..125a9698d0 Binary files /dev/null and b/mapdb/file.db differ diff --git a/mapdb/pom.xml b/mapdb/pom.xml new file mode 100644 index 0000000000..c11380bb28 --- /dev/null +++ b/mapdb/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + site.ycsb + root + 0.18.0-SNAPSHOT + + + mapdb-binding + MapDB Binding + jar + + + 17 + 17 + UTF-8 + + + + + org.mapdb + mapdb + 3.1.0 + + + site.ycsb + core + 0.18.0-SNAPSHOT + compile + + + junit + junit + 4.13.2 + test + + + + \ No newline at end of file diff --git a/mapdb/src/main/java/site/ycsb/MapDBClient.java b/mapdb/src/main/java/site/ycsb/MapDBClient.java new file mode 100644 index 0000000000..110911a21f --- /dev/null +++ b/mapdb/src/main/java/site/ycsb/MapDBClient.java @@ -0,0 +1,132 @@ +package site.ycsb; + +import org.mapdb.*; +import org.mapdb.DB; + +import java.util.*; + +/** + * MapDB client for YCSB framework. + * + */ +public class MapDBClient extends site.ycsb.DB { + + private DB mapDB; + private HTreeMap>> db; + + @Override + public void init() throws DBException { + this.mapDB = DBMaker + .fileDB("file.db") + .closeOnJvmShutdown() + .make(); + + db = mapDB.hashMap("db") + .keySerializer(Serializer.STRING) + .valueSerializer(Serializer.JAVA) + .createOrOpen(); + } + + public void cleanup() throws DBException { + db.clear(); + db.close(); + mapDB.close(); + } + + @Override + public Status read(String table, String key, Set fields, Map result) { + Map> collection = db.getOrDefault(table, new TreeMap<>()); + + Map map = collection.get(key); + + if (map == null) { + return Status.NOT_FOUND; + } + + for (String field : fields) { + result.put(field, new ByteArrayByteIterator(map.get(field))); + } + + return Status.OK; + } + + @Override + public Status scan(String table, + String startkey, + int recordcount, + Set fields, + Vector> result) { + TreeMap> collection = db.getOrDefault(table, new TreeMap<>()); + SortedMap> map = collection.tailMap(startkey); + + int counter = 0; + for (Map.Entry> entry : map.entrySet()) { + HashMap filteredMap = new HashMap<>(); + if (fields == null) { + for (Map.Entry entry1 : entry.getValue().entrySet()) { + filteredMap.put(entry1.getKey(), new ByteArrayByteIterator(entry1.getValue())); + } + } else { + for (Map.Entry entry1 : entry.getValue().entrySet()) { + if (fields.contains(entry1.getKey())) { + filteredMap.put(entry1.getKey(), new ByteArrayByteIterator(entry1.getValue())); + } + } + } + result.add(filteredMap); + + counter += 1; + if (counter == recordcount) { + break; + } + } + + return Status.OK; + } + + @Override + public Status update(String table, String key, Map values) { + TreeMap> collection = db.getOrDefault(table, new TreeMap<>()); + + HashMap map = collection.get(key); + + if (map == null) { + return Status.NOT_FOUND; + } + + for (Map.Entry entry : values.entrySet()) { + map.put(entry.getKey(), entry.getValue().toArray()); + } + collection.put(key, map); + db.put(table, collection); + + return Status.OK; + } + + @Override + public Status insert(String table, String key, Map values) { + TreeMap> collection = db.getOrDefault(table, new TreeMap<>()); + + HashMap map = collection.getOrDefault(key, new HashMap<>()); + + for (Map.Entry entry : values.entrySet()) { + map.put(entry.getKey(), entry.getValue().toArray()); + } + collection.put(key, map); + db.put(table, collection); + + return Status.OK; + } + + @Override + public Status delete(String table, String key) { + Map> collection = db.getOrDefault(table, new TreeMap<>()); + + Map removed = collection.remove(key); + + if (removed == null) { + return Status.NOT_FOUND; + } + return Status.OK; + } +} \ No newline at end of file diff --git a/mapdb/src/main/java/site/ycsb/package-info.java b/mapdb/src/main/java/site/ycsb/package-info.java new file mode 100644 index 0000000000..a6d73c4f74 --- /dev/null +++ b/mapdb/src/main/java/site/ycsb/package-info.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2017, 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. + */ + +/** + * The YCSB binding for MapDB. + */ +package site.ycsb; + diff --git a/mapdb/src/test/java/site/ycsb/MapDBClientTest.java b/mapdb/src/test/java/site/ycsb/MapDBClientTest.java new file mode 100644 index 0000000000..3c8319e4ea --- /dev/null +++ b/mapdb/src/test/java/site/ycsb/MapDBClientTest.java @@ -0,0 +1,147 @@ +/** + * Copyright (c) 2012-2017 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. + */ + +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package site.ycsb; + +import site.ycsb.workloads.CoreWorkload; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.util.HashMap; +import java.util.Properties; +import java.util.Set; +import java.util.Vector; + +import static org.junit.Assert.assertEquals; + +public class MapDBClientTest { + + @ClassRule public final static TemporaryFolder temp = new TemporaryFolder(); + private static final MapDBClient instance = new MapDBClient(); + private final static HashMap MOCK_DATA; + private final static String MOCK_TABLE = "MOCK_TABLE"; + private final static String MOCK_KEY0 = "0"; + private final static String MOCK_KEY1 = "1"; + private final static String MOCK_KEY2 = "2"; + private final static String FIELD_PREFIX = CoreWorkload.FIELD_NAME_PREFIX_DEFAULT; + + static { + MOCK_DATA = new HashMap<>(10); + for (int i = 1; i <= 10; i++) { + MOCK_DATA.put(FIELD_PREFIX + i, new StringByteIterator("value" + i)); + } + } + + @BeforeClass + public static void setUpClass() throws DBException { + final Properties props = new Properties(); + props.put("path.home", temp.getRoot().toString()); + instance.setProperties(props); + instance.init(); + } + + @AfterClass + public static void tearDownClass() throws DBException { + instance.cleanup(); + } + + @Before + public void setUp() { + instance.insert(MOCK_TABLE, MOCK_KEY1, MOCK_DATA); + instance.insert(MOCK_TABLE, MOCK_KEY2, MOCK_DATA); + } + + @After + public void tearDown() { + instance.delete(MOCK_TABLE, MOCK_KEY1); + instance.delete(MOCK_TABLE, MOCK_KEY2); + } + + /** + * Test of insert method, of class MapDBClient. + */ + @Test + public void testInsert() { + Status result = instance.insert(MOCK_TABLE, MOCK_KEY0, MOCK_DATA); + assertEquals(Status.OK, result); + } + + /** + * Test of delete method, of class MapDBClient. + */ + @Test + public void testDelete() { + Status result = instance.delete(MOCK_TABLE, MOCK_KEY1); + assertEquals(Status.OK, result); + } + + /** + * Test of read method, of class MapDBClient. + */ + @Test + public void testRead() { + Set fields = MOCK_DATA.keySet(); + HashMap resultParam = new HashMap<>(10); + Status result = instance.read(MOCK_TABLE, MOCK_KEY1, fields, resultParam); + assertEquals(Status.OK, result); + } + + /** + * Test of update method, of class MapDBClient. + */ + @Test + public void testUpdate() { + int i; + HashMap newValues = new HashMap<>(10); + + for (i = 1; i <= 10; i++) { + newValues.put(FIELD_PREFIX + i, new StringByteIterator("newvalue" + i)); + } + + Status result = instance.update(MOCK_TABLE, MOCK_KEY1, newValues); + assertEquals(Status.OK, result); + + //validate that the values changed + HashMap resultParam = new HashMap<>(10); + instance.read(MOCK_TABLE, MOCK_KEY1, MOCK_DATA.keySet(), resultParam); + + for (i = 1; i <= 10; i++) { + assertEquals("newvalue" + i, resultParam.get(FIELD_PREFIX + i).toString()); + } + } + + /** + * Test of scan method, of class MapDBClient. + */ + @Test + public void testScan() { + int recordcount = 10; + Set fields = MOCK_DATA.keySet(); + Vector> resultParam = new Vector<>(10); + Status result = instance.scan(MOCK_TABLE, MOCK_KEY1, recordcount, fields, resultParam); + assertEquals(Status.OK, result); + } +} diff --git a/pom.xml b/pom.xml index 7a24d43d4f..4e3ba9ad69 100644 --- a/pom.xml +++ b/pom.xml @@ -203,6 +203,7 @@ LICENSE file. tablestore voltdb zookeeper + mapdb