mirror of https://github.com/apache/openjpa.git
OPENJPA-263 : Introducing getAll(List) method for data cache to be called by loadAll()
will allow data cache plug-ins to leverage the advantage of any third-party cache that provides a way to get multiple object in one call by providing a list of keys (oids). git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@558125 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
a5d1acd44e
commit
168c0076c8
|
@ -21,7 +21,10 @@ package org.apache.openjpa.datacache;
|
|||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.openjpa.conf.OpenJPAConfiguration;
|
||||
import org.apache.openjpa.event.RemoteCommitEvent;
|
||||
|
@ -439,4 +442,14 @@ public abstract class AbstractDataCache
|
|||
log.warn(s_loc.get("exp-listener-ex"), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the objects for the given key List.
|
||||
*/
|
||||
public Map getAll(List keys) {
|
||||
Map resultMap = new HashMap(keys.size());
|
||||
for(int i=0; i<keys.size(); i++)
|
||||
resultMap.put(keys.get(i), get(keys.get(i)));
|
||||
return resultMap;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.openjpa.datacache;
|
|||
|
||||
import java.util.BitSet;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.openjpa.lib.util.Closeable;
|
||||
|
@ -258,4 +259,9 @@ public interface DataCache
|
|||
* Free the resources used by this cache.
|
||||
*/
|
||||
public void close ();
|
||||
|
||||
/**
|
||||
* returns objects from the caches for a given list of keys
|
||||
*/
|
||||
public Map getAll(List keys);
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ import org.apache.openjpa.kernel.StoreManager;
|
|||
import org.apache.openjpa.kernel.StoreQuery;
|
||||
import org.apache.openjpa.meta.ClassMetaData;
|
||||
import org.apache.openjpa.meta.MetaDataRepository;
|
||||
import org.apache.openjpa.util.OpenJPAId;
|
||||
import org.apache.openjpa.util.OptimisticException;
|
||||
|
||||
/**
|
||||
|
@ -409,6 +410,8 @@ public class DataCacheStoreManager
|
|||
return super.loadAll(sms, state, load, fetch, edata);
|
||||
|
||||
Map unloaded = null;
|
||||
List smList = null;
|
||||
Map caches = new HashMap();
|
||||
OpenJPAStateManager sm;
|
||||
DataCache cache;
|
||||
DataCachePCData data;
|
||||
|
@ -422,8 +425,37 @@ public class DataCacheStoreManager
|
|||
continue;
|
||||
}
|
||||
|
||||
if (sm.getManagedInstance() == null
|
||||
|| load != FORCE_LOAD_NONE
|
||||
|| sm.getPCState() == PCState.HOLLOW) {
|
||||
smList = (List) caches.get(cache);
|
||||
if (smList == null) {
|
||||
smList = new ArrayList();
|
||||
caches.put(cache, smList);
|
||||
}
|
||||
smList.add(sm);
|
||||
} else if (!cache.contains(sm.getObjectId()))
|
||||
unloaded = addUnloaded(sm, null, unloaded);
|
||||
}
|
||||
|
||||
for (Iterator itr = caches.keySet().iterator(); itr.hasNext();) {
|
||||
cache = (DataCache) itr.next();
|
||||
smList = (List) caches.get(cache);
|
||||
List oidList = new ArrayList(smList.size());
|
||||
|
||||
for (itr=smList.iterator();itr.hasNext();) {
|
||||
sm = (OpenJPAStateManager) itr.next();
|
||||
oidList.add((OpenJPAId) sm.getObjectId());
|
||||
}
|
||||
|
||||
Map dataMap = cache.getAll(oidList);
|
||||
|
||||
for (itr=smList.iterator();itr.hasNext();) {
|
||||
sm = (OpenJPAStateManager) itr.next();
|
||||
data = (DataCachePCData) dataMap.get(
|
||||
(OpenJPAId) sm.getObjectId());
|
||||
|
||||
if (sm.getManagedInstance() == null) {
|
||||
data = cache.get(sm.getObjectId());
|
||||
if (data != null) {
|
||||
//### the 'data.type' access here probably needs
|
||||
//### to be addressed for bug 511
|
||||
|
@ -442,8 +474,8 @@ public class DataCacheStoreManager
|
|||
unloaded = addUnloaded(sm, fields, unloaded);
|
||||
} else
|
||||
unloaded = addUnloaded(sm, null, unloaded);
|
||||
} else if (!cache.contains(sm.getObjectId()))
|
||||
unloaded = addUnloaded(sm, null, unloaded);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (unloaded == null)
|
||||
|
|
|
@ -20,6 +20,8 @@ package org.apache.openjpa.datacache;
|
|||
|
||||
import java.util.BitSet;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.ObjectUtils;
|
||||
import org.apache.openjpa.util.RuntimeExceptionTranslator;
|
||||
|
@ -333,4 +335,14 @@ public class DelegatingDataCache
|
|||
throw translate(re);
|
||||
}
|
||||
}
|
||||
|
||||
public Map getAll(List keys) {
|
||||
if (_cache == null)
|
||||
return null;
|
||||
try {
|
||||
return _cache.getAll(keys);
|
||||
} catch (RuntimeException re) {
|
||||
throw translate(re);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,9 +75,8 @@ public abstract class AbstractPCData
|
|||
case JavaTypes.COLLECTION:
|
||||
ProxyDataList c = (ProxyDataList) data;
|
||||
Collection c2 = (Collection) sm.newFieldProxy(fmd.getIndex());
|
||||
for (int i = 0; i < c.size(); i++)
|
||||
c2.add(toNestedField(sm, fmd.getElement(), c.get(i),
|
||||
fetch, context));
|
||||
c2 = toNestedFields(sm, fmd.getElement(), (Collection) data,
|
||||
fetch, context);
|
||||
if (c2 instanceof Proxy) {
|
||||
ChangeTracker ct = ((Proxy) c2).getChangeTracker();
|
||||
if (ct != null)
|
||||
|
@ -87,17 +86,18 @@ public abstract class AbstractPCData
|
|||
case JavaTypes.MAP:
|
||||
Map m = (Map) data;
|
||||
Map m2 = (Map) sm.newFieldProxy(fmd.getIndex());
|
||||
Map.Entry e;
|
||||
Object key;
|
||||
Object value;
|
||||
for (Iterator mi = m.entrySet().iterator(); mi.hasNext();) {
|
||||
e = (Map.Entry) mi.next();
|
||||
key = toNestedField(sm, fmd.getKey(), e.getKey(),
|
||||
fetch, context);
|
||||
value = toNestedField(sm, fmd.getElement(), e.getValue(),
|
||||
fetch, context);
|
||||
m2.put(key, value);
|
||||
}
|
||||
Collection keys = new ArrayList (m.size());
|
||||
|
||||
for (Iterator mi = m.entrySet().iterator(); mi.hasNext();)
|
||||
keys.add(mi.next());
|
||||
|
||||
Object[] keyArray = keys.toArray();
|
||||
Object[] values = toNestedFields(sm, fmd.getElement(),
|
||||
keys, fetch, context).toArray();
|
||||
int idx = 0;
|
||||
for (Iterator mi = m.entrySet().iterator(); mi.hasNext(); idx++)
|
||||
m2.put(keyArray[idx], values[idx]);
|
||||
|
||||
return m2;
|
||||
case JavaTypes.ARRAY:
|
||||
int length = Array.getLength(data);
|
||||
|
@ -151,6 +151,51 @@ public abstract class AbstractPCData
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the given data value to its field value. The data value
|
||||
* may be a key, value, or element of a map or collection.
|
||||
*/
|
||||
protected Collection toNestedFields(OpenJPAStateManager sm,
|
||||
ValueMetaData vmd, Collection data, FetchConfiguration fetch,
|
||||
Object context) {
|
||||
if (data == null)
|
||||
return null;
|
||||
|
||||
Collection ret = new ArrayList(data.size());
|
||||
switch (vmd.getDeclaredTypeCode()) {
|
||||
case JavaTypes.DATE:
|
||||
for (Iterator itr=data.iterator(); itr.hasNext();)
|
||||
ret.add(((Date)itr.next()).clone());
|
||||
return ret;
|
||||
case JavaTypes.LOCALE:
|
||||
for (Iterator itr=data.iterator(); itr.hasNext();)
|
||||
ret.add((Locale) itr.next());
|
||||
return ret;
|
||||
case JavaTypes.PC:
|
||||
if (vmd.isEmbedded())
|
||||
for (Iterator itr=data.iterator(); itr.hasNext();)
|
||||
ret.add(toEmbeddedField(sm, vmd, itr.next(), fetch
|
||||
, context));
|
||||
// no break
|
||||
case JavaTypes.PC_UNTYPED:
|
||||
Object[] r = toRelationFields(sm, data, fetch);
|
||||
if (r != null) {
|
||||
for (int i = 0; i < r.length; i++)
|
||||
if (r[i] != null)
|
||||
ret.add(r[i]);
|
||||
else {
|
||||
ret.add(sm.getContext().getConfiguration().
|
||||
getOrphanedKeyActionInstance().
|
||||
orphan(data, sm, vmd));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
default:
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transform the given data into a relation field value. Default
|
||||
* implementation assumes the data is an oid.
|
||||
|
@ -160,6 +205,15 @@ public abstract class AbstractPCData
|
|||
return sm.getContext().find(data, fetch, null, null, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the given data into relation field values. Default
|
||||
* implementation assumes the data is an oid.
|
||||
*/
|
||||
protected Object[] toRelationFields(OpenJPAStateManager sm,
|
||||
Object data, FetchConfiguration fetch) {
|
||||
return sm.getContext().findAll((Collection) data, fetch, null, null, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the given data into an embedded PC field value. Default
|
||||
* implementation assumes the data is an {@link AbstractPCData}.
|
||||
|
|
|
@ -184,6 +184,7 @@ public class BrokerImpl
|
|||
private Set _updatedClss = null;
|
||||
private Set _deletedClss = null;
|
||||
private Set _pending = null;
|
||||
private int findAllDepth = 0;
|
||||
|
||||
// track instances that become transactional after the first savepoint
|
||||
// (the first uses the transactional cache)
|
||||
|
@ -903,6 +904,8 @@ public class BrokerImpl
|
|||
*/
|
||||
protected Object[] findAll(Collection oids, FetchConfiguration fetch,
|
||||
BitSet exclude, Object edata, int flags, FindCallbacks call) {
|
||||
findAllDepth ++;
|
||||
|
||||
// throw any exceptions for null oids up immediately
|
||||
if (oids == null)
|
||||
throw new NullPointerException("oids == null");
|
||||
|
@ -912,7 +915,9 @@ public class BrokerImpl
|
|||
// we have to use a map of oid->sm rather than a simple
|
||||
// array, so that we make sure not to create multiple sms for equivalent
|
||||
// oids if the user has duplicates in the given array
|
||||
if (_loading == null)
|
||||
_loading = new HashMap((int) (oids.size() * 1.33 + 1));
|
||||
|
||||
if (call == null)
|
||||
call = this;
|
||||
if (fetch == null)
|
||||
|
@ -1007,6 +1012,8 @@ public class BrokerImpl
|
|||
} catch (RuntimeException re) {
|
||||
throw new GeneralException(re);
|
||||
} finally {
|
||||
findAllDepth--;
|
||||
if (findAllDepth == 0)
|
||||
_loading = null;
|
||||
endOperation();
|
||||
}
|
||||
|
|
|
@ -136,6 +136,7 @@ public class PCDataImpl
|
|||
loadImplData(sm);
|
||||
|
||||
FieldMetaData[] fmds = sm.getMetaData().getFields();
|
||||
((StateManagerImpl)sm).setLoading(true);
|
||||
for (int i = 0; i < fmds.length; i++) {
|
||||
// load intermediate data for all unloaded fields and data for
|
||||
// fields in configured fetch groups
|
||||
|
|
Loading…
Reference in New Issue