src.net.sf.ehcache.constructs.blocking.BlockingCache Maven / Gradle / Ivy
/**
* Copyright 2003-2006 Greg Luck
*
* 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.
*/
package net.sf.ehcache.constructs.blocking;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import net.sf.ehcache.Statistics;
import net.sf.ehcache.Status;
import net.sf.ehcache.bootstrap.BootstrapCacheLoader;
import net.sf.ehcache.constructs.concurrent.ConcurrencyUtil;
import net.sf.ehcache.constructs.concurrent.Mutex;
import net.sf.ehcache.event.RegisteredEventListeners;
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.Serializable;
import java.util.List;
/**
* A blocking decorator for an Ehcache, backed by a {@link Ehcache}.
*
* It allows concurrent read access to elements already in the cache. If the element is null, other
* reads will block until an element with the same key is put into the cache.
*
* This is useful for constructing read-through or self-populating caches.
*
* This implementation uses the {@link Mutex} class from Doug Lea's concurrency package. If you wish to use
* this class, you will need the concurrent package in your class path.
*
* It features:
*
* - Excellent liveness.
*
- Fine-grained locking on each element, rather than the cache as a whole.
*
- Scalability to a large number of threads.
*
*
* This class has been updated to use Lock striping. The Mutex implementation gives scalability but creates
* many Mutex objects of 24 bytes each. Lock striping limits their number to 100.
*
* A version of this class is planned which will dynamically use JDK5's concurrency package, which is
* based on Doug Lea's, so as to avoid a dependency on his package for JDK5 systems. This will not
* be implemented until JDK5 is released on MacOSX and Linux, as JDK5 will be required to compile
* it, though any version from JDK1.2 up will be able to run the code, falling back to Doug
* Lea's concurrency package, if the JDK5 package is not found in the classpath.
*
* The Mutex
class does not appear in the JDK5 concurrency package. Doug Lea has
* generously offered the following advice:
*
* "You should just be able to use ReentrantLock here. We supply
* ReentrantLock, but not Mutex because the number of cases where a
* non-reentrant mutex is preferable is small, and most people are more
* familiar with reentrant seamantics. If you really need a non-reentrant
* one, the javadocs for class AbstractQueuedSynchronizer include sample
* code for them."
*
* -Doug
*
* "Hashtable / synchronizedMap uses the "one big fat lock" approach to guard the mutable state of the map.
* That works, but is a big concurrency bottleneck, as you've observed. You went to the opposite extreme, one lock per key.
* That works (as long as you've got sufficient synchronization in the cache itself to protect its own data structures.)
*
* Lock striping is a middle ground, partitioning keys into a fixed number of subsets, like the trick used at large
* theaters for will-call ticket pickup -- there are separate lines for "A-F, G-M, N-R, and S-Z".
* This way, there are a fixed number of locks, each guarding (hopefully) 1/Nth of the keys."
* - Brian Goetz
*
* Further improvements to hashing suggested by Joe Bowbeer.
*
* @author Greg Luck
* @version $Id: BlockingCache.java 187 2006-09-02 01:54:40Z gregluck $
*/
public class BlockingCache implements Ehcache {
/**
* The default number of locks to use. Must be a power of 2
*/
public static final int LOCK_NUMBER = 2048;
private static final Log LOG = LogFactory.getLog(BlockingCache.class.getName());
/**
* Based on the lock striping concept from Brian Goetz. See Java Concurrency in Practice 11.4.3
*/
protected final Mutex[] locks = new Mutex[LOCK_NUMBER];
{
for (int i = 0; i < LOCK_NUMBER; i++) {
locks[i] = new Mutex();
}
}
/**
* The backing Cache
*/
protected final Ehcache cache;
/**
* The amount of time to block a thread before a LockTimeoutException is thrown
*/
protected int timeoutMillis;
/**
* Creates a BlockingCache which decorates the supplied cache.
*
* @param cache a backing ehcache.
* @throws CacheException
* @since 1.2
*/
public BlockingCache(final Ehcache cache) throws CacheException {
this.cache = cache;
}
/**
* Retrieve the EHCache backing cache
*/
protected Ehcache getCache() {
return cache;
}
/**
* Returns this cache's name
*/
public String getName() {
return cache.getName();
}
/**
* Sets the cache name which will name.
*
* @param name the name of the cache. Should not be null.
*/
public void setName(String name) {
cache.setName(name);
}
/**
* Gets timeToIdleSeconds.
*/
public long getTimeToIdleSeconds() {
return cache.getTimeToIdleSeconds();
}
/**
* Gets timeToLiveSeconds.
*/
public long getTimeToLiveSeconds() {
return cache.getTimeToLiveSeconds();
}
/**
* Are elements eternal.
*/
public boolean isEternal() {
return cache.isEternal();
}
/**
* Does the overflow go to disk.
*/
public boolean isOverflowToDisk() {
return cache.isOverflowToDisk();
}
/**
* Gets the maximum number of elements to hold in memory.
*/
public int getMaxElementsInMemory() {
return cache.getMaxElementsInMemory();
}
/**
* The policy used to evict elements from the {@link net.sf.ehcache.store.MemoryStore}.
* This can be one of:
*
* - LRU - least recently used
*
- LFU - least frequently used
*
- FIFO - first in first out, the oldest element by creation time
*
* The default value is LRU
*
* @since 1.2
*/
public MemoryStoreEvictionPolicy getMemoryStoreEvictionPolicy() {
return cache.getMemoryStoreEvictionPolicy();
}
/**
* Checks whether this cache element has expired.
*
* The element is expired if:
*
* - the idle time is non-zero and has elapsed, unless the cache is eternal; or
*
- the time to live is non-zero and has elapsed, unless the cache is eternal; or
*
- the value of the element is null.
*
*
* @return true if it has expired
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
* @throws NullPointerException if the element is null
*/
public boolean isExpired(Element element) throws IllegalStateException, NullPointerException {
return cache.isExpired(element);
}
/**
* Clones a cache. This is only legal if the cache has not been
* initialized. At that point only primitives have been set and no
* {@link net.sf.ehcache.store.LruMemoryStore} or {@link net.sf.ehcache.store.DiskStore} has been created.
*
* A new, empty, RegisteredEventListeners is created on clone.
*
*
* @return an object of type {@link net.sf.ehcache.Cache}
* @throws CloneNotSupportedException
*/
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
/**
* @return true if the cache overflows to disk and the disk is persistent between restarts
*/
public boolean isDiskPersistent() {
return cache.isDiskPersistent();
}
/**
* @return the interval between runs
* of the expiry thread, where it checks the disk store for expired elements. It is not the
* the timeToLiveSeconds.
*/
public long getDiskExpiryThreadIntervalSeconds() {
return cache.getDiskExpiryThreadIntervalSeconds();
}
/**
* Use this to access the service in order to register and unregister listeners
*
* @return the RegisteredEventListeners instance for this cache.
*/
public RegisteredEventListeners getCacheEventNotificationService() {
return cache.getCacheEventNotificationService();
}
/**
* Whether an Element is stored in the cache in Memory, indicating a very low cost of retrieval.
*
* @return true if an element matching the key is found in memory
*/
public boolean isElementInMemory(Serializable key) {
return cache.isElementInMemory(key);
}
/**
* Whether an Element is stored in the cache in Memory, indicating a very low cost of retrieval.
*
* @return true if an element matching the key is found in memory
* @since 1.2
*/
public boolean isElementInMemory(Object key) {
return cache.isElementInMemory(key);
}
/**
* Whether an Element is stored in the cache on Disk, indicating a higher cost of retrieval.
*
* @return true if an element matching the key is found in the diskStore
*/
public boolean isElementOnDisk(Serializable key) {
return cache.isElementOnDisk(key);
}
/**
* Whether an Element is stored in the cache on Disk, indicating a higher cost of retrieval.
*
* @return true if an element matching the key is found in the diskStore
* @since 1.2
*/
public boolean isElementOnDisk(Object key) {
return cache.isElementOnDisk(key);
}
/**
* The GUID for this cache instance can be used to determine whether two cache instance references
* are pointing to the same cache.
*
* @return the globally unique identifier for this cache instance. This is guaranteed to be unique.
* @since 1.2
*/
public String getGuid() {
return cache.getGuid();
}
/**
* Gets the CacheManager managing this cache. For a newly created cache this will be null until
* it has been added to a CacheManager.
*
* @return the manager or null if there is none
*/
public CacheManager getCacheManager() {
return cache.getCacheManager();
}
/**
* Resets statistics counters back to 0.
*/
public void clearStatistics() {
cache.clearStatistics();
}
/**
* Accurately measuring statistics can be expensive. Returns the current accuracy setting.
*
* @return one of {@link net.sf.ehcache.Statistics#STATISTICS_ACCURACY_BEST_EFFORT}, {@link net.sf.ehcache.Statistics#STATISTICS_ACCURACY_GUARANTEED}, {@link net.sf.ehcache.Statistics#STATISTICS_ACCURACY_NONE}
*/
public int getStatisticsAccuracy() {
return cache.getStatisticsAccuracy();
}
/**
* Sets the statistics accuracy.
*
* @param statisticsAccuracy one of {@link net.sf.ehcache.Statistics#STATISTICS_ACCURACY_BEST_EFFORT}, {@link net.sf.ehcache.Statistics#STATISTICS_ACCURACY_GUARANTEED}, {@link net.sf.ehcache.Statistics#STATISTICS_ACCURACY_NONE}
*/
public void setStatisticsAccuracy(int statisticsAccuracy) {
cache.setStatisticsAccuracy(statisticsAccuracy);
}
/**
* Causes all elements stored in the Cache to be synchronously checked for expiry, and if expired, evicted.
*/
public void evictExpiredElements() {
cache.evictExpiredElements();
}
/**
* An inexpensive check to see if the key exists in the cache.
*
* @param key the key to check for
* @return true if an Element matching the key is found in the cache. No assertions are made about the state of the Element.
*/
public boolean isKeyInCache(Object key) {
return cache.isKeyInCache(key);
}
/**
* An extremely expensive check to see if the value exists in the cache.
*
* @param value to check for
* @return true if an Element matching the key is found in the cache. No assertions are made about the state of the Element.
*/
public boolean isValueInCache(Object value) {
return cache.isValueInCache(value);
}
/**
* Gets an immutable Statistics object representing the Cache statistics at the time. How the statistics are calculated
* depends on the statistics accuracy setting. The only aspect of statistics sensitive to the accuracy setting is
* object size. How that is calculated is discussed below.
* Best Effort Size
* This result is returned when the statistics accuracy setting is {@link net.sf.ehcache.Statistics#STATISTICS_ACCURACY_BEST_EFFORT}.
*
* The size is the number of {@link net.sf.ehcache.Element}s in the {@link net.sf.ehcache.store.MemoryStore} plus
* the number of {@link net.sf.ehcache.Element}s in the {@link net.sf.ehcache.store.DiskStore}.
*
* This number is the actual number of elements, including expired elements that have
* not been removed. Any duplicates between stores are accounted for.
*
* Expired elements are removed from the the memory store when
* getting an expired element, or when attempting to spool an expired element to
* disk.
*
* Expired elements are removed from the disk store when getting an expired element,
* or when the expiry thread runs, which is once every five minutes.
*
* Guaranteed Accuracy Size
* This result is returned when the statistics accuracy setting is {@link net.sf.ehcache.Statistics#STATISTICS_ACCURACY_GUARANTEED}.
*
* This method accounts for elements which might be expired or duplicated between stores. It take approximately
* 200ms per 1000 elements to execute.
* Fast but non-accurate Size
* This result is returned when the statistics accuracy setting is {@link net.sf.ehcache.Statistics#STATISTICS_ACCURACY_NONE}.
*
* The number given may contain expired elements. In addition if the DiskStore is used it may contain some double
* counting of elements. It takes 6ms for 1000 elements to execute. Time to execute is O(log n). 50,000 elements take
* 36ms.
*
* @return the number of elements in the ehcache, with a varying degree of accuracy, depending on accuracy setting.
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
*/
public Statistics getStatistics() throws IllegalStateException {
return cache.getStatistics();
}
/**
* Sets the CacheManager
*
* @param cacheManager
*/
public void setCacheManager(CacheManager cacheManager) {
cache.setCacheManager(cacheManager);
}
/**
* Accessor for the BootstrapCacheLoader associated with this cache. For testing purposes.
*/
public BootstrapCacheLoader getBootstrapCacheLoader() {
return cache.getBootstrapCacheLoader();
}
/**
* Sets the bootstrap cache loader.
*
* @param bootstrapCacheLoader the loader to be used
* @throws net.sf.ehcache.CacheException if this method is called after the cache is initialized
*/
public void setBootstrapCacheLoader(BootstrapCacheLoader bootstrapCacheLoader) throws CacheException {
cache.setBootstrapCacheLoader(bootstrapCacheLoader);
}
/**
* DiskStore paths can conflict between CacheManager instances. This method allows the path to be changed.
*
* @param diskStorePath the new path to be used.
* @throws net.sf.ehcache.CacheException if this method is called after the cache is initialized
*/
public void setDiskStorePath(String diskStorePath) throws CacheException {
cache.setDiskStorePath(diskStorePath);
}
/**
* Newly created caches do not have a {@link net.sf.ehcache.store.MemoryStore} or a {@link net.sf.ehcache.store.DiskStore}.
*
* This method creates those and makes the cache ready to accept elements
*/
public void initialise() {
cache.initialise();
}
/**
* Bootstrap command. This must be called after the Cache is intialised, during
* CacheManager initialisation. If loads are synchronous, they will complete before the CacheManager
* initialise completes, otherwise they will happen in the background.
*/
public void bootstrap() {
cache.bootstrap();
}
/**
* Flushes all cache items from memory to auxilliary caches and close the auxilliary caches.
*
* Should be invoked only by CacheManager.
*
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
*/
public void dispose() throws IllegalStateException {
cache.dispose();
}
/**
* Looks up an entry. Blocks if the entry is null until a call to {@link #put} is done
* to put an Element in.
*
* If a put is not done, the lock is never released
*
* Note. If a LockTimeoutException is thrown while doing a {@link #get} it means the lock was never acquired,
* therefore it is a threading error to call {@link #put}
* @throws LockTimeoutException if timeout millis is non zero and this method has been unable to
* acquire a lock in that time
*/
public Element get(final Object key) throws LockTimeoutException {
Mutex lock = getLockForKey(key);
try {
if (timeoutMillis == 0) {
lock.acquire();
} else {
boolean acquired = lock.attempt(timeoutMillis);
if (!acquired) {
StringBuffer message = new StringBuffer("Lock timeout. Waited more than")
.append(timeoutMillis)
.append("ms to acquire lock for key ")
.append(key).append(" on blocking cache ").append(cache.getName());
throw new LockTimeoutException(message.toString());
}
}
final Element element = cache.get(key);
if (element != null) {
//ok let the other threads in
lock.release();
return element;
} else {
//don't release the read lock until we put
return null;
}
} catch (InterruptedException e) {
throw new CacheException("Interrupted. Message was: " + e.getMessage());
}
}
/**
* Gets the Mutex to use for a given key.
* @param key the key
* @return one of a limited number of Mutexes.
*/
protected Mutex getLockForKey(final Object key) {
int lockNumber = ConcurrencyUtil.selectLock(key, LOCK_NUMBER);
return locks[lockNumber];
}
/**
* Adds an entry and unlocks it
*/
public void put(Element element) {
if (element == null) {
return;
}
Object key = element.getObjectKey();
Object value = element.getObjectValue();
Mutex lock = getLockForKey(key);
try {
if (value != null) {
cache.put(element);
} else {
cache.remove(key);
}
} finally {
//Release the readlock here. This will have been acquired in the get, where the element was null
lock.release();
}
}
/**
* Put an element in the cache.
*
* Resets the access statistics on the element, which would be the case if it has previously been
* gotten from a cache, and is now being put back.
*
* Also notifies the CacheEventListener that:
*
* - the element was put, but only if the Element was actually put.
*
- if the element exists in the cache, that an update has occurred, even if the element would be expired
* if it was requested
*
*
* @param element An object. If Serializable it can fully participate in replication and the DiskStore.
* @param doNotNotifyCacheReplicators whether the put is coming from a doNotNotifyCacheReplicators cache peer, in which case this put should not initiate a
* further notification to doNotNotifyCacheReplicators cache peers
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
* @throws IllegalArgumentException if the element is null
*/
public void put(Element element, boolean doNotNotifyCacheReplicators) throws IllegalArgumentException,
IllegalStateException, CacheException {
cache.put(element, doNotNotifyCacheReplicators);
}
/**
* Put an element in the cache, without updating statistics, or updating listeners. This is meant to be used
* in conjunction with {@link #getQuiet}
*
* @param element An object. If Serializable it can fully participate in replication and the DiskStore.
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
* @throws IllegalArgumentException if the element is null
*/
public void putQuiet(Element element) throws IllegalArgumentException, IllegalStateException, CacheException {
cache.putQuiet(element);
}
/**
* Gets an element from the cache. Updates Element Statistics
*
* Note that the Element's lastAccessTime is always the time of this get.
* Use {@link #getQuiet(Object)} to peak into the Element to see its last access time with get
*
* @param key a serializable value
* @return the element, or null, if it does not exist.
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
* @see #isExpired
*/
public Element get(Serializable key) throws IllegalStateException, CacheException {
return this.get((Object) key);
}
/**
* Gets an element from the cache, without updating Element statistics. Cache statistics are
* still updated.
*
*
* @param key a serializable value
* @return the element, or null, if it does not exist.
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
* @see #isExpired
*/
public Element getQuiet(Serializable key) throws IllegalStateException, CacheException {
return cache.getQuiet(key);
}
/**
* Gets an element from the cache, without updating Element statistics. Cache statistics are
* still updated.
*
*
* @param key a serializable value
* @return the element, or null, if it does not exist.
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
* @see #isExpired
* @since 1.2
*/
public Element getQuiet(Object key) throws IllegalStateException, CacheException {
return cache.getQuiet(key);
}
/**
* Returns the keys for this cache.
*
* @return The keys of this cache. This is not a live set, so it will not track changes to the key set.
*/
public List getKeys() throws CacheException {
return cache.getKeys();
}
/**
* Returns a list of all elements in the cache. Only keys of non-expired
* elements are returned.
*
* The returned keys are unique and can be considered a set.
*
* The List returned is not live. It is a copy.
*
* The time taken is O(n), where n is the number of elements in the cache. On
* a 1.8Ghz P4, the time taken is approximately 200ms per 1000 entries. This method
* is not synchronized, because it relies on a non-live list returned from {@link #getKeys()}
* , which is synchronised, and which takes 8ms per 1000 entries. This way
* cache liveness is preserved, even if this method is very slow to return.
*
* Consider whether your usage requires checking for expired keys. Because
* this method takes so long, depending on cache settings, the list could be
* quite out of date by the time you get it.
*
* @return a list of {@link Object} keys
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
*/
public List getKeysWithExpiryCheck() throws IllegalStateException, CacheException {
return cache.getKeysWithExpiryCheck();
}
/**
* Returns a list of all elements in the cache, whether or not they are expired.
*
* The returned keys are not unique and may contain duplicates. If the cache is only
* using the memory store, the list will be unique. If the disk store is being used
* as well, it will likely contain duplicates, because of the internal store design.
*
* The List returned is not live. It is a copy.
*
* The time taken is O(log n). On a single cpu 1.8Ghz P4, approximately 6ms is required
* for 1000 entries and 36 for 50000.
*
* This is the fastest getKeys method
*
* @return a list of {@link Object} keys
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
*/
public List getKeysNoDuplicateCheck() throws IllegalStateException {
return getKeysNoDuplicateCheck();
}
/**
* Removes an {@link net.sf.ehcache.Element} from the Cache. This also removes it from any
* stores it may be in.
*
* Also notifies the CacheEventListener after the element was removed, but only if an Element
* with the key actually existed.
*
* @param key
* @return true if the element was removed, false if it was not found in the cache
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
*/
public boolean remove(Serializable key) throws IllegalStateException {
return cache.remove(key);
}
/**
* Removes an {@link net.sf.ehcache.Element} from the Cache. This also removes it from any
* stores it may be in.
*
* Also notifies the CacheEventListener after the element was removed, but only if an Element
* with the key actually existed.
*
* @param key
* @return true if the element was removed, false if it was not found in the cache
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
* @since 1.2
*/
public boolean remove(Object key) throws IllegalStateException {
return cache.remove(key);
}
/**
* Removes an {@link net.sf.ehcache.Element} from the Cache. This also removes it from any
* stores it may be in.
*
* Also notifies the CacheEventListener after the element was removed, but only if an Element
* with the key actually existed.
*
* @param key
* @param doNotNotifyCacheReplicators whether the put is coming from a doNotNotifyCacheReplicators cache peer, in which case this put should not initiate a
* further notification to doNotNotifyCacheReplicators cache peers
* @return true if the element was removed, false if it was not found in the cache
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
* @noinspection SameParameterValue
*/
public boolean remove(Serializable key, boolean doNotNotifyCacheReplicators) throws IllegalStateException {
return cache.remove(key, doNotNotifyCacheReplicators);
}
/**
* Removes an {@link net.sf.ehcache.Element} from the Cache. This also removes it from any
* stores it may be in.
*
* Also notifies the CacheEventListener after the element was removed, but only if an Element
* with the key actually existed.
*
* @param key
* @param doNotNotifyCacheReplicators whether the put is coming from a doNotNotifyCacheReplicators cache peer, in which case this put should not initiate a
* further notification to doNotNotifyCacheReplicators cache peers
* @return true if the element was removed, false if it was not found in the cache
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
*/
public boolean remove(Object key, boolean doNotNotifyCacheReplicators) throws IllegalStateException {
return cache.remove(key, doNotNotifyCacheReplicators);
}
/**
* Removes an {@link net.sf.ehcache.Element} from the Cache, without notifying listeners. This also removes it from any
* stores it may be in.
*
*
* @param key
* @return true if the element was removed, false if it was not found in the cache
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
*/
public boolean removeQuiet(Serializable key) throws IllegalStateException {
return cache.removeQuiet(key);
}
/**
* Removes an {@link net.sf.ehcache.Element} from the Cache, without notifying listeners. This also removes it from any
* stores it may be in.
*
*
* @param key
* @return true if the element was removed, false if it was not found in the cache
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
* @since 1.2
*/
public boolean removeQuiet(Object key) throws IllegalStateException {
return cache.removeQuiet(key);
}
/**
* Removes all cached items.
*
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
*/
public void removeAll() throws IllegalStateException, CacheException {
cache.removeAll();
}
/**
* Removes all cached items.
*
* @param doNotNotifyCacheReplicators whether the put is coming from a doNotNotifyCacheReplicators cache peer,
* in which case this put should not initiate a further notification to doNotNotifyCacheReplicators cache peers
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
*/
public void removeAll(boolean doNotNotifyCacheReplicators) throws IllegalStateException, CacheException {
cache.removeAll(doNotNotifyCacheReplicators);
}
/**
* Flushes all cache items from memory to the disk store, and from the DiskStore to disk.
*
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
*/
public void flush() throws IllegalStateException, CacheException {
cache.flush();
}
/**
* Gets the size of the cache. This is a subtle concept. See below.
*
* The size is the number of {@link net.sf.ehcache.Element}s in the {@link net.sf.ehcache.store.MemoryStore} plus
* the number of {@link net.sf.ehcache.Element}s in the {@link net.sf.ehcache.store.DiskStore}.
*
* This number is the actual number of elements, including expired elements that have
* not been removed.
*
* Expired elements are removed from the the memory store when
* getting an expired element, or when attempting to spool an expired element to
* disk.
*
* Expired elements are removed from the disk store when getting an expired element,
* or when the expiry thread runs, which is once every five minutes.
*
* To get an exact size, which would exclude expired elements, use {@link #getKeysWithExpiryCheck()}.size(),
* although see that method for the approximate time that would take.
*
* To get a very fast result, use {@link #getKeysNoDuplicateCheck()}.size(). If the disk store
* is being used, there will be some duplicates.
*
* @return The size value
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
*/
public int getSize() throws IllegalStateException, CacheException {
return cache.getSize();
}
/**
* Gets the size of the memory store for this cache
*
* Warning: This method can be very expensive to run. Allow approximately 1 second
* per 1MB of entries. Running this method could create liveness problems
* because the object lock is held for a long period
*
*
* @return the approximate size of the memory store in bytes
* @throws IllegalStateException
*/
public long calculateInMemorySize() throws IllegalStateException, CacheException {
return cache.calculateInMemorySize();
}
/**
* Returns the number of elements in the memory store.
*
* @return the number of elements in the memory store
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
*/
public long getMemoryStoreSize() throws IllegalStateException {
return cache.getMemoryStoreSize();
}
/**
* Returns the number of elements in the disk store.
*
* @return the number of elements in the disk store.
* @throws IllegalStateException if the cache is not {@link net.sf.ehcache.Status#STATUS_ALIVE}
*/
public int getDiskStoreSize() throws IllegalStateException {
return cache.getDiskStoreSize();
}
/**
* Gets the status attribute of the Cache.
*
* @return The status value from the Status enum class
*/
public Status getStatus() {
return cache.getStatus();
}
/**
* The number of times a requested item was found in the cache.
*
* @return the number of times a requested item was found in the cache
*/
public int getHitCount() {
return cache.getHitCount();
}
/**
* Number of times a requested item was found in the Memory Store.
*
* @return Number of times a requested item was found in the Memory Store.
*/
public int getMemoryStoreHitCount() {
return cache.getMemoryStoreHitCount();
}
/**
* Number of times a requested item was found in the Disk Store.
*/
public int getDiskStoreHitCount() {
return cache.getDiskStoreHitCount();
}
/**
* Number of times a requested element was not found in the cache. This
* may be because it expired, in which case this will also be recorded in {@link #getMissCountExpired},
* or because it was simply not there.
*/
public int getMissCountNotFound() {
return cache.getMissCountNotFound();
}
/**
* Number of times a requested element was found but was expired.
*/
public int getMissCountExpired() {
return cache.getMissCountExpired();
}
/**
* Synchronized version of getName to test liveness of the object lock.
*
* The time taken for this method to return is a useful measure of runtime contention on the cache.
*/
public synchronized String liveness() {
return getName();
}
/**
* Sets the time to wait to acquire a lock. This may be modified at any time.
*
* The consequences of setting a timeout are:
*
* - if a lock cannot be acquired in the given time a LockTimeoutException is thrown.
*
- if there is a queue of threads waiting for the first thread to complete, but it does not complete within
* the time out period, the successive threads may find that they have exceeded their lock timeouts and fail. This
* is usually a good thing because it stops a build up of threads from overwhelming a busy resource, but it does
* need to be considered in the design of user interfaces. The timeout should be set no greater than the time a user
* would be expected to wait before considering the action will never return
*
- it will be common to see a number of threads timeout trying to get the same lock. This is a normal and desired
* consequence.
*
* The consequences of not setting a timeout (or setting it to 0) are:
*
* - There are no partial failures in the system. But there is a greater possibility that a temporary overload
* in one part of the system can cause a back up that may take a long time to recover from.
*
- A failing method that perhaps fails because a resource is overloaded will be hit by each thread in turn, no matter whether there is a still a user who
* cares about getting a response.
*
*
* @param timeoutMillis the time in ms. Must be a positive number. 0 means wait forever.
*/
public void setTimeoutMillis(int timeoutMillis) {
if (timeoutMillis < 0) {
throw new CacheException("The lock timeout must be a positive number of ms. Value was " + timeoutMillis);
}
this.timeoutMillis = timeoutMillis;
}
/**
* Gets the time to wait to acquire a lock.
*
* @return the time in ms.
*/
public int getTimeoutMillis() {
return timeoutMillis;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy