diff --git a/engine/src/main/java/com/arcadedb/GlobalConfiguration.java b/engine/src/main/java/com/arcadedb/GlobalConfiguration.java index 484c57121..a6ab4cebf 100644 --- a/engine/src/main/java/com/arcadedb/GlobalConfiguration.java +++ b/engine/src/main/java/com/arcadedb/GlobalConfiguration.java @@ -125,7 +125,7 @@ public Object call(final Object value) { }, null, Set.of("default", "high-performance", "low-ram", "low-cpu")), TEST("arcadedb.test", SCOPE.JVM, - "Tells if it is running in test mode. This enables the calling of callbacks for testing purpose ", Boolean.class, false), + "Tells if it is running in test mode. This enables the calling of callbacks for testing purpose", Boolean.class, false), MAX_PAGE_RAM("arcadedb.maxPageRAM", SCOPE.DATABASE, "Maximum amount of pages (in MB) to keep in RAM", Long.class, 4 * 1024, // 4GB new Callable<>() { @@ -235,6 +235,10 @@ public Object call(final Object value) { "Maximum amount of milliseconds to compute a random number to wait for the next retry. This setting is helpful in case of high concurrency on the same pages (multi-thread insertion over the same bucket)", Integer.class, 100), + BACKUP_ENABLED("arcadedb.backup.enabled", SCOPE.DATABASE, + "Allow a database to be backup. Disabling backup gives a huge boost in performance because no lock will be used for every operations", + Boolean.class, true), + // SQL SQL_STATEMENT_CACHE("arcadedb.sqlStatementCache", SCOPE.DATABASE, "Maximum number of parsed statements to keep in cache", Integer.class, 300), diff --git a/engine/src/main/java/com/arcadedb/database/LocalDatabase.java b/engine/src/main/java/com/arcadedb/database/LocalDatabase.java index c5c2d65c4..ce8b1f10f 100644 --- a/engine/src/main/java/com/arcadedb/database/LocalDatabase.java +++ b/engine/src/main/java/com/arcadedb/database/LocalDatabase.java @@ -1409,7 +1409,7 @@ public SecurityManager getSecurity() { */ @Override public RET executeInReadLock(final Callable callable) { - final ReentrantReadWriteLock.ReadLock stamp = readLock(); + final ReentrantReadWriteLock.ReadLock readLock = readLock(); try { return callable.call(); @@ -1426,7 +1426,7 @@ public RET executeInReadLock(final Callable callable) { throw new DatabaseOperationException("Error during read lock", e); } finally { - readUnlock(stamp); + readUnlock(readLock); } } @@ -1435,7 +1435,7 @@ public RET executeInReadLock(final Callable callable) { */ @Override public RET executeInWriteLock(final Callable callable) { - final ReentrantReadWriteLock.WriteLock stamp = writeLock(); + final ReentrantReadWriteLock.WriteLock writeLock = writeLock(); try { return callable.call(); @@ -1452,7 +1452,7 @@ public RET executeInWriteLock(final Callable callable) { throw new DatabaseOperationException("Error during write lock", e); } finally { - writeUnlock(stamp); + writeUnlock(writeLock); } } @@ -1772,6 +1772,7 @@ private void checkForRecovery() throws IOException { private void openInternal() { try { DatabaseContext.INSTANCE.init(this); + setLockingEnabled(configuration.getValueAsBoolean(GlobalConfiguration.BACKUP_ENABLED)); fileManager = new FileManager(databasePath, mode, SUPPORTED_FILE_EXT); transactionManager = new TransactionManager(wrappedDatabaseInstance); @@ -1854,4 +1855,5 @@ private void delayBetweenRetries(final int retryDelay) { } } } + } diff --git a/engine/src/main/java/com/arcadedb/utility/RWLockContext.java b/engine/src/main/java/com/arcadedb/utility/RWLockContext.java index 886b7a993..3e7348120 100644 --- a/engine/src/main/java/com/arcadedb/utility/RWLockContext.java +++ b/engine/src/main/java/com/arcadedb/utility/RWLockContext.java @@ -24,9 +24,13 @@ import java.util.concurrent.locks.*; public class RWLockContext { - private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); + private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); + private boolean enableLocking = true; protected ReentrantReadWriteLock.ReadLock readLock() { + if (!enableLocking) + return null; + final ReentrantReadWriteLock.ReadLock rl = lock.readLock(); rl.lock(); return rl; @@ -38,6 +42,9 @@ protected void readUnlock(final ReentrantReadWriteLock.ReadLock rl) { } protected ReentrantReadWriteLock.WriteLock writeLock() { + if (!enableLocking) + return null; + final ReentrantReadWriteLock.WriteLock wl = lock.writeLock(); wl.lock(); return wl; @@ -87,4 +94,12 @@ public RET executeInWriteLock(final Callable callable) { writeUnlock(wl); } } + + protected void setLockingEnabled(final boolean enabled) { + this.enableLocking = enabled; + } + + protected boolean isLockingEnabled() { + return enableLocking; + } } diff --git a/engine/src/test/java/performance/LocalDatabaseBenchmark.java b/engine/src/test/java/performance/LocalDatabaseBenchmark.java index 84702f013..77665ac9f 100644 --- a/engine/src/test/java/performance/LocalDatabaseBenchmark.java +++ b/engine/src/test/java/performance/LocalDatabaseBenchmark.java @@ -62,9 +62,11 @@ public static void main(String[] args) { private void endTest() { database.close(); + GlobalConfiguration.resetAll(); } private void beginTest() { + GlobalConfiguration.BACKUP_ENABLED.setValue(false); if (new DatabaseFactory(DATABASE_NAME).exists()) new DatabaseFactory(DATABASE_NAME).open().drop(); database = new DatabaseFactory(DATABASE_NAME).create(); @@ -153,8 +155,8 @@ private void querySQL() { long begin = System.currentTimeMillis(); for (int i = 0; i < TOTAL * CONCURRENT_THREADS; i++) { assertThat(database.query("sql", - "select from User where id = ? and id = ? and id = ? and id = ? and id = ? and id = ? and id = ? and id = ? and id = ? and id = ?", - i, i, i, i, i, i, i, i, i, i).toVertices().size()).isEqualTo(1); + "select from User where id = ? and id = ? and id = ? and id = ? and id = ? and id = ? and id = ? and id = ? and id = ? and id = ?", + i, i, i, i, i, i, i, i, i, i).toVertices().size()).isEqualTo(1); } System.out.println("SQL " + (System.currentTimeMillis() - begin) + "ms"); }