All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.java.ao.cache.CacheLayer Maven / Gradle / Ivy

Go to download

This is the full Active Objects library, if you don't know which one to use, you probably want this one.

There is a newer version: 6.1.1
Show newest version
/*
 * Copyright 2007 Daniel Spiewak
 * 
 * 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.java.ao.cache;

import java.util.HashMap;
import java.util.Map;

import net.java.ao.RawEntity;

/**
 * 

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 {@link Cache} implementation.

* *

The basic cache model is that of the {@link Map} interface (which * is logical as ActiveObjects was originally cached with a conventional * {@link 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".

* * @author Daniel Spiewak * @see Cache */ public interface CacheLayer { /** * Stores a typed value in the cache, indexed by the given * String key. If the key is already assigned, its * value should be overwritten. * * @param field The key which should be assigned to the given value. * @param value The value to be stored (may be null). */ public void put(String field, Object value); /** * Retrieves a typed value from the cache based on the given * 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 {@link ClassCastException} will be * thrown on some entity operations. * * @param field The key for which the corresponding value should be retrieved. * @return The value which corresponds to the given key, or * null if no binding is found (or if the value * itself is null). */ public Object get(String field); /** * Removes the binding for a specified key, deleting the association * from the cache. From an implementation standpoint, the cache itself * need not discard the value when its binding is removed, it must * simply return null for any future calls to {@link #get(String)} * on that key, as well as false for any calls to * {@link #contains(String)}. * * @param field The key which indexes the binding to be removed. */ public void remove(String field); /** * Determines if a binding is present which corresponds to the given * key. Note that this method cannot simply check for a null * value as ActiveObjects may store nulls within the * cache. If this method is inconsistent in its implementation, very * strange things will happen on all entity calls. * * @param field The key for which a binding may be found. * @return true if the cache contains a binding for the * given key, false otherwise. */ public boolean contains(String field); /** * Removes all bindings, effectively flushing the cache. As with * {@link #remove(String)}, values need not actually be deleted, but * the bindings must become void. */ public void clear(); /** * Adds a given field to the set of dirty fields (fields which have * been modified without being persisted back to the DB). At the * very least, this method must append the field to the set of dirty * fields (as returned from {@link #getDirtyFields()}). However, * secondary actions are also permitted (such as flagging the field * for a preemptive, local cache). * * @param field The field which has been locally modified. */ public void markDirty(String field); /** * Retrieves the set of all dirty fields in no particular order. * * @return The set of all fields which have been locally modified. * @see #markDirty(String) */ public String[] getDirtyFields(); /** * Determines if a given field is in the set of dirty fields (has * been locally modified). Correct implementation of this method * is critical to the functionality of the {@link RawEntity#save()} * method. * * @param field The field which may be dirty. * @return true if the field is dirty, false * otherwise. */ public boolean dirtyContains(String field); /** * Removes all fields from the dirty set, implicitly marking all fields * as "in sync" with the database. As with the {@link #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. */ public void clearDirty(); public void markToFlush(Class> type); public Class>[] getToFlush(); public void clearFlush(); }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy