From 70f4362bdf63c6de6f408029bdcb6951f02867c6 Mon Sep 17 00:00:00 2001 From: Andrey Lomakin <lomakin.andrey@gmail.com> Date: Mon, 31 Oct 2016 22:28:34 +0200 Subject: [PATCH] [orientdb] OrientDB was updated to 2.2.10 and multithreading bugs fixed (#848) --- orientdb/README.md | 6 - .../com/yahoo/ycsb/db/OrientDBClient.java | 328 +++++++++--------- .../com/yahoo/ycsb/db/OrientDBClientTest.java | 110 +++--- pom.xml | 2 +- 4 files changed, 231 insertions(+), 215 deletions(-) diff --git a/orientdb/README.md b/orientdb/README.md index 578a5abb..ed637282 100644 --- a/orientdb/README.md +++ b/orientdb/README.md @@ -60,12 +60,6 @@ WARNING: Creating a new database will be done safely with multiple threads on a * ```orientdb.newdb``` - Overwrite the database if it already exists. * Only effects the ```load``` phase. * Default: ```false``` -* ```orientdb.intent``` - Declare an Intent to the database. - * This is an optimization feature provided by OrientDB: http://orientdb.com/docs/2.1/Performance-Tuning.html#massive-insertion - * Possible values are: - * massiveinsert - * massiveread - * nocache * ```orientdb.remote.storagetype``` - Storage type of the database on remote server * This is only required if using a ```remote:``` connection url diff --git a/orientdb/src/main/java/com/yahoo/ycsb/db/OrientDBClient.java b/orientdb/src/main/java/com/yahoo/ycsb/db/OrientDBClient.java index d1d29205..5c54d0c8 100644 --- a/orientdb/src/main/java/com/yahoo/ycsb/db/OrientDBClient.java +++ b/orientdb/src/main/java/com/yahoo/ycsb/db/OrientDBClient.java @@ -17,197 +17,191 @@ package com.yahoo.ycsb.db; -import com.orientechnologies.common.exception.OException; -import com.orientechnologies.orient.client.remote.OEngineRemote; import com.orientechnologies.orient.client.remote.OServerAdmin; -import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal; +import com.orientechnologies.orient.core.config.OGlobalConfiguration; +import com.orientechnologies.orient.core.db.OPartitionedDatabasePool; import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; -import com.orientechnologies.orient.core.db.record.OIdentifiable; import com.orientechnologies.orient.core.dictionary.ODictionary; -import com.orientechnologies.orient.core.exception.ODatabaseException; +import com.orientechnologies.orient.core.exception.OConcurrentModificationException; import com.orientechnologies.orient.core.index.OIndexCursor; -import com.orientechnologies.orient.core.intent.OIntentMassiveInsert; -import com.orientechnologies.orient.core.intent.OIntentMassiveRead; -import com.orientechnologies.orient.core.intent.OIntentNoCache; import com.orientechnologies.orient.core.record.ORecord; import com.orientechnologies.orient.core.record.impl.ODocument; -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 com.yahoo.ycsb.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map.Entry; -import java.util.Properties; -import java.util.Set; -import java.util.Vector; +import java.io.File; +import java.util.*; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; /** * OrientDB client for YCSB framework. */ public class OrientDBClient extends DB { + private static final String URL_PROPERTY = "orientdb.url"; + private static final String URL_PROPERTY_DEFAULT = + "plocal:." + File.separator + "target" + File.separator + "databases" + File.separator + "ycsb"; - private static final String CLASS = "usertable"; - private ODatabaseDocumentTx db; - private ODictionary<ORecord> dictionary; - private boolean isRemote = false; - - private static final String URL_PROPERTY = "orientdb.url"; - - private static final String USER_PROPERTY = "orientdb.user"; + private static final String USER_PROPERTY = "orientdb.user"; private static final String USER_PROPERTY_DEFAULT = "admin"; - private static final String PASSWORD_PROPERTY = "orientdb.password"; + private static final String PASSWORD_PROPERTY = "orientdb.password"; private static final String PASSWORD_PROPERTY_DEFAULT = "admin"; - private static final String NEWDB_PROPERTY = "orientdb.newdb"; + private static final String NEWDB_PROPERTY = "orientdb.newdb"; private static final String NEWDB_PROPERTY_DEFAULT = "false"; private static final String STORAGE_TYPE_PROPERTY = "orientdb.remote.storagetype"; - private static final String INTENT_PROPERTY = "orientdb.intent"; - private static final String INTENT_PROPERTY_DEFAULT = ""; + private static final String ORIENTDB_DOCUMENT_TYPE = "document"; - private static final String DO_TRANSACTIONS_PROPERTY = "dotransactions"; - private static final String DO_TRANSACTIONS_PROPERTY_DEFAULT = "true"; + private static final String CLASS = "usertable"; - private static final String ORIENTDB_DOCUMENT_TYPE = "document"; - private static final String ORIENTDB_MASSIVEINSERT = "massiveinsert"; - private static final String ORIENTDB_MASSIVEREAD = "massiveread"; - private static final String ORIENTDB_NOCACHE = "nocache"; + private static final Lock INIT_LOCK = new ReentrantLock(); + private static boolean dbChecked = false; + private static volatile OPartitionedDatabasePool databasePool; + private static boolean initialized = false; + private static int clientCounter = 0; + + private boolean isRemote = false; private static final Logger LOG = LoggerFactory.getLogger(OrientDBClient.class); /** - * This method abstracts the administration of OrientDB namely creating and connecting to a database. - * Creating a database needs to be done in a synchronized method so that multiple threads do not all try - * to run the creation operation simultaneously, this ends in failure. - * - * @param props Workload properties object - * @return a usable ODatabaseDocumentTx object - * @throws DBException + * Initialize any state for this DB. Called once per DB instance; there is one DB instance per client thread. */ - private static synchronized ODatabaseDocumentTx initDB(Properties props) throws DBException { - String url = props.getProperty(URL_PROPERTY); + public void init() throws DBException { + // initialize OrientDB driver + final Properties props = getProperties(); + String url = props.getProperty(URL_PROPERTY, URL_PROPERTY_DEFAULT); String user = props.getProperty(USER_PROPERTY, USER_PROPERTY_DEFAULT); + String password = props.getProperty(PASSWORD_PROPERTY, PASSWORD_PROPERTY_DEFAULT); Boolean newdb = Boolean.parseBoolean(props.getProperty(NEWDB_PROPERTY, NEWDB_PROPERTY_DEFAULT)); String remoteStorageType = props.getProperty(STORAGE_TYPE_PROPERTY); - Boolean isrun = Boolean.parseBoolean(props.getProperty(DO_TRANSACTIONS_PROPERTY, DO_TRANSACTIONS_PROPERTY_DEFAULT)); - - ODatabaseDocumentTx dbconn; - - if (url == null) { - throw new DBException(String.format("Required property \"%s\" missing for OrientDBClient", URL_PROPERTY)); - } - LOG.info("OrientDB loading database url = " + url); + INIT_LOCK.lock(); + try { + clientCounter++; + if (!initialized) { + OGlobalConfiguration.dumpConfiguration(System.out); - // If using a remote database, use the OServerAdmin interface to connect - if (url.startsWith(OEngineRemote.NAME)) { - if (remoteStorageType == null) { - throw new DBException("When connecting to a remote OrientDB instance, " + - "specify a database storage type (plocal or memory) with " + STORAGE_TYPE_PROPERTY); - } + LOG.info("OrientDB loading database url = " + url); - try { - OServerAdmin server = new OServerAdmin(url).connect(user, password); + ODatabaseDocumentTx db = new ODatabaseDocumentTx(url); - if (server.existsDatabase()) { - if (newdb && !isrun) { - LOG.info("OrientDB dropping and recreating fresh db on remote server."); - server.dropDatabase(remoteStorageType); - server.createDatabase(server.getURL(), ORIENTDB_DOCUMENT_TYPE, remoteStorageType); - } - } else { - LOG.info("OrientDB database not found, creating fresh db"); - server.createDatabase(server.getURL(), ORIENTDB_DOCUMENT_TYPE, remoteStorageType); + if (db.getStorage().isRemote()) { + isRemote = true; } - server.close(); - dbconn = new ODatabaseDocumentTx(url).open(user, password); - } catch (IOException | OException e) { - throw new DBException(String.format("Error interfacing with %s", url), e); - } - } else { - try { - dbconn = new ODatabaseDocumentTx(url); - if (dbconn.exists()) { - dbconn.open(user, password); - if (newdb && !isrun) { - LOG.info("OrientDB dropping and recreating fresh db."); - dbconn.drop(); - dbconn.create(); + if (!dbChecked) { + if (!isRemote) { + if (newdb) { + if (db.exists()) { + db.open(user, password); + LOG.info("OrientDB drop and recreate fresh db"); + + db.drop(); + } + + db.create(); + } else { + if (!db.exists()) { + LOG.info("OrientDB database not found, creating fresh db"); + + db.create(); + } + } + } else { + OServerAdmin server = new OServerAdmin(url).connect(user, password); + + if (remoteStorageType == null) { + throw new DBException( + "When connecting to a remote OrientDB instance, " + + "specify a database storage type (plocal or memory) with " + + STORAGE_TYPE_PROPERTY); + } + + if (newdb) { + if (server.existsDatabase()) { + LOG.info("OrientDB drop and recreate fresh db"); + + server.dropDatabase(remoteStorageType); + } + + server.createDatabase(db.getName(), ORIENTDB_DOCUMENT_TYPE, remoteStorageType); + } else { + if (!server.existsDatabase()) { + + LOG.info("OrientDB database not found, creating fresh db"); + server.createDatabase(server.getURL(), ORIENTDB_DOCUMENT_TYPE, remoteStorageType); + } + } + + server.close(); } - } else { - LOG.info("OrientDB database not found, creating fresh db"); - dbconn.create(); - } - } catch (ODatabaseException e) { - throw new DBException(String.format("Error interfacing with %s", url), e); - } - } - if (dbconn == null) { - throw new DBException("Could not establish connection to: " + url); - } + dbChecked = true; + } - LOG.info("OrientDB connection created with " + url); - return dbconn; - } + if (db.isClosed()) { + db.open(user, password); + } - @Override - public void init() throws DBException { - Properties props = getProperties(); + if (!db.getMetadata().getSchema().existsClass(CLASS)) { + db.getMetadata().getSchema().createClass(CLASS); + } - String intent = props.getProperty(INTENT_PROPERTY, INTENT_PROPERTY_DEFAULT); + db.close(); - db = initDB(props); + if (databasePool == null) { + databasePool = new OPartitionedDatabasePool(url, user, password); + } - if (db.getURL().startsWith(OEngineRemote.NAME)) { - isRemote = true; + initialized = true; + } + } catch (Exception e) { + LOG.error("Could not initialize OrientDB connection pool for Loader: " + e.toString()); + e.printStackTrace(); + } finally { + INIT_LOCK.unlock(); } - dictionary = db.getMetadata().getIndexManager().getDictionary(); - if (!db.getMetadata().getSchema().existsClass(CLASS)) { - db.getMetadata().getSchema().createClass(CLASS); - } + } - if (intent.equals(ORIENTDB_MASSIVEINSERT)) { - LOG.info("Declaring intent of MassiveInsert."); - db.declareIntent(new OIntentMassiveInsert()); - } else if (intent.equals(ORIENTDB_MASSIVEREAD)) { - LOG.info("Declaring intent of MassiveRead."); - db.declareIntent(new OIntentMassiveRead()); - } else if (intent.equals(ORIENTDB_NOCACHE)) { - LOG.info("Declaring intent of NoCache."); - db.declareIntent(new OIntentNoCache()); - } + OPartitionedDatabasePool getDatabasePool() { + return databasePool; } @Override public void cleanup() throws DBException { - // Set this thread's db reference (needed for thread safety in testing) - ODatabaseRecordThreadLocal.INSTANCE.set(db); + INIT_LOCK.lock(); + try { + clientCounter--; + if (clientCounter == 0) { + databasePool.close(); + } - if (db != null) { - db.close(); - db = null; + databasePool = null; + initialized = false; + } finally { + INIT_LOCK.unlock(); } + } @Override public Status insert(String table, String key, HashMap<String, ByteIterator> values) { - try { + try (ODatabaseDocumentTx db = databasePool.acquire()) { final ODocument document = new ODocument(CLASS); - for (Entry<String, String> entry : StringByteIterator.getStringMap(values).entrySet()) { + + for (Map.Entry<String, String> entry : StringByteIterator.getStringMap(values).entrySet()) { document.field(entry.getKey(), entry.getValue()); } + document.save(); + final ODictionary<ORecord> dictionary = db.getMetadata().getIndexManager().getDictionary(); dictionary.put(key, document); return Status.OK; @@ -219,18 +213,24 @@ public class OrientDBClient extends DB { @Override public Status delete(String table, String key) { - try { - dictionary.remove(key); - return Status.OK; - } catch (Exception e) { - e.printStackTrace(); + while (true) { + try (ODatabaseDocumentTx db = databasePool.acquire()) { + final ODictionary<ORecord> dictionary = db.getMetadata().getIndexManager().getDictionary(); + dictionary.remove(key); + return Status.OK; + } catch (OConcurrentModificationException cme) { + continue; + } catch (Exception e) { + e.printStackTrace(); + return Status.ERROR; + } } - return Status.ERROR; } @Override public Status read(String table, String key, Set<String> fields, HashMap<String, ByteIterator> result) { - try { + try (ODatabaseDocumentTx db = databasePool.acquire()) { + final ODictionary<ORecord> dictionary = db.getMetadata().getIndexManager().getDictionary(); final ODocument document = dictionary.get(key); if (document != null) { if (fields != null) { @@ -252,48 +252,63 @@ public class OrientDBClient extends DB { @Override public Status update(String table, String key, HashMap<String, ByteIterator> values) { - try { - final ODocument document = dictionary.get(key); - if (document != null) { - for (Entry<String, String> entry : StringByteIterator.getStringMap(values).entrySet()) { - document.field(entry.getKey(), entry.getValue()); + while (true) { + try (ODatabaseDocumentTx db = databasePool.acquire()) { + final ODictionary<ORecord> dictionary = db.getMetadata().getIndexManager().getDictionary(); + final ODocument document = dictionary.get(key); + if (document != null) { + for (Map.Entry<String, String> entry : StringByteIterator.getStringMap(values).entrySet()) { + document.field(entry.getKey(), entry.getValue()); + } + + document.save(); + return Status.OK; } - document.save(); - return Status.OK; + } catch (OConcurrentModificationException cme) { + continue; + } catch (Exception e) { + e.printStackTrace(); + return Status.ERROR; } - } catch (Exception e) { - e.printStackTrace(); } - return Status.ERROR; } @Override public Status scan(String table, String startkey, int recordcount, Set<String> fields, - Vector<HashMap<String, ByteIterator>> result) { + Vector<HashMap<String, ByteIterator>> result) { + if (isRemote) { // Iterator methods needed for scanning are Unsupported for remote database connections. LOG.warn("OrientDB scan operation is not implemented for remote database connections."); return Status.NOT_IMPLEMENTED; } - try { - int entrycount = 0; + try (ODatabaseDocumentTx db = databasePool.acquire()) { + final ODictionary<ORecord> dictionary = db.getMetadata().getIndexManager().getDictionary(); final OIndexCursor entries = dictionary.getIndex().iterateEntriesMajor(startkey, true, true); - while (entries.hasNext() && entrycount < recordcount) { - final OIdentifiable entry = entries.next(); - final ODocument document = entry.getRecord(); + int currentCount = 0; + while (entries.hasNext()) { + final ODocument document = entries.next().getRecord(); - final HashMap<String, ByteIterator> map = new HashMap<String, ByteIterator>(); + final HashMap<String, ByteIterator> map = new HashMap<>(); result.add(map); - if (fields != null && !fields.isEmpty()) { + if (fields != null) { for (String field : fields) { map.put(field, new StringByteIterator((String) document.field(field))); } + } else { + for (String field : document.fieldNames()) { + map.put(field, new StringByteIterator((String) document.field(field))); + } } - entrycount++; + currentCount++; + + if (currentCount >= recordcount) { + break; + } } return Status.OK; @@ -302,11 +317,4 @@ public class OrientDBClient extends DB { } return Status.ERROR; } - - /** - * Access method to db variable for unit testing. - **/ - ODatabaseDocumentTx getDB() { - return db; - } } diff --git a/orientdb/src/test/java/com/yahoo/ycsb/db/OrientDBClientTest.java b/orientdb/src/test/java/com/yahoo/ycsb/db/OrientDBClientTest.java index 140a9773..d72607cc 100644 --- a/orientdb/src/test/java/com/yahoo/ycsb/db/OrientDBClientTest.java +++ b/orientdb/src/test/java/com/yahoo/ycsb/db/OrientDBClientTest.java @@ -17,6 +17,8 @@ package com.yahoo.ycsb.db; +import com.orientechnologies.orient.core.db.OPartitionedDatabasePool; +import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; import com.orientechnologies.orient.core.dictionary.ODictionary; import com.orientechnologies.orient.core.record.ORecord; import com.orientechnologies.orient.core.record.impl.ODocument; @@ -25,6 +27,7 @@ import com.yahoo.ycsb.DBException; import com.yahoo.ycsb.StringByteIterator; import org.junit.*; + import java.util.*; import static org.junit.Assert.*; @@ -34,14 +37,13 @@ import static org.junit.Assert.*; */ public class OrientDBClientTest { // TODO: This must be copied because it is private in OrientDBClient, but this should defer to table property. - private static final String CLASS = "usertable"; - private static final int FIELD_LENGTH = 32; + private static final String CLASS = "usertable"; + private static final int FIELD_LENGTH = 32; private static final String FIELD_PREFIX = "FIELD"; - private static final String KEY_PREFIX = "user"; - private static final int NUM_FIELDS = 3; - private static final String TEST_DB_URL = "memory:test"; + private static final String KEY_PREFIX = "user"; + private static final int NUM_FIELDS = 3; + private static final String TEST_DB_URL = "memory:test"; - private static ODictionary<ORecord> orientDBDictionary; private static OrientDBClient orientDBClient = null; @Before @@ -54,7 +56,6 @@ public class OrientDBClientTest { orientDBClient.setProperties(p); orientDBClient.init(); - orientDBDictionary = orientDBClient.getDB().getDictionary(); } @After @@ -101,12 +102,17 @@ public class OrientDBClientTest { String insertKey = "user0"; Map<String, ByteIterator> insertMap = insertRow(insertKey); - ODocument result = orientDBDictionary.get(insertKey); + OPartitionedDatabasePool pool = orientDBClient.getDatabasePool(); + try(ODatabaseDocumentTx db = pool.acquire()) { + ODictionary<ORecord> dictionary = db.getDictionary(); + ODocument result = dictionary.get(insertKey); - assertTrue("Assert a row was inserted.", result != null); + assertTrue("Assert a row was inserted.", result != null); - for (int i = 0; i < NUM_FIELDS; i++) { - assertEquals("Assert all inserted columns have correct values.", result.field(FIELD_PREFIX + i), insertMap.get(FIELD_PREFIX + i).toString()); + for (int i = 0; i < NUM_FIELDS; i++) { + assertEquals("Assert all inserted columns have correct values.", result.field(FIELD_PREFIX + i), + insertMap.get(FIELD_PREFIX + i).toString()); + } } } @@ -117,14 +123,19 @@ public class OrientDBClientTest { String user1 = "user1"; String user2 = "user2"; - // Manually insert three documents - for(String key: Arrays.asList(user0, user1, user2)) { - ODocument doc = new ODocument(CLASS); - for (int i = 0; i < NUM_FIELDS; i++) { - doc.field(FIELD_PREFIX + i, preupdateString); + OPartitionedDatabasePool pool = orientDBClient.getDatabasePool(); + try(ODatabaseDocumentTx db = pool.acquire()) { + // Manually insert three documents + for (String key : Arrays.asList(user0, user1, user2)) { + ODocument doc = new ODocument(CLASS); + for (int i = 0; i < NUM_FIELDS; i++) { + doc.field(FIELD_PREFIX + i, preupdateString); + } + doc.save(); + + ODictionary<ORecord> dictionary = db.getDictionary(); + dictionary.put(key, doc); } - doc.save(); - orientDBDictionary.put(key, doc); } HashMap<String, ByteIterator> updateMap = new HashMap<>(); @@ -134,22 +145,26 @@ public class OrientDBClientTest { orientDBClient.update(CLASS, user1, updateMap); - // Ensure that user0 record was not changed - ODocument result = orientDBDictionary.get(user0); - for (int i = 0; i < NUM_FIELDS; i++) { - assertEquals("Assert first row fields contain preupdateString", result.field(FIELD_PREFIX + i), preupdateString); - } + try(ODatabaseDocumentTx db = pool.acquire()) { + ODictionary<ORecord> dictionary = db.getDictionary(); + // Ensure that user0 record was not changed + ODocument result = dictionary.get(user0); + for (int i = 0; i < NUM_FIELDS; i++) { + assertEquals("Assert first row fields contain preupdateString", result.field(FIELD_PREFIX + i), preupdateString); + } - // Check that all the columns have expected values for user1 record - result = orientDBDictionary.get(user1); - for (int i = 0; i < NUM_FIELDS; i++) { - assertEquals("Assert updated row fields are correct", result.field(FIELD_PREFIX + i), updateMap.get(FIELD_PREFIX + i).toString()); - } + // Check that all the columns have expected values for user1 record + result = dictionary.get(user1); + for (int i = 0; i < NUM_FIELDS; i++) { + assertEquals("Assert updated row fields are correct", result.field(FIELD_PREFIX + i), + updateMap.get(FIELD_PREFIX + i).toString()); + } - // Ensure that user2 record was not changed - result = orientDBDictionary.get(user2); - for (int i = 0; i < NUM_FIELDS; i++) { - assertEquals("Assert third row fields contain preupdateString", result.field(FIELD_PREFIX + i), preupdateString); + // Ensure that user2 record was not changed + result = dictionary.get(user2); + for (int i = 0; i < NUM_FIELDS; i++) { + assertEquals("Assert third row fields contain preupdateString", result.field(FIELD_PREFIX + i), preupdateString); + } } } @@ -164,7 +179,7 @@ public class OrientDBClientTest { readFields.add("FIELD0"); orientDBClient.read(CLASS, insertKey, readFields, readResultMap); assertEquals("Assert that result has correct number of fields", readFields.size(), readResultMap.size()); - for (String field: readFields) { + for (String field : readFields) { assertEquals("Assert " + field + " was read correctly", insertMap.get(field).toString(), readResultMap.get(field).toString()); } @@ -175,7 +190,7 @@ public class OrientDBClientTest { readFields.add("FIELD2"); orientDBClient.read(CLASS, insertKey, readFields, readResultMap); assertEquals("Assert that result has correct number of fields", readFields.size(), readResultMap.size()); - for (String field: readFields) { + for (String field : readFields) { assertEquals("Assert " + field + " was read correctly", insertMap.get(field).toString(), readResultMap.get(field).toString()); } } @@ -192,9 +207,14 @@ public class OrientDBClientTest { orientDBClient.delete(CLASS, user1); - assertNotNull("Assert user0 still exists", orientDBDictionary.get(user0)); - assertNull("Assert user1 does not exist", orientDBDictionary.get(user1)); - assertNotNull("Assert user2 still exists", orientDBDictionary.get(user2)); + OPartitionedDatabasePool pool = orientDBClient.getDatabasePool(); + try(ODatabaseDocumentTx db = pool.acquire()) { + ODictionary<ORecord> dictionary = db.getDictionary(); + + assertNotNull("Assert user0 still exists", dictionary.get(user0)); + assertNull("Assert user1 does not exist", dictionary.get(user1)); + assertNotNull("Assert user2 still exists", dictionary.get(user2)); + } } @Test @@ -208,7 +228,7 @@ public class OrientDBClientTest { Set<String> fieldSet = new HashSet<>(); fieldSet.add("FIELD0"); fieldSet.add("FIELD1"); - int startIndex = 1; + int startIndex = 0; int resultRows = 3; Vector<HashMap<String, ByteIterator>> resultVector = new Vector<>(); @@ -217,20 +237,14 @@ public class OrientDBClientTest { // Check the resultVector is the correct size assertEquals("Assert the correct number of results rows were returned", resultRows, resultVector.size()); - /** - * Part of the known issue about the broken iterator in orientdb is that the iterator - * starts at index 1 instead of index 0. Because of this, to test it we must increment - * the start index. When that known issue has been fixed, remove the increment below. - * Track the issue here: https://github.com/orientechnologies/orientdb/issues/5541 - * This fix was implemented for orientechnologies:orientdb-client:2.1.8 - */ int testIndex = startIndex; // Check each vector row to make sure we have the correct fields - for (HashMap<String, ByteIterator> result: resultVector) { + for (HashMap<String, ByteIterator> result : resultVector) { assertEquals("Assert that this row has the correct number of fields", fieldSet.size(), result.size()); - for (String field: fieldSet) { - assertEquals("Assert this field is correct in this row", keyMap.get(KEY_PREFIX + testIndex).get(field).toString(), result.get(field).toString()); + for (String field : fieldSet) { + assertEquals("Assert this field is correct in this row", keyMap.get(KEY_PREFIX + testIndex).get(field).toString(), + result.get(field).toString()); } testIndex++; } diff --git a/pom.xml b/pom.xml index 585bf584..9a49531f 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ LICENSE file. <!--<mapkeeper.version>1.0</mapkeeper.version>--> <mongodb.version>3.0.3</mongodb.version> <mongodb.async.version>2.0.1</mongodb.async.version> - <orientdb.version>2.1.8</orientdb.version> + <orientdb.version>2.2.10</orientdb.version> <redis.version>2.0.0</redis.version> <s3.version>1.10.20</s3.version> <voldemort.version>0.81</voldemort.version> -- GitLab