|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
public interface CacheLayer
Superinterface for classes which manage the cache semantics for
specific entity values. Implementations of this interface are what
actually handle the meat of the cache operation, using resources
allocated within the corresponding Cache
implementation.
The basic cache model is that of the Map
interface (which
is logical as ActiveObjects was originally cached with a conventional
HashMap
). Values are stored in the cache based on
String
keys. These values must be typed within
the cache and returned in their proper type, up-cast to
Object
. This is extremely important since AO will
assume that values can be cast to their appropriate types within
code which uses the cache. Thus, any cache implementation must
also store value types in its implementation. It is also critical
that any cache implementation be able to store null
values. Technically, null
values may be
dropped for non-dirty fields, but this will lead to decreased
performance in the entity accessor algorithm. Null keys need not
be accepted.
Cache bindings themselves need not be persistent. For example, it is strongly encouraged to implement value expiry on implementations with a distributed backend. Likewise, local caches may take into account finite resources (such as memory). There is nothing in the ActiveObjects core implementation which assumes that bindings will be persistent for any length of time. In fact, it is technically permissible to implement a cache layer which does not cache at all, but simply responds appropriately when invoked. Note that while this is certainly possible, it would be quite detrimental to performance. Implementations should make the utmost effort to ensure that key,value bindings persist for as long as possible. The values themselves will never become stale (out of sync with the DB) unless the cache is being accessed by multiple instnaces of AO.
It is important to note that all of the methods in the interface must be implemented for ActiveObjects to function properly. A few of the methods may be omitted without affecting critical functionality, but this should not be assumed. This fact is especially important to keep in mind when working with limitted cache backends (such as memcached). By whatever means necessary, the contract must be fullfilled.
Concurrency must be considered for all implementations, but especially those with a distributed backend. ActiveObjects does not synchronize calls to the cache, that task is left up to the cache implementation itself. Due to the fact that entire code blocks are not locked against the cache, ActiveObjects is inherantly prone to race conditions and stale data in distributed caches. This is a design decision which may change in future, but for now it remains due to performance and stability concerns. For this reason, caches with distributed backends (such as memcached) are encouraged to set a sufficiently short default timeout to allow invalid data to simply expire naturally.
Except in odd cases, CacheLayer
implementations
should not manage volatile resources themselves. All of this
work should be handled within the corresponding ValueCache
implementation. The general rule of thumb is that the value
cache handles the "what" while the cache layer manages the "how".
Cache
Method Summary | |
---|---|
void |
clear()
Removes all bindings, effectively flushing the cache. |
void |
clearDirty()
Removes all fields from the dirty set, implicitly marking all fields as "in sync" with the database. |
void |
clearFlush()
|
boolean |
contains(String field)
Determines if a binding is present which corresponds to the given key. |
boolean |
dirtyContains(String field)
Determines if a given field is in the set of dirty fields (has been locally modified). |
Object |
get(String field)
Retrieves a typed value from the cache based on the given String key. |
String[] |
getDirtyFields()
Retrieves the set of all dirty fields in no particular order. |
Class<? extends RawEntity<?>>[] |
getToFlush()
|
void |
markDirty(String field)
Adds a given field to the set of dirty fields (fields which have been modified without being persisted back to the DB). |
void |
markToFlush(Class<? extends RawEntity<?>> type)
|
void |
put(String field,
Object value)
Stores a typed value in the cache, indexed by the given String key. |
void |
remove(String field)
Removes the binding for a specified key, deleting the association from the cache. |
Method Detail |
---|
void put(String field, Object value)
String
key. If the key is already assigned, its
value should be overwritten.
field
- The key which should be assigned to the given value.value
- The value to be stored (may be null
).Object get(String field)
String
key. Even with a non-native cache backend,
all values returned from the get(String)
method
must be of the same type with which they were stored. If this
contract is not observed, a ClassCastException
will be
thrown on some entity operations.
field
- The key for which the corresponding value should be retrieved.
null
if no binding is found (or if the value
itself is null
).void remove(String field)
null
for any future calls to get(String)
on that key, as well as false
for any calls to
contains(String)
.
field
- The key which indexes the binding to be removed.boolean contains(String field)
null
value as ActiveObjects may store null
s within the
cache. If this method is inconsistent in its implementation, very
strange things will happen on all entity calls.
field
- The key for which a binding may be found.
true
if the cache contains a binding for the
given key, false
otherwise.void clear()
remove(String)
, values need not actually be deleted, but
the bindings must become void.
void markDirty(String field)
getDirtyFields()
). However,
secondary actions are also permitted (such as flagging the field
for a preemptive, local cache).
field
- The field which has been locally modified.String[] getDirtyFields()
markDirty(String)
boolean dirtyContains(String field)
RawEntity.save()
method.
field
- The field which may be dirty.
true
if the field is dirty, false
otherwise.void clearDirty()
markDirty(String)
method, the implementation must at the minimum clear the set of all
dirty fields. However, other side effects (like resyncing with a
distributed cache) may also be implemented.
void markToFlush(Class<? extends RawEntity<?>> type)
Class<? extends RawEntity<?>>[] getToFlush()
void clearFlush()
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |