diff --git a/src/main/java/com/iota/iri/controllers/ApproveeViewModel.java b/src/main/java/com/iota/iri/controllers/ApproveeViewModel.java index cb69d1def0..9be7552d0c 100644 --- a/src/main/java/com/iota/iri/controllers/ApproveeViewModel.java +++ b/src/main/java/com/iota/iri/controllers/ApproveeViewModel.java @@ -97,6 +97,9 @@ public static ApproveeViewModel first(Tangle tangle) throws Exception { @Override public boolean store(Tangle tangle) throws Exception { Cache cache = tangle.getCache(ApproveeViewModel.class); + if (cache == null) { + return true; + } ApproveeViewModel approveeViewModel = cache.get(hash); if (approveeViewModel != null) { return true; @@ -151,10 +154,12 @@ public ApproveeViewModel next(Tangle tangle) throws Exception { */ public static void cachePut(Tangle tangle, ApproveeViewModel approveeViewModel, Indexable hash) throws Exception { Cache cache = tangle.getCache(ApproveeViewModel.class); - if (cache.getSize() == cache.getConfiguration().getMaxSize()) { - cacheEvict(tangle); + if (cache != null) { + if (cache.getSize() == cache.getConfiguration().getMaxSize()) { + cacheEvict(tangle); + } + cache.put(hash, approveeViewModel); } - cache.put(hash, approveeViewModel); } /** @@ -164,7 +169,10 @@ public static void cachePut(Tangle tangle, ApproveeViewModel approveeViewModel, * @param hash Hash of item to evict */ public static void cacheDelete(Tangle tangle, Indexable hash) { - tangle.getCache(ApproveeViewModel.class).evict(hash); + Cache cache = tangle.getCache(ApproveeViewModel.class); + if (cache != null) { + cache.evict(hash); + } } /** @@ -175,6 +183,9 @@ public static void cacheDelete(Tangle tangle, Indexable hash) { */ public static void cacheEvict(Tangle tangle) throws Exception { Cache cache = tangle.getCache(ApproveeViewModel.class); + if (cache == null) { + return; + } for (int i = 0; i < cache.getConfiguration().getEvictionCount(); i++) { Indexable hash = cache.nextEvictionKey(); if (hash != null) { diff --git a/src/main/java/com/iota/iri/controllers/TransactionViewModel.java b/src/main/java/com/iota/iri/controllers/TransactionViewModel.java index 0471685017..083e53a9a3 100644 --- a/src/main/java/com/iota/iri/controllers/TransactionViewModel.java +++ b/src/main/java/com/iota/iri/controllers/TransactionViewModel.java @@ -236,7 +236,11 @@ public static boolean mightExist(Tangle tangle, Hash hash) throws Exception { * @throws Exception Thrown if there is an error determining if the transaction exists or not */ public static boolean exists(Tangle tangle, Hash hash) throws Exception { - return tangle.getCache(TransactionViewModel.class).get(hash) != null || tangle.exists(Transaction.class, hash); + Cache cache = tangle.getCache(TransactionViewModel.class); + if (cache != null) { + return cache.get(hash) != null || tangle.exists(Transaction.class, hash); + } + return tangle.exists(Transaction.class, hash); } /** @@ -310,7 +314,13 @@ public void update(Tangle tangle, Snapshot initialSnapshot, String item) throws return; } - TransactionViewModel cachedTvm = tangle.getCache(TransactionViewModel.class).get(hash); + Cache cache = tangle.getCache(TransactionViewModel.class); + if (cache == null) { + updateDB(tangle, transaction, hash, item); + return; + } + + TransactionViewModel cachedTvm = cache.get(hash); if (cachedTvm != null) { this.isCacheEntryFresh = false; } @@ -442,8 +452,12 @@ public boolean store(Tangle tangle, Snapshot initialSnapshot) throws Exception { // non-cached operations. List> batch = getSaveBatch(); cacheApprovees(tangle); - if (tangle.getCache(TransactionViewModel.class).get(hash) == null) { - cachePut(tangle, this, hash); + + Cache cache = tangle.getCache(TransactionViewModel.class); + if (cache != null) { + if (cache.get(hash) == null) { + cachePut(tangle, this, hash); + } } if (tangle.exists(Transaction.class, hash)) { @@ -455,6 +469,9 @@ public boolean store(Tangle tangle, Snapshot initialSnapshot) throws Exception { private void cacheApprovees(Tangle tangle) throws Exception { Cache approveeViewModelCache = tangle.getCache(ApproveeViewModel.class); + if (approveeViewModelCache == null) { + return; + } ApproveeViewModel branchViewModel = ApproveeViewModel.load(tangle, getBranchTransactionHash()); branchViewModel.addHash(hash); approveeViewModelCache.put(getBranchTransactionHash(), branchViewModel); @@ -976,6 +993,9 @@ public String toString() { */ private static void cachePut(Tangle tangle, TransactionViewModel transactionViewModel, Hash hash) throws Exception { Cache cache = tangle.getCache(TransactionViewModel.class); + if (cache == null) { + return; + } if (cache.getSize() == cache.getConfiguration().getMaxSize()) { cacheEvict(tangle); } @@ -989,6 +1009,9 @@ private static void cachePut(Tangle tangle, TransactionViewModel transactionView */ public static void cacheEvict(Tangle tangle) throws Exception { Cache cache = tangle.getCache(TransactionViewModel.class); + if (cache == null) { + return; + } for (int i = 0; i < cache.getConfiguration().getEvictionCount(); i++) { Indexable hash = cache.nextEvictionKey(); if (hash != null) { @@ -1009,7 +1032,10 @@ public static void cacheEvict(Tangle tangle) throws Exception { * @param hash hash to evict */ private static void cacheDelete(Tangle tangle, Hash hash) { - tangle.getCache(TransactionViewModel.class).evict(hash); + Cache cache = tangle.getCache(TransactionViewModel.class); + if (cache != null) { + cache.evict(hash); + } } /** diff --git a/src/main/java/com/iota/iri/storage/Tangle.java b/src/main/java/com/iota/iri/storage/Tangle.java index aa811df9b5..6895ec3790 100644 --- a/src/main/java/com/iota/iri/storage/Tangle.java +++ b/src/main/java/com/iota/iri/storage/Tangle.java @@ -8,26 +8,13 @@ import com.iota.iri.controllers.TransactionViewModel; import com.iota.iri.model.Hash; import com.iota.iri.model.StateDiff; -import com.iota.iri.model.persistables.Address; -import com.iota.iri.model.persistables.Approvee; -import com.iota.iri.model.persistables.Bundle; -import com.iota.iri.model.persistables.Milestone; -import com.iota.iri.model.persistables.ObsoleteTag; -import com.iota.iri.model.persistables.Tag; -import com.iota.iri.model.persistables.Transaction; +import com.iota.iri.model.persistables.*; import com.iota.iri.utils.Pair; import com.iota.iri.zmq.MessageQueueProvider; import javax.naming.OperationNotSupportedException; -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -58,6 +45,7 @@ public class Tangle { private final List persistenceProviders = new ArrayList<>(); private final List messageQueueProviders = new ArrayList<>(); private CacheManager cacheManager; + private boolean isCacheEnabled = true; public void addPersistenceProvider(PersistenceProvider provider) { this.persistenceProviders.add(provider); @@ -398,7 +386,28 @@ public void clearMetadata(Class column) throws Exception { * @return The cache with the specified type */ public Cache getCache(Class type){ - return getCacheManager().getCache(type); + if (!isCacheEnabled) { + return null; + } + return getCacheManager().getCache(type); + } + + /** + * Gets if caching is enabled or not. + * + * @return True if caching is enabled. Else, returns false. + */ + public boolean isCacheEnabled() { + return isCacheEnabled; + } + + /** + * Sets caching on or off. + * + * @param cacheEnabled The value to set. + */ + public void setCacheEnabled(boolean cacheEnabled) { + isCacheEnabled = cacheEnabled; } /** diff --git a/src/test/java/com/iota/iri/service/tipselection/impl/WalkValidatorImplTest.java b/src/test/java/com/iota/iri/service/tipselection/impl/WalkValidatorImplTest.java index 36d2cca2b9..b624516d97 100644 --- a/src/test/java/com/iota/iri/service/tipselection/impl/WalkValidatorImplTest.java +++ b/src/test/java/com/iota/iri/service/tipselection/impl/WalkValidatorImplTest.java @@ -1,6 +1,7 @@ package com.iota.iri.service.tipselection.impl; import com.iota.iri.TransactionTestUtils; +import com.iota.iri.cache.Cache; import com.iota.iri.conf.MainnetConfig; import com.iota.iri.conf.TipSelConfig; import com.iota.iri.controllers.TransactionViewModel; @@ -8,26 +9,22 @@ import com.iota.iri.service.ledger.LedgerService; import com.iota.iri.service.snapshot.SnapshotProvider; import com.iota.iri.service.snapshot.impl.SnapshotMockUtils; +import com.iota.iri.storage.Indexable; import com.iota.iri.storage.Tangle; import com.iota.iri.storage.rocksDB.RocksDBPersistenceProvider; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; + +import java.util.HashMap; +import java.util.HashSet; + +import org.junit.*; import org.junit.rules.TemporaryFolder; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; -import static com.iota.iri.TransactionTestUtils.getTransactionTritsWithTrunkAndBranch; import static com.iota.iri.TransactionTestUtils.getTransactionHash; - -import java.util.HashMap; -import java.util.HashSet; +import static com.iota.iri.TransactionTestUtils.getTransactionTritsWithTrunkAndBranch; public class WalkValidatorImplTest { @@ -54,7 +51,10 @@ public static void tearDown() throws Exception { @After public void clearCache(){ - tangle.getCache(TransactionViewModel.class).clear(); + Cache cache = tangle.getCache(TransactionViewModel.class); + if (cache != null) { + cache.clear(); + } } @BeforeClass