package com.googlecode.objectify.impl;
import java.util.Map;
import com.google.appengine.api.datastore.QueryResultIterator;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyFactory;
import com.googlecode.objectify.helper.QueryResultIteratorWrapper;
/**
* Extends the QueryImpl to add a session cache. Note that it only needs
* to override the iterator() method.
*
* @author Jeff Schnitzer <jeff@infohazard.org>
*/
public class SessionCachingQueryImpl<T> extends QueryImpl<T>
{
/** The cache is a simple hashmap, obtained from the SessionCachingObjectifyImpl */
final protected Map<Key<?>, Object> cache;
/** */
public SessionCachingQueryImpl(ObjectifyFactory fact, Objectify ofy, Map<Key<?>, Object> cache)
{
super(fact, ofy);
this.cache = cache;
}
/** */
public SessionCachingQueryImpl(ObjectifyFactory fact, Objectify ofy, Map<Key<?>, Object> cache, Class<T> clazz)
{
super(fact, ofy, clazz);
this.cache = cache;
}
@Override
public QueryResultIterator<T> iterator()
{
return new SessionCachingQueryResultIterator(super.iterator());
}
/**
* Simple iterator passes through and merges with the cache.
*/
protected class SessionCachingQueryResultIterator extends QueryResultIteratorWrapper<T>
{
public SessionCachingQueryResultIterator(QueryResultIterator<T> base)
{
super(base);
}
@Override
@SuppressWarnings("unchecked")
public T next()
{
T t = super.next();
Key<T> key = factory.getKey(t);
T cached = (T)cache.get(key);
if (cached == null || cached == SessionCachingObjectifyImpl.NEGATIVE_RESULT)
{
cache.put(key, t);
cached = t;
}
return cached;
}
}
}