| java.lang.Object hu.netmind.persistence.ResultsCache
ResultsCache | public class ResultsCache (Code) | | This is an implementation of an intelligent, configurationless
read-only cache with change detection.
The main design point is that it does not require any configuration
from the user. It's task is to cache result sets up to a previously
given deadline, and when that is reached, clear from cache. When the
same result is referenced, the deadline may be moved further into the future.
Memory management is dynamic. When a resultset arives into the cache,
it is always cached, but if the cache detects, that
there is "not enough memory" (see below) left, it may clear some entries before their
their deadline is reached.
So basically one does not have to configure the size of the cache because
it assumes that if a resultset was not recalled in a given timeframe,
the overhead of selecting from database is acceptable (rather than
always using a predetemined size for the cache, hoping to achieve more
cache hits). Also, memory adapts to usage: When the load is low,
it is more likely, that only a few resultsets are in the cache, because
they expire, and are not likely to be hit anyway. But if the load rises,
more and more results get into the cache, the likelyhood of a hit also
rises, together with the memory allocation.
The cache determines whether there is enough memory by checking the
raw bytes free, and also computes the ratio of allocated vs. free memory.
If this ratio is below a given threshold, then there is enough memory. The
theory is, that the Java VM will allocate more heap when this ratio
is sufficiently small (usually around 60-70%). This leaves two cases:
- If the cache's ratio is less than the VM's, than the cache will
not force the VM to allocate more space, which in turn means, that
the cache will not grow, although the VM could allocate more memory.
- If this ratio is more than the VM's, than the cache will potentially
force the VM to allocate new memory, potentially eating the memory
away from more important tasks.
The cache uses the first non-agressive algorithm. The cache itself will not
cause the VM to allocate more heap, but if the application uses more memory
the cache will use proportionally more memory for it's own cause. Note:
The VM tries to maintain free/used ratio between appr. 30-70%.
This cache specializes to store only current searches' result (rather than
current and historical results). This is because in the
case of current results, the cache can effectively compute the interval
the result is valid. When determining whether a statement's result is in
the cache, the cache searches all entries (which are all current), and if
the statements serial is above or equals to the result's start serial
(the serial of the first query which caused the entry to be created),
then the result is valid for that query. If a query is received for which
the result may depend on changes inside the transaction, which are not
yet visible to the other transactions, then this query is not handled. This
is mainly because handling transaction-dependent result sets would be
a large overhead for the cache, with little benefit if at all.
In effect, cache hits will occur mostly, when the same non-historical
query, for a common table (not frequently changed) is run multiple times
in short period of time.
author: Brautigam Robert version: Revision: $Revision$ |
addEntry | public void addEntry(QueryStatement stmt, Limits limits, SearchResult result)(Code) | | Add an entry to the cache.
Parameters: stmt - The statement source of result. Parameters: limits - The limits of result. Parameters: result - The SearchResult object. |
clear | public void clear()(Code) | | Clear the cache.
|
getEntry | public SearchResult getEntry(QueryStatement stmt, Limits limits)(Code) | | Get an entry from the cache.
Parameters: stmt - The statement to look for. Parameters: limits - The limits of the query. A SearchResult object if the query was cached, null otherwise. |
init | public void init()(Code) | | Initialize the cache with the current serial.
|
updateEntries | public void updateEntries(String tableName, Long modifySerial)(Code) | | Tell the cache, that a table was updated. If an object is updated,
the old resultsets could be theoretically kept, with an other time
control, but empirically that does not add to cache hits, because more
often, only current resultsets are selected.
Parameters: tableName - The table to update. Parameters: modifySerial - The modification serial of table. |
|
|