You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by wi...@apache.org on 2007/07/20 22:37:12 UTC
svn commit: r558125 - in
/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa: datacache/
kernel/
Author: wisneskid
Date: Fri Jul 20 13:37:08 2007
New Revision: 558125
URL: http://svn.apache.org/viewvc?view=rev&rev=558125
Log:
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).
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCache.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DelegatingDataCache.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractPCData.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCDataImpl.java
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java?view=diff&rev=558125&r1=558124&r2=558125
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java Fri Jul 20 13:37:08 2007
@@ -21,7 +21,10 @@
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 @@
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;
+ }
}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCache.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCache.java?view=diff&rev=558125&r1=558124&r2=558125
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCache.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCache.java Fri Jul 20 13:37:08 2007
@@ -20,6 +20,7 @@
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 @@
* 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);
}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java?view=diff&rev=558125&r1=558124&r2=558125
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java Fri Jul 20 13:37:08 2007
@@ -41,6 +41,7 @@
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 @@
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,28 +425,57 @@
continue;
}
- 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
- sm.initialize(data.getType(), state);
- data.load(sm, fetch, edata);
- } else
- unloaded = addUnloaded(sm, null, unloaded);
- } else if (load != FORCE_LOAD_NONE
+ if (sm.getManagedInstance() == null
+ || load != FORCE_LOAD_NONE
|| sm.getPCState() == PCState.HOLLOW) {
- data = cache.get(sm.getObjectId());
- if (data != null) {
- // load unloaded fields
- fields = sm.getUnloaded(fetch);
- data.load(sm, fields, fetch, edata);
- if (fields.length() > 0)
- unloaded = addUnloaded(sm, fields, unloaded);
- } else
- unloaded = addUnloaded(sm, null, unloaded);
+ 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) {
+ if (data != null) {
+ //### the 'data.type' access here probably needs
+ //### to be addressed for bug 511
+ sm.initialize(data.getType(), state);
+ data.load(sm, fetch, edata);
+ } else
+ unloaded = addUnloaded(sm, null, unloaded);
+ } else if (load != FORCE_LOAD_NONE
+ || sm.getPCState() == PCState.HOLLOW) {
+ data = cache.get(sm.getObjectId());
+ if (data != null) {
+ // load unloaded fields
+ fields = sm.getUnloaded(fetch);
+ data.load(sm, fields, fetch, edata);
+ if (fields.length() > 0)
+ unloaded = addUnloaded(sm, fields, unloaded);
+ } else
+ unloaded = addUnloaded(sm, null, unloaded);
+ }
+ }
}
if (unloaded == null)
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DelegatingDataCache.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DelegatingDataCache.java?view=diff&rev=558125&r1=558124&r2=558125
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DelegatingDataCache.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DelegatingDataCache.java Fri Jul 20 13:37:08 2007
@@ -20,6 +20,8 @@
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 @@
throw translate(re);
}
}
+
+ public Map getAll(List keys) {
+ if (_cache == null)
+ return null;
+ try {
+ return _cache.getAll(keys);
+ } catch (RuntimeException re) {
+ throw translate(re);
+ }
+ }
}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractPCData.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractPCData.java?view=diff&rev=558125&r1=558124&r2=558125
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractPCData.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractPCData.java Fri Jul 20 13:37:08 2007
@@ -75,9 +75,8 @@
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 @@
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);
@@ -152,12 +152,66 @@
}
/**
+ * 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.
*/
protected Object toRelationField(OpenJPAStateManager sm, ValueMetaData vmd,
Object data, FetchConfiguration fetch, Object context) {
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);
}
/**
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java?view=diff&rev=558125&r1=558124&r2=558125
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java Fri Jul 20 13:37:08 2007
@@ -184,6 +184,7 @@
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 @@
*/
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 @@
// 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
- _loading = new HashMap((int) (oids.size() * 1.33 + 1));
+ if (_loading == null)
+ _loading = new HashMap((int) (oids.size() * 1.33 + 1));
+
if (call == null)
call = this;
if (fetch == null)
@@ -1007,7 +1012,9 @@
} catch (RuntimeException re) {
throw new GeneralException(re);
} finally {
- _loading = null;
+ findAllDepth--;
+ if (findAllDepth == 0)
+ _loading = null;
endOperation();
}
}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCDataImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCDataImpl.java?view=diff&rev=558125&r1=558124&r2=558125
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCDataImpl.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCDataImpl.java Fri Jul 20 13:37:08 2007
@@ -136,6 +136,7 @@
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