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