/* * Copyright (c) 2017 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller.impl.utils; import java.net.URI; import java.util.Collection; import java.util.List; import com.emc.storageos.db.client.DbClient; import com.emc.storageos.db.client.impl.DbClientImpl; import com.emc.storageos.db.client.model.DataObject; /** * This class should be used instead of DbClient if activity is expected to query DB for the same set of objects. * This class is NOT thread safe. The cache should be local with a scope of a single thread. * An example where it is appropriate might be in matching and placement activities run by apisvc and also, to a lesser extend by * controllers. * Activities are moved through a net of methods where each method is likely to query DB for the same set of objects. * To avoid OOM, the cache contains SoftReferences to cached DataObjects. Java's GC guarantees to clear them before JVM * can go OOM. * Cache is not kept in sync with DB. Any update to the database is not visible to the cache. * Use methods * clearCache(URI cached) * or * refresh (Class<T> clazz, URI id) * to eliminate stale objects from the cache. * * This version of the local cache extends DbClientImpl so that all methods of DbClient are valid. Only these methods will result in * caching of the returned objects: * queryObject(clazz, id) * queryObject(clazz, ids) */ public class DbClientObjectLocalCache extends DbClientImpl { private DbClient dbClientCache; private ObjectLocalCache cache; public void init() { if (cache == null) { this.start(); cache = new ObjectLocalCache(dbClientCache, true); } else { throw new IllegalStateException(); } } public void setMaxHashSize(int max) { if (cache == null) { throw new IllegalStateException(); } this.cache.setMaxHashSize(max); } public int getMaxHashSize() { if (cache == null) { throw new IllegalStateException(); } return this.cache.getMaxHashSize(); } /** * @param enabled the enabled to set */ public void setEnabled(boolean enabled) { if (cache == null) { throw new IllegalStateException(); } this.cache.setEnable(enabled); } public boolean getEnabled() { if (cache == null) { throw new IllegalStateException(); } return this.cache.getEnabled(); } @Override public <T extends DataObject> T queryObject(Class<T> clazz, URI id) { if (cache == null) { throw new IllegalStateException(); } return cache.queryObject(clazz, id); } @Override public <T extends DataObject> List<T> queryObject(Class<T> clazz, Collection<URI> ids) { if (cache == null) { throw new IllegalStateException(); } return cache.queryObject(clazz, ids); } public void clearCache() { if (cache == null) { throw new IllegalStateException(); } this.cache.clearCache(); } public void clearCache(URI cached) { if (cache == null) { throw new IllegalStateException(); } this.cache.clearCache(cached); } public <T extends DataObject> T refresh(Class<T> clazz, URI id) { if (cache == null) { throw new IllegalStateException(); } return this.cache.refresh(clazz, id); } /** * @param dbClientCache the dbClientCache to set */ public void setDbClientCache(DbClient dbClientCache) { this.dbClientCache = dbClientCache; } }