ehcache

net.sf.ehcache.store
Class DiskStore

java.lang.Object
  extended by net.sf.ehcache.store.DiskStore
All Implemented Interfaces:
CacheConfigurationListener, Store

public class DiskStore
extends java.lang.Object
implements Store, CacheConfigurationListener

A disk store implementation.

As of ehcache-1.2 (v1.41 of this file) DiskStore has been changed to a mix of finer grained locking using synchronized collections and synchronizing on the whole instance, as was the case with earlier versions.

The DiskStore, as of ehcache-1.2.4, supports eviction using an LFU policy, if a maximum disk store size is set. LFU uses statistics held at the Element level which survive moving between maps in the MemoryStore and DiskStores.

As of ehcache-2.0, a cache can be configured with a DiskStore with multiple stripes. This enables much higher throughput.

Version:
$Id: DiskStore.java 1892 2010-02-18 07:27:25Z asingh $
Author:
Adam Murdoch, Greg Luck, patches contributed: Ben Houston, patches contributed: James Abley

Field Summary
static java.lang.String AUTO_DISK_PATH_DIRECTORY_PREFIX
          If the CacheManager needs to resolve a conflict with the disk path, it will create a subdirectory in the given disk path with this prefix followed by a number.
 
Constructor Summary
protected DiskStore(Ehcache cache, java.lang.String diskPath)
          Creates a disk store.
 
Method Summary
 boolean bufferFull()
          In some circumstances data can be written so quickly to the spool that the VM runs out of memory while waiting for the spooling to disk.
 float calculateDataFileSparseness()
          The design of the layout on the data file means that there will be small gaps created when DiskElements are reused.
 boolean containsKey(java.lang.Object key)
          An unsynchronized and very low cost check to see if a key is in the Store.
static Store create(Cache cache, java.lang.String diskStorePath)
          A factory method to create a DiskStore.
protected  void deleteFilesInAutoGeneratedDirectory()
          Delete files in the auto generated directory.
 void deregistered(CacheConfiguration config)
          Indicates that this listener was removed from the given configuration
 void diskCapacityChanged(int oldCapacity, int newCapacity)
          Indicates a change in the configurations disk store capacity
 void dispose()
          Shuts down the disk store in preparation for cache shutdown

If a VM crash happens, the shutdown hook will not run.

 void expireElements()
          Removes expired elements.
 void flush()
          Flush the spool if persistent, so we don't lose any data.
static java.lang.String generateUniqueDirectory()
          Generates a unique directory name for use in automatically creating a diskStorePath where there is a conflict.
 Element get(java.lang.Object key)
          Gets an Element from the Disk Store.
 java.lang.String getDataFileName()
          Creates a file system safe data file.
 java.lang.String getDataFilePath()
           
 long getDataFileSize()
           
 Policy getEvictionPolicy()
           
 java.lang.String getIndexFileName()
           
 long getIndexFileSize()
           
 java.lang.Object getInternalContext()
          This should not be used, and will generally return null
 java.lang.Object[] getKeyArray()
          Gets an Array of the keys for all elements in the disk store.
 Element getQuiet(java.lang.Object key)
          Gets an Element from the Disk Store, without updating statistics
 int getSize()
          Returns the current store size in number of Elements.
 long getSizeInBytes()
          Gets the size of the store, in bytes.
 Status getStatus()
          Returns the store status.
 int getTerracottaClusteredSize()
          Returns nothing since a disk store isn't clustered
 long getTotalFileSize()
           
 long getUsedDataSize()
          When elements are deleted, spaces are left in the file.
 boolean isCacheCoherent()
          Indicates whether this store provides a coherent view of all the elements in a cache.
 boolean isClusterCoherent()
          Returns true if the cache is in coherent mode cluster-wide.
 boolean isNodeCoherent()
          Returns true if the cache is in coherent mode for the current node.
 boolean isSpoolThreadAlive()
          The spool thread is started when the disk store is created.
static net.sf.ehcache.store.DiskStore.DiskElement leastHit(net.sf.ehcache.store.DiskStore.DiskElement[] sampledElements, net.sf.ehcache.store.DiskStore.DiskElement justAdded)
          Finds the least hit of the sampled elements provided
 void loggingEnabledChanged(boolean oldValue, boolean newValue)
          Indicates a change in the configuration for enable/disable logging
 void memoryCapacityChanged(int oldCapacity, int newCapacity)
          Indicates a change in the configurations memory store capacity
 boolean put(Element element)
          Puts an element into the disk store.
 boolean putWithWriter(Element element, CacheWriterManager writerManager)
          Puts an item into the store and the cache writer manager in an atomic operation
 void registered(CacheConfiguration config)
          Indicates that this listener was registered with the given configuration
 Element remove(java.lang.Object key)
          Removes an item from the disk store.
 void removeAll()
          Remove all of the elements from the store.
 Element removeWithWriter(java.lang.Object key, CacheWriterManager writerManager)
          Removes an item from the store and the cache writer manager in an atomic operation.
 void setEvictionPolicy(Policy policy)
          Sets the eviction policy strategy.
 void setNodeCoherent(boolean coherent)
          Sets the cache in coherent or incoherent mode for the current node depending on the parameter.
 void timeToIdleChanged(long oldTti, long newTti)
          Indicates a change in the configurations time to idle
 void timeToLiveChanged(long oldTtl, long newTtl)
          Indicates a change in the configurations time to live
 java.lang.String toString()
          Returns a String representation of the DiskStore
 void waitUntilClusterCoherent()
          This method waits until the cache is in coherent mode in all the connected nodes.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

AUTO_DISK_PATH_DIRECTORY_PREFIX

public static final java.lang.String AUTO_DISK_PATH_DIRECTORY_PREFIX
If the CacheManager needs to resolve a conflict with the disk path, it will create a subdirectory in the given disk path with this prefix followed by a number. The presence of this name is used to determined whether it makes sense for a persistent DiskStore to be loaded. Loading persistent DiskStores will only have useful semantics where the diskStore path has not changed.

See Also:
Constant Field Values
Constructor Detail

DiskStore

protected DiskStore(Ehcache cache,
                    java.lang.String diskPath)
Creates a disk store.

Parameters:
cache - the Cache that the store is part of
diskPath - the directory in which to create data and index files
Method Detail

create

public static Store create(Cache cache,
                           java.lang.String diskStorePath)
A factory method to create a DiskStore.

Parameters:
cache -
diskStorePath -
Returns:
an instance of a DiksStore

get

public final Element get(java.lang.Object key)
Gets an Element from the Disk Store.

Specified by:
get in interface Store
Returns:
The element

containsKey

public final boolean containsKey(java.lang.Object key)
An unsynchronized and very low cost check to see if a key is in the Store. No check is made to see if the Element is expired.

Specified by:
containsKey in interface Store
Parameters:
key - The Element key
Returns:
true if found. If this method return false, it means that an Element with the given key is definitely not in the MemoryStore. If it returns true, there is an Element there. An attempt to get it may return null if the Element has expired.

getQuiet

public final Element getQuiet(java.lang.Object key)
Gets an Element from the Disk Store, without updating statistics

Specified by:
getQuiet in interface Store
Returns:
The element
See Also:
get(Object)

getKeyArray

public final java.lang.Object[] getKeyArray()
Gets an Array of the keys for all elements in the disk store.

Specified by:
getKeyArray in interface Store
Returns:
An Object[] of Serializable keys

getSize

public final int getSize()
Returns the current store size in number of Elements. This method may not measure data in transit from the spool to the disk.

Specified by:
getSize in interface Store
Returns:
the count of the Elements in the Store on the local machine
See Also:
getDataFileSize()

getTerracottaClusteredSize

public final int getTerracottaClusteredSize()
Returns nothing since a disk store isn't clustered

Specified by:
getTerracottaClusteredSize in interface Store
Returns:
returns 0

getSizeInBytes

public long getSizeInBytes()
Gets the size of the store, in bytes.

This method may be expensive to run, depending on implementation. Implementers may choose to return an approximate size.

This implementation returns the size of the data file, but does not take into account the memory in the spool.

Specified by:
getSizeInBytes in interface Store
Returns:
the approximate size of the store in bytes

getStatus

public final Status getStatus()
Returns the store status.

Specified by:
getStatus in interface Store

put

public final boolean put(Element element)
Puts an element into the disk store.

This method is not synchronized. It is however threadsafe. It uses fine-grained synchronization on the spool.

Specified by:
put in interface Store
Returns:
true if this is a new put for the key or element is null. Returns false if it was an update.

putWithWriter

public boolean putWithWriter(Element element,
                             CacheWriterManager writerManager)
                      throws CacheException
Puts an item into the store and the cache writer manager in an atomic operation

Specified by:
putWithWriter in interface Store
Returns:
true if this is a new put for the key or element is null. Returns false if it was an update.
Throws:
CacheException

bufferFull

public boolean bufferFull()
In some circumstances data can be written so quickly to the spool that the VM runs out of memory while waiting for the spooling to disk.

This is a very simple and quick test which estimates the spool size based on the last element's written size.

Specified by:
bufferFull in interface Store
Returns:
true if the spool is not being cleared fast enough

remove

public final Element remove(java.lang.Object key)
Removes an item from the disk store.

Specified by:
remove in interface Store

removeWithWriter

public Element removeWithWriter(java.lang.Object key,
                                CacheWriterManager writerManager)
Removes an item from the store and the cache writer manager in an atomic operation.

Specified by:
removeWithWriter in interface Store

removeAll

public final void removeAll()
Remove all of the elements from the store.

If there are registered CacheEventListeners they are notified of the expiry or removal of the Element as each is removed.

Specified by:
removeAll in interface Store

dispose

public final void dispose()
Shuts down the disk store in preparation for cache shutdown

If a VM crash happens, the shutdown hook will not run. The data file and the index file will be out of synchronisation. At initialisation we always delete the index file after we have read the elements, so that it has a zero length. On a dirty restart, it still will have and the data file will automatically be deleted, thus preserving safety.

Specified by:
dispose in interface Store

deleteFilesInAutoGeneratedDirectory

protected void deleteFilesInAutoGeneratedDirectory()
Delete files in the auto generated directory. These are one time only for those who create multiple CacheManagers with the same disk path settings.


flush

public final void flush()
Flush the spool if persistent, so we don't lose any data.

This, as of ehcache-1.6.0, is an asynchronous operation. It will write the next time the spoolAndExpiryThread runs. By default this is every 200ms.

Specified by:
flush in interface Store

expireElements

public void expireElements()
Removes expired elements.

Note that the DiskStore cannot efficiently expire based on TTI. It does it on TTL. However any gets out of the DiskStore are check for both before return.

Specified by:
expireElements in interface Store

toString

public final java.lang.String toString()
Returns a String representation of the DiskStore

Overrides:
toString in class java.lang.Object

generateUniqueDirectory

public static java.lang.String generateUniqueDirectory()
Generates a unique directory name for use in automatically creating a diskStorePath where there is a conflict.

Returns:
a path consisting of AUTO_DISK_PATH_DIRECTORY_PREFIX followed by "_" followed by the current time as a long e.g. ehcache_auto_created_1149389837006

timeToIdleChanged

public void timeToIdleChanged(long oldTti,
                              long newTti)
Indicates a change in the configurations time to idle

Specified by:
timeToIdleChanged in interface CacheConfigurationListener
Parameters:
oldTti - previous time to idle value
newTti - new time to idle value

timeToLiveChanged

public void timeToLiveChanged(long oldTtl,
                              long newTtl)
Indicates a change in the configurations time to live

Specified by:
timeToLiveChanged in interface CacheConfigurationListener
Parameters:
oldTtl - previous time to live value
newTtl - new time to live value

diskCapacityChanged

public void diskCapacityChanged(int oldCapacity,
                                int newCapacity)
Indicates a change in the configurations disk store capacity

Specified by:
diskCapacityChanged in interface CacheConfigurationListener
Parameters:
oldCapacity - previous capacity
newCapacity - new capacity

memoryCapacityChanged

public void memoryCapacityChanged(int oldCapacity,
                                  int newCapacity)
Indicates a change in the configurations memory store capacity

Specified by:
memoryCapacityChanged in interface CacheConfigurationListener
Parameters:
oldCapacity - previous capacity
newCapacity - new capacity

loggingEnabledChanged

public void loggingEnabledChanged(boolean oldValue,
                                  boolean newValue)
Indicates a change in the configuration for enable/disable logging

Specified by:
loggingEnabledChanged in interface CacheConfigurationListener
Parameters:
oldValue - old value whether logging was enabled or not
newValue - new value whether logging was enabled or not

registered

public void registered(CacheConfiguration config)
Indicates that this listener was registered with the given configuration

Specified by:
registered in interface CacheConfigurationListener

deregistered

public void deregistered(CacheConfiguration config)
Indicates that this listener was removed from the given configuration

Specified by:
deregistered in interface CacheConfigurationListener

getTotalFileSize

public final long getTotalFileSize()
Returns:
the total size of the data file and the index file, in bytes.

getDataFileSize

public final long getDataFileSize()
Returns:
the size of the data file in bytes.

calculateDataFileSparseness

public final float calculateDataFileSparseness()
The design of the layout on the data file means that there will be small gaps created when DiskElements are reused.

Returns:
the sparseness, measured as the percentage of space in the Data File not used for holding data

getUsedDataSize

public final long getUsedDataSize()
When elements are deleted, spaces are left in the file. These spaces are tracked and are reused when new elements need to be written.

This method indicates the actual size used for data, excluding holes. It can be compared with getDataFileSize() as a measure of fragmentation.


getIndexFileSize

public final long getIndexFileSize()
Returns:
the size of the index file, in bytes.

getDataFileName

public final java.lang.String getDataFileName()
Creates a file system safe data file. Any incidences of or / are replaced with _ so there are no unwanted side effects.

Returns:
the file name of the data file where the disk store stores data, without any path information.

getDataFilePath

public final java.lang.String getDataFilePath()
Returns:
the disk path, which will be dependent on the operating system

getIndexFileName

public final java.lang.String getIndexFileName()
Returns:
the file name of the index file, which maintains a record of elements and their addresses on the data file, without any path information.

isSpoolThreadAlive

public final boolean isSpoolThreadAlive()
The spool thread is started when the disk store is created.

It will continue to run until the dispose() method is called, at which time it should be interrupted and then die.

Returns:
true if the spoolThread is still alive.

leastHit

public static net.sf.ehcache.store.DiskStore.DiskElement leastHit(net.sf.ehcache.store.DiskStore.DiskElement[] sampledElements,
                                                                  net.sf.ehcache.store.DiskStore.DiskElement justAdded)
Finds the least hit of the sampled elements provided

Parameters:
sampledElements - this should be a random subset of the population
justAdded - we never want to select the element just added. May be null.
Returns:
the least hit

getEvictionPolicy

public Policy getEvictionPolicy()
Specified by:
getEvictionPolicy in interface Store
Returns:
the current eviction policy. This may not be the configured policy, if it has been dynamically set.
See Also:
setEvictionPolicy(Policy)

setEvictionPolicy

public void setEvictionPolicy(Policy policy)
Sets the eviction policy strategy. The Store will use a policy at startup. The store may allow changing the eviction policy strategy dynamically. Otherwise implementations will throw an exception if this method is called.

Specified by:
setEvictionPolicy in interface Store
Parameters:
policy - the new policy

getInternalContext

public java.lang.Object getInternalContext()
This should not be used, and will generally return null

Specified by:
getInternalContext in interface Store
Returns:
some internal context (probably null)

isCacheCoherent

public boolean isCacheCoherent()
Indicates whether this store provides a coherent view of all the elements in a cache. Note that this is same as calling Store.isClusterCoherent() (introduced since 2.0) Use Store.isNodeCoherent() to find out if the cache is coherent in the current node in the cluster

Specified by:
isCacheCoherent in interface Store
Returns:
true if the store is coherent; or false if the store potentially splits the cache storage with another store or isn't internally coherent

isClusterCoherent

public boolean isClusterCoherent()
Returns true if the cache is in coherent mode cluster-wide. Returns false otherwise.

It applies to coherent clustering mechanisms only e.g. Terracotta

Specified by:
isClusterCoherent in interface Store
Returns:
true if the cache is in coherent mode cluster-wide, false otherwise

isNodeCoherent

public boolean isNodeCoherent()
Returns true if the cache is in coherent mode for the current node. Returns false otherwise.

It applies to coherent clustering mechanisms only e.g. Terracotta

Specified by:
isNodeCoherent in interface Store
Returns:
true if the cache is in coherent mode cluster-wide, false otherwise

setNodeCoherent

public void setNodeCoherent(boolean coherent)
Sets the cache in coherent or incoherent mode for the current node depending on the parameter. Calling setNodeCoherent(true) when the cache is already in coherent mode or calling setNodeCoherent(false) when already in incoherent mode will be a no-op.

It applies to coherent clustering mechanisms only e.g. Terracotta

Specified by:
setNodeCoherent in interface Store
Parameters:
coherent - true transitions to coherent mode, false to incoherent mode

waitUntilClusterCoherent

public void waitUntilClusterCoherent()
This method waits until the cache is in coherent mode in all the connected nodes. If the cache is already in coherent mode it returns immediately

It applies to coherent clustering mechanisms only e.g. Terracotta

Specified by:
waitUntilClusterCoherent in interface Store

ehcache

true