org.helidb.backend.cache.lru
Class LruCacheBackend<K,V,P>

java.lang.Object
  extended by org.helidb.backend.AbstractDatabaseBackendProxy<K,V,P>
      extended by org.helidb.backend.cache.lru.LruCacheBackend<K,V,P>
Type Parameters:
K - The type of keys in the database.
V - The type of values in the database.
P - The type the proxied backend uses to represent positions.
All Implemented Interfaces:
Iterable<Record<K,V>>, DatabaseBackend<K,V,P>

public class LruCacheBackend<K,V,P>
extends AbstractDatabaseBackendProxy<K,V,P>

The LRUCacheBackend is a proxy for another DatabaseBackend object and caches results from searches and updates. It contains two LRU caches, one cache for database records and one cache for negative search information (we did not find the key k when searching for it the last time, so we would not find it if we searched for it again).

Results from calling DatabaseBackend.getNextPosition(Object) and DatabaseBackend.getPreviousPosition(Object) (used by database Cursor:s) are not cached. Those operations is assumed to have efficient implementations in the backend.

LRU stands for Least Recently Used and means that, if the cache is full, the least recently used element is purged to make room for a new element.

Consider the key and value objects stored in a caching database as immutable. If they are modified, the behavior of the database is unspecified and, almost certainly, unpleasant.

Since:
1.0
Author:
Karl Gustafsson
See Also:
LruCacheBackendFactory
In_jar:
helidb-core

Constructor Summary
LruCacheBackend(DatabaseBackend<K,V,P> proxied, boolean readOnly, int maxCacheSize, int maxNegativeCacheSize)
           
 
Method Summary
 void clear()
          Wipe out the entire database.
 void close()
          Subclasses overriding this method must call super.close().
 boolean delete(K key)
          Delete the record with the supplied key, if it exists.
 P find(Comparable<K> key, SearchMode mode)
          The results from this method are not cached.
 P find(K key)
          Find the position of the record with the supplied key in the database backend.
 P find(K key, SearchMode mode, Comparator<? super K> cmp)
          The results from this method are not cached.
 V getValueFor(K key)
          Get the value for the record with the supplied key.
 P insert(K key, V value)
          Insert a new record in the database.
 P insertCheckKeyUnique(K key, V value)
          Insert a new record in the database after verifying that the key is unique within the database.
 boolean insertOrUpdate(K key, V value)
          If a record with the supplied key exists, update its value.
 K readKeyAt(P pos)
          Read the key at the supplied position.
 Record<K,V> readRecordAt(P pos)
          Read the record (key and value) at the specified position.
 V readValueAt(P pos)
          Read the value at the specified position.
 V remove(K key)
          Delete the record with the supplied key and return its value.
 void removeAt(P pos, K key)
          Delete the record at the supplied position.
 void replaceContentsWith(RandomAccess ra, long dataSize)
          Replace the contents of the database with content read from the supplied RandomAccess.
 Pair<P> update(K key, V value)
          Update an existing record with a new value.
 P updateAt(P pos, K key, V value)
          Update the record at the supplied position with the new value.
 
Methods inherited from class org.helidb.backend.AbstractDatabaseBackendProxy
addRecordMoveListener, assertNotClosed, assertNotReadOnly, compact, finalize, forEachKey, getContentsVersion, getFirstPosition, getKeys, getLastPosition, getNextPosition, getPreviousPosition, getProxied, getRecords, getValues, isClosed, isReadOnly, iterator, keyIterator, removeRecordMoveListener, valueIterator, writeContentsTo
 
Methods inherited from class java.lang.Object
clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

LruCacheBackend

public LruCacheBackend(DatabaseBackend<K,V,P> proxied,
                       boolean readOnly,
                       int maxCacheSize,
                       int maxNegativeCacheSize)
                throws IllegalArgumentException
Throws:
IllegalArgumentException
Method Detail

insert

public P insert(K key,
                V value)
Description copied from interface: DatabaseBackend
Insert a new record in the database.

Parameters:
key - The key. It is not verified that this key is unique. Inserting duplicate keys will result in unspecified behavior from the backend.
value - The value.
Returns:
The position of the new record.

insertCheckKeyUnique

public P insertCheckKeyUnique(K key,
                              V value)
Description copied from interface: DatabaseBackend
Insert a new record in the database after verifying that the key is unique within the database.

Parameters:
key - The key.
value - The value.
Returns:
The position of the new record.

find

public P find(K key)
Description copied from interface: DatabaseBackend
Find the position of the record with the supplied key in the database backend.

Parameters:
key - The key to find.
Returns:
The position of the key, or null if not found.
See Also:
DatabaseBackend.find(Comparable, SearchMode), DatabaseBackend.find(Object, SearchMode, Comparator)

find

public P find(Comparable<K> key,
              SearchMode mode)
The results from this method are not cached.

Parameters:
key - The key to find.
mode - The search mode. The backend implementation must support the SearchMode.EXACT_MATCH mode (which makes this method behave exactly like DatabaseBackend.find(Object)). The backend may also support SearchMode.CLOSEST_ABOVE, SearchMode.CLOSEST_BELOW and SearchMode.CLOSEST_MATCH. If not, this method should throw an UnsupportedOperationException when called with any of those search modes. The backend implementation may also invent its own search modes.

The closest match is defined as the match that gives the lowest positive (SearchMode.CLOSEST_ABOVE), negative ( SearchMode.CLOSEST_BELOW) or absolute ( SearchMode.CLOSEST_MATCH) value from the supplied key's Comparable.compareTo(Object) method when comparing the keys in the database with the key to search for.

Returns:
The position of the record that matches the search criteria, or null if no record matching the search criteria is found.
See Also:
DatabaseBackend.find(Object), DatabaseBackend.find(Object, SearchMode, Comparator)

find

public P find(K key,
              SearchMode mode,
              Comparator<? super K> cmp)
The results from this method are not cached.

Parameters:
key - The key to find.
mode - The search mode. The backend implementation must support the SearchMode.EXACT_MATCH mode (which makes this method behave exactly like DatabaseBackend.find(Object)). The backend may also support SearchMode.CLOSEST_ABOVE, SearchMode.CLOSEST_BELOW and SearchMode.CLOSEST_MATCH. If not, this method should throw an UnsupportedOperationException when called with any of those search modes. The backend implementation may also invent its own search modes.

The closest match is defined as the match that gives the lowest positive (SearchMode.CLOSEST_ABOVE), negative ( SearchMode.CLOSEST_BELOW) or absolute ( SearchMode.CLOSEST_MATCH) value from the comparator when comparing the keys in the database with the key to search for.

cmp - The Comparator used to compare keys.
Returns:
The position of the record that matches the search criteria, or null if no record matching the search criteria is found.
See Also:
DatabaseBackend.find(Object), DatabaseBackend.find(Comparable, SearchMode)

getValueFor

public V getValueFor(K key)
Description copied from interface: DatabaseBackend
Get the value for the record with the supplied key.

Parameters:
key - The record's key.
Returns:
The record's value or null if no record in the database has the supplied key.

updateAt

public P updateAt(P pos,
                  K key,
                  V value)
Description copied from interface: DatabaseBackend
Update the record at the supplied position with the new value. The new key is always the same as the previous key.

It is up to the implementation to decide exactly how this is done. It is not required that the record should be located at the same position in the backend after the update. One strategy for implementing this method is to delete the old record and insert a new record with the updated values.

Parameters:
pos - The position of the record to update.
key - The record's key. The key is not modified by the update.
value - The new value.
Returns:
The new position of the record.

update

public Pair<P> update(K key,
                      V value)
Description copied from interface: DatabaseBackend
Update an existing record with a new value.

It is up to the implementation to decide exactly how this is done. It is not required that the record should be located at the same position in the backend after the update. One strategy for implementing this method is to delete the old record and insert a new record with the updated values.

Parameters:
key - The record's key.
value - The record's new value.
Returns:
The record's old position (the first object in the pair) and the new position (the second object in the pair).

insertOrUpdate

public boolean insertOrUpdate(K key,
                              V value)
Description copied from interface: DatabaseBackend
If a record with the supplied key exists, update its value. If not, insert a new record.

Parameters:
key - The key.
value - The value.
Returns:
true if an existing record was updated, false if a new record was inserted.

readValueAt

public V readValueAt(P pos)
Description copied from interface: DatabaseBackend
Read the value at the specified position.

Parameters:
pos - The position of the record containing the value. This must be a valid position in the backend. If it is not, the behavior of this method is unspecified.
Returns:
The value.
See Also:
DatabaseBackend.readKeyAt(Object), DatabaseBackend.readRecordAt(Object)

readKeyAt

public K readKeyAt(P pos)
            throws WrappedIOException,
                   IllegalStateException
Description copied from interface: DatabaseBackend
Read the key at the supplied position.

Parameters:
pos - The position of the record containing the key. This must be a valid position in the backend. It it is not, the behavior of this method is unspecified.
Returns:
The key.
Throws:
WrappedIOException - On I/O errors.
IllegalStateException - If the database backend has been closed.
See Also:
DatabaseBackend.readValueAt(Object), DatabaseBackend.readRecordAt(Object)

readRecordAt

public Record<K,V> readRecordAt(P pos)
                         throws WrappedIOException,
                                IllegalStateException
Description copied from interface: DatabaseBackend
Read the record (key and value) at the specified position.

Parameters:
pos - The position of the record. This must be a valid position in the backend. If it is not, the behavior of this method is unspecified.
Returns:
The record.
Throws:
WrappedIOException - On I/O errors.
IllegalStateException - If the database backend has been closed.
See Also:
DatabaseBackend.readKeyAt(Object), DatabaseBackend.readValueAt(Object)

clear

public void clear()
Description copied from interface: DatabaseBackend
Wipe out the entire database.


removeAt

public void removeAt(P pos,
                     K key)
Description copied from interface: DatabaseBackend
Delete the record at the supplied position.

Parameters:
pos - The position of the record to delete.
key - The key for the record to remove.

delete

public boolean delete(K key)
Description copied from interface: DatabaseBackend
Delete the record with the supplied key, if it exists.

Parameters:
key - The record's key.
Returns:
true if a record was deleted.

remove

public V remove(K key)
Description copied from interface: DatabaseBackend
Delete the record with the supplied key and return its value.

Parameters:
key - The record's key.
Returns:
The record's value or null if no record in the database has the supplied key.

replaceContentsWith

public void replaceContentsWith(RandomAccess ra,
                                long dataSize)
Description copied from interface: DatabaseBackend
Replace the contents of the database with content read from the supplied RandomAccess. The database contents start at the RandomAccess' current position.

Parameters:
ra - The RandomAccess to read data from. It should not be closed after reading.
dataSize - The total size of the database data in bytes.

close

public void close()
Description copied from class: AbstractDatabaseBackendProxy
Subclasses overriding this method must call super.close().

Specified by:
close in interface DatabaseBackend<K,V,P>
Overrides:
close in class AbstractDatabaseBackendProxy<K,V,P>