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 core library for Active Objects. It is generic and can be embedded in any environment. As such it is generic and won't contain all connection pooling, etc.

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