You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2009/10/16 07:07:57 UTC
svn commit: r825768 - in /openjpa/trunk:
openjpa-kernel/src/main/java/org/apache/openjpa/conf/
openjpa-kernel/src/main/java/org/apache/openjpa/datacache/
openjpa-kernel/src/main/java/org/apache/openjpa/kernel/
openjpa-kernel/src/main/resources/org/apac...
Author: ppoddar
Date: Fri Oct 16 05:07:56 2009
New Revision: 825768
URL: http://svn.apache.org/viewvc?rev=825768&view=rev
Log:
OPENJPA-1334: Support partitioned cache with instance-level distribution policy
Added:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheDistributionPolicy.java (with props)
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/PartitionedDataCache.java (with props)
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestPartionedDataCache.java (with props)
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/ConcurrentDataCache.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/DataCacheManager.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCachePCDataImpl.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/BrokerImpl.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/InverseManager.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCData.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCDataImpl.java
openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/datacache/localizer.properties
openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java?rev=825768&r1=825767&r2=825768&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java Fri Oct 16 05:07:56 2009
@@ -28,6 +28,7 @@
import org.apache.openjpa.datacache.DataCacheManager;
import org.apache.openjpa.datacache.DataCacheManagerImpl;
import org.apache.openjpa.datacache.DataCacheMode;
+import org.apache.openjpa.datacache.PartitionedDataCache;
import org.apache.openjpa.ee.ManagedRuntime;
import org.apache.openjpa.enhance.RuntimeUnenhancedClassesModes;
import org.apache.openjpa.event.BrokerFactoryEventManager;
@@ -238,7 +239,8 @@
aliases = new String[] {
"false", null,
"true", ConcurrentDataCache.class.getName(),
- "concurrent", ConcurrentDataCache.class.getName(),
+ "concurrent", ConcurrentDataCache.class.getName(),
+ "partitioned", PartitionedDataCache.class.getName(),
};
dataCachePlugin.setAliases(aliases);
dataCachePlugin.setDefault(aliases[0]);
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?rev=825768&r1=825767&r2=825768&view=diff
==============================================================================
--- 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 Oct 16 05:07:56 2009
@@ -22,6 +22,7 @@
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -475,6 +476,20 @@
public Set<String> getExcludedTypes() {
return _excludedTypes;
}
+
+ public boolean isExcludedType(String type) {
+ if (_excludedTypes != null) {
+ if (_excludedTypes.contains(type)) {
+ return true;
+ }
+ }
+ if (_includedTypes != null) {
+ if (!_includedTypes.contains(type)) {
+ return true;
+ }
+ }
+ return false;
+ }
public void setTypes(Set<String> types) {
_includedTypes = types;
@@ -495,4 +510,25 @@
StringUtils.isEmpty(types) ? null : new HashSet<String>(Arrays
.asList(Strings.split(types, ";", 0)));
}
+
+ /**
+ *
+ */
+ public DataCache getPartition(String name, boolean create) {
+ if (StringUtils.equals(_name, name))
+ return this;
+ return null;
+ }
+
+ /**
+ *
+ */
+ public Set<String> getPartitionNames() {
+ return Collections.emptySet();
+ }
+
+ public boolean isPartitioned() {
+ return false;
+ }
+
}
Added: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheDistributionPolicy.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheDistributionPolicy.java?rev=825768&view=auto
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheDistributionPolicy.java (added)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheDistributionPolicy.java Fri Oct 16 05:07:56 2009
@@ -0,0 +1,38 @@
+package org.apache.openjpa.datacache;
+
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.meta.ClassMetaData;
+
+/**
+ * A policy determines the name of the cache where a given entity state will be cached.
+ *
+ * @author Pinaki Poddar
+ *
+ * @since 2.0.0
+ *
+ */
+public interface CacheDistributionPolicy {
+ /**
+ * Selects the name of the cache where the given managed proxy object state be cached.
+ *
+ * @param sm the managed proxy object to be cached
+ * @param context the context of invocation. No specific semantics is
+ * attributed currently. Can be null.
+ *
+ * @return name of the cache or null if the managed instance need not be cached.
+ */
+ String selectCache(OpenJPAStateManager sm, Object context);
+
+ /**
+ * A default implementation that selects the cache by the type of the given
+ * managed instance.
+ *
+ * @see ClassMetaData#getDataCacheName()
+ *
+ */
+ public static class Default implements CacheDistributionPolicy {
+ public String selectCache(OpenJPAStateManager sm, Object context) {
+ return sm.getMetaData().getDataCacheName();
+ }
+ }
+}
Propchange: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheDistributionPolicy.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/ConcurrentDataCache.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/ConcurrentDataCache.java?rev=825768&r1=825767&r2=825768&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/ConcurrentDataCache.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/ConcurrentDataCache.java Fri Oct 16 05:07:56 2009
@@ -18,6 +18,8 @@
*/
package org.apache.openjpa.datacache;
+import java.util.List;
+
import org.apache.openjpa.event.RemoteCommitListener;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.util.CacheMap;
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?rev=825768&r1=825767&r2=825768&view=diff
==============================================================================
--- 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 Oct 16 05:07:56 2009
@@ -22,6 +22,7 @@
import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.apache.openjpa.lib.util.Closeable;
@@ -36,6 +37,7 @@
* @see DataCachePCData#isTimedOut
* @author Patrick Linskey
* @author Abe White
+ * @author Pinaki Poddar
*/
public interface DataCache
extends Closeable {
@@ -270,6 +272,34 @@
public Map<Object,DataCachePCData> getAll(List<Object> keys);
/**
+ * Gets the named partition. Note that a partition itself is another cache.
+ *
+ * @param name name of the given partition.
+ *
+ * @param create if true optionally create a new partition.
+ *
+ * @return a partition of the given name. Or null, if either no such partition exists or can not be created.
+ * @since 2.0.0
+ */
+ public DataCache getPartition(String name, boolean create);
+
+ /**
+ * Gets the name of the known partitions.
+ *
+ * @return empty set if no partition exists.
+ *
+ * @since 2.0.0
+ */
+ public Set<String> getPartitionNames();
+
+ /**
+ * Affirms if this cache maintains partitions.
+ *
+ * @since 2.0.0
+ */
+ public boolean isPartitioned();
+
+ /**
* Returns number of read/write request and cache hit ratio data.
*/
public CacheStatistics getStatistics();
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManager.java?rev=825768&r1=825767&r2=825768&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManager.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManager.java Fri Oct 16 05:07:56 2009
@@ -19,6 +19,7 @@
package org.apache.openjpa.datacache;
import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.lib.conf.ObjectValue;
/**
@@ -69,6 +70,24 @@
* Return the runnable which schedules evictions.
*/
public DataCacheScheduler getDataCacheScheduler();
+
+ /**
+ * Select the cache where the given managed proxy instance should be cached.
+ * This decision <em>may</em> override the cache returned by
+ * {@link CacheDistributionPolicy#selectCache(OpenJPAStateManager, Object) policy}
+ * as specified by the user.
+ *
+ * @param sm the managed proxy instance
+ * @return the cache that will store the state of the given managed instance.
+ * @since 2.0.0
+ */
+ public DataCache selectCache(OpenJPAStateManager sm);
+
+ /**
+ * Return the policy that suggests the cache where a managed entity state is stored.
+ * @since 2.0.0
+ */
+ public CacheDistributionPolicy getDistributionPolicy();
/**
* Close all caches.
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java?rev=825768&r1=825767&r2=825768&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java Fri Oct 16 05:07:56 2009
@@ -19,6 +19,7 @@
package org.apache.openjpa.datacache;
import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.lib.conf.ObjectValue;
import org.apache.openjpa.lib.util.Closeable;
import org.apache.openjpa.util.ImplHelper;
@@ -36,21 +37,20 @@
private QueryCache _queryCache = null;
private DataCachePCDataGenerator _pcGenerator = null;
private DataCacheScheduler _scheduler = null;
+ private CacheDistributionPolicy _policy = new CacheDistributionPolicy.Default();
- public void initialize(OpenJPAConfiguration conf, ObjectValue dataCache,
- ObjectValue queryCache) {
+ public void initialize(OpenJPAConfiguration conf, ObjectValue dataCache, ObjectValue queryCache) {
_cache = (DataCache) dataCache.instantiate(DataCache.class, conf);
if (_cache == null)
return;
-
+
// create helpers before initializing caches
if (conf.getDynamicDataStructs())
_pcGenerator = new DataCachePCDataGenerator(conf);
_scheduler = new DataCacheScheduler(conf);
_cache.initialize(this);
- _queryCache = (QueryCache) queryCache.instantiate(QueryCache.class,
- conf);
+ _queryCache = (QueryCache) queryCache.instantiate(QueryCache.class, conf);
if (_queryCache != null)
_queryCache.initialize(this);
}
@@ -63,9 +63,14 @@
return getDataCache(name, false);
}
+ /**
+ * Returns the named cache.
+ */
public DataCache getDataCache(String name, boolean create) {
if (name == null || (_cache != null && name.equals(_cache.getName())))
return _cache;
+ if (_cache != null)
+ return _cache.getPartition(name, create);
return null;
}
@@ -87,4 +92,22 @@
if (_scheduler != null)
_scheduler.stop();
}
+
+ public DataCache selectCache(OpenJPAStateManager sm) {
+ if (sm == null)
+ return null;
+ if (_cache instanceof AbstractDataCache
+ && ((AbstractDataCache)_cache).isExcludedType(sm.getMetaData().getDescribedType().getName()))
+ return null;
+ String name = _policy.selectCache(sm, null);
+ return name == null ? null : getDataCache(name);
+ }
+
+ public CacheDistributionPolicy getDistributionPolicy() {
+ return _policy;
+ }
+
+ public void setDistributionPolicy(CacheDistributionPolicy policy) {
+ _policy = policy;
+ }
}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCachePCDataImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCachePCDataImpl.java?rev=825768&r1=825767&r2=825768&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCachePCDataImpl.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCachePCDataImpl.java Fri Oct 16 05:07:56 2009
@@ -37,6 +37,7 @@
*
* @author Patrick Linskey
*/
+@SuppressWarnings("serial")
public class DataCachePCDataImpl
extends PCDataImpl
implements DataCachePCData {
@@ -46,8 +47,8 @@
/**
* Constructor.
*/
- public DataCachePCDataImpl(Object oid, ClassMetaData meta) {
- super(oid, meta);
+ public DataCachePCDataImpl(Object oid, ClassMetaData meta, String name) {
+ super(oid, meta, name);
int timeout = meta.getDataCacheTimeout();
if (timeout > 0)
@@ -130,7 +131,7 @@
* order.
*/
protected void storeField(OpenJPAStateManager sm, FieldMetaData fmd) {
- if (fmd.getManagement() != fmd.MANAGE_PERSISTENT)
+ if (fmd.getManagement() != FieldMetaData.MANAGE_PERSISTENT)
return;
int index = fmd.getIndex();
@@ -160,25 +161,22 @@
* in inverse relation. If it is, clear the other field cache because it
* could be out of order.
*/
- protected void clearInverseRelationCache(OpenJPAStateManager sm,
- FieldMetaData fmd) {
+ protected void clearInverseRelationCache(OpenJPAStateManager sm, FieldMetaData fmd) {
+ DataCache cache = sm.getMetaData().getDataCache();
+ if (cache == null)
+ return;
ClassMetaData cmd = sm.getMetaData();
FieldMetaData[] fields = cmd.getFields();
for (int i = 0; i < fields.length; i++) {
FieldMetaData[] inverses = fields[i].getInverseMetaDatas();
if (inverses.length == 0)
continue;
- for (int j = 0; j < inverses.length; j++) {
- if (inverses[j].getOrderDeclaration()
- .indexOf(fmd.getName()) != -1) {
- DataCache cache = sm.getMetaData().getDataCache();
+ for (FieldMetaData inverse : inverses) {
+ if (inverse.getOrderDeclaration().indexOf(fmd.getName()) != -1) {
Object oid = sm.getContext().getObjectId(sm.fetch(i));
- DataCachePCData data = cache == null ? null
- : cache.get(oid);
- if ((data != null) &&
- (data instanceof DataCachePCDataImpl)) {
- ((DataCachePCDataImpl) data)
- .clearData(inverses[j].getIndex());
+ DataCachePCData data = cache.get(oid);
+ if (data instanceof DataCachePCDataImpl) {
+ ((DataCachePCDataImpl) data).clearData(inverse.getIndex());
}
}
}
@@ -209,6 +207,6 @@
}
public AbstractPCData newEmbeddedPCData(OpenJPAStateManager sm) {
- return new DataCachePCDataImpl(sm.getId(), sm.getMetaData());
+ return new DataCachePCDataImpl(sm.getId(), sm.getMetaData(), getCache());
}
}
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?rev=825768&r1=825767&r2=825768&view=diff
==============================================================================
--- 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 Oct 16 05:07:56 2009
@@ -34,6 +34,7 @@
import org.apache.openjpa.kernel.DataCacheStoreMode;
import org.apache.openjpa.kernel.DelegatingStoreManager;
import org.apache.openjpa.kernel.FetchConfiguration;
+import org.apache.openjpa.kernel.FindCallbacks;
import org.apache.openjpa.kernel.LockLevels;
import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.kernel.PCState;
@@ -62,7 +63,7 @@
// the owning context
private StoreContext _ctx = null;
-
+ private DataCacheManager _mgr = null;
// pc data generator
private PCDataGenerator _gen = null;
@@ -77,7 +78,8 @@
public void setContext(StoreContext ctx) {
_ctx = ctx;
- _gen = ctx.getConfiguration().getDataCacheManagerInstance().getPCDataGenerator();
+ _mgr = ctx.getConfiguration().getDataCacheManagerInstance();
+ _gen = _mgr.getPCDataGenerator();
super.setContext(ctx);
}
@@ -113,8 +115,7 @@
if (classes.isEmpty())
return;
- MetaDataRepository mdr = _ctx.getConfiguration().
- getMetaDataRepositoryInstance();
+ MetaDataRepository mdr = _ctx.getConfiguration().getMetaDataRepositoryInstance();
ClassLoader loader = _ctx.getClassLoader();
DataCache cache;
@@ -141,7 +142,7 @@
// create pc datas for inserts
if (_ctx.getPopulateDataCache() && _inserts != null) {
for (OpenJPAStateManager sm : _inserts) {
- cache = sm.getMetaData().getDataCache();
+ cache = _mgr.selectCache(sm);
if (cache == null)
continue;
@@ -160,7 +161,7 @@
sm = entry.getKey();
fields = entry.getValue();
- cache = sm.getMetaData().getDataCache();
+ cache = _mgr.selectCache(sm);
if (cache == null) {
continue;
}
@@ -190,7 +191,7 @@
// remove pcdatas for deletes
if (_deletes != null) {
for (OpenJPAStateManager sm : _deletes) {
- cache = sm.getMetaData().getDataCache();
+ cache = _mgr.selectCache(sm);
if (cache == null)
continue;
@@ -290,7 +291,7 @@
}
public boolean exists(OpenJPAStateManager sm, Object edata) {
- DataCache cache = sm.getMetaData().getDataCache();
+ DataCache cache = _mgr.selectCache(sm);
if (cache != null && !isLocking(null)
&& cache.contains(sm.getObjectId()))
return true;
@@ -298,7 +299,7 @@
}
public boolean syncVersion(OpenJPAStateManager sm, Object edata) {
- DataCache cache = sm.getMetaData().getDataCache();
+ DataCache cache = _mgr.selectCache(sm);
if (cache == null || sm.isEmbedded())
return super.syncVersion(sm, edata);
@@ -323,7 +324,7 @@
public boolean initialize(OpenJPAStateManager sm, PCState state, FetchConfiguration fetch, Object edata) {
boolean fromDatabase;
- DataCache cache = sm.getMetaData().getDataCache();
+ DataCache cache = _mgr.selectCache(sm);
DataCachePCData data = null;
boolean updateCache = _ctx.getCacheStoreMode() != DataCacheStoreMode.BYPASS && _ctx.getPopulateDataCache();
if (cache == null || sm.isEmbedded() || _ctx.getCacheRetrieveMode() == DataCacheRetrieveMode.BYPASS
@@ -353,7 +354,7 @@
}
private void cacheStateManager(DataCache cache, OpenJPAStateManager sm, DataCachePCData data) {
- if(sm.isFlushed()) {
+ if (sm.isFlushed()) {
return;
}
// make sure that we're not trying to cache an old version
@@ -383,7 +384,7 @@
public boolean load(OpenJPAStateManager sm, BitSet fields,
FetchConfiguration fetch, int lockLevel, Object edata) {
- DataCache cache = sm.getMetaData().getDataCache();
+ DataCache cache = _mgr.selectCache(sm);
if (cache == null || sm.isEmbedded() || _ctx.getCacheRetrieveMode() == DataCacheRetrieveMode.BYPASS)
return super.load(sm, fields, fetch, lockLevel, edata);
@@ -421,7 +422,7 @@
BitSet fields;
for (OpenJPAStateManager sm : sms) {
- cache = sm.getMetaData().getDataCache();
+ cache = _mgr.selectCache(sm);
if (cache == null || sm.isEmbedded()) {
unloaded = addUnloaded(sm, null, unloaded);
continue;
@@ -494,7 +495,7 @@
OpenJPAStateManager sm = entry.getKey();
fields = entry.getValue();
- cache = sm.getMetaData().getDataCache();
+ cache = _mgr.selectCache(sm);
if (cache == null || sm.isEmbedded() || (failed != null
&& failed.contains(sm.getId())))
continue;
@@ -607,8 +608,7 @@
// this logic could be more efficient -- we could aggregate
// all the cache->oid changes, and then use DataCache.removeAll()
// and less write locks to do the mutation.
- ClassMetaData meta = sm.getMetaData();
- DataCache cache = meta.getDataCache();
+ DataCache cache = _mgr.selectCache(sm);
if (cache == null)
return;
@@ -684,7 +684,7 @@
ClassMetaData meta = sm.getMetaData();
if (_gen != null)
return (DataCachePCData) _gen.generatePCData(sm.getObjectId(), meta);
- return new DataCachePCDataImpl(sm.fetchObjectId(), meta);
+ return new DataCachePCDataImpl(sm.fetchObjectId(), meta, _mgr.selectCache(sm).getName());
}
/**
@@ -694,8 +694,8 @@
if (fetch == null)
fetch = _ctx.getFetchConfiguration();
return fetch.getReadLockLevel() > LockLevels.LOCK_NONE;
- }
-
+ }
+
/**
* Structure used during the commit process to track cache modifications.
*/
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?rev=825768&r1=825767&r2=825768&view=diff
==============================================================================
--- 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 Oct 16 05:07:56 2009
@@ -22,6 +22,7 @@
import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.apache.commons.lang.ObjectUtils;
import org.apache.openjpa.util.RuntimeExceptionTranslator;
@@ -125,8 +126,8 @@
}
}
- public void commit(Collection additions, Collection newUpdates,
- Collection existingUpdates, Collection deletes) {
+ public void commit(Collection<DataCachePCData> additions, Collection<DataCachePCData> newUpdates,
+ Collection<DataCachePCData> existingUpdates, Collection<Object> deletes) {
if (_cache == null)
return;
try {
@@ -146,7 +147,7 @@
}
}
- public BitSet containsAll(Collection oids) {
+ public BitSet containsAll(Collection<Object> oids) {
if (_cache == null)
return EMPTY_BITSET;
try {
@@ -196,7 +197,7 @@
}
}
- public BitSet removeAll(Collection oids) {
+ public BitSet removeAll(Collection<Object> oids) {
if (_cache == null)
return EMPTY_BITSET;
try {
@@ -206,7 +207,7 @@
}
}
- public void removeAll(Class cls, boolean subclasses) {
+ public void removeAll(Class<?> cls, boolean subclasses) {
if (_cache == null)
return;
try {
@@ -236,7 +237,7 @@
}
}
- public BitSet pinAll(Collection oids) {
+ public BitSet pinAll(Collection<Object> oids) {
if (_cache == null)
return EMPTY_BITSET;
try {
@@ -246,7 +247,7 @@
}
}
- public void pinAll(Class cls, boolean subs) {
+ public void pinAll(Class<?> cls, boolean subs) {
if (_cache == null)
return;
try {
@@ -266,7 +267,7 @@
}
}
- public BitSet unpinAll(Collection oids) {
+ public BitSet unpinAll(Collection<Object> oids) {
if (_cache == null)
return EMPTY_BITSET;
try {
@@ -276,7 +277,7 @@
}
}
- public void unpinAll(Class cls, boolean subs) {
+ public void unpinAll(Class<?> cls, boolean subs) {
if (_cache == null)
return;
try {
@@ -336,7 +337,7 @@
}
}
- public Map getAll(List keys) {
+ public Map<Object,DataCachePCData> getAll(List<Object> keys) {
if (_cache == null)
return null;
try {
@@ -349,4 +350,35 @@
public CacheStatistics getStatistics() {
return (_cache == null) ? null : _cache.getStatistics();
}
+
+
+ public DataCache getPartition(String name, boolean create) {
+ if (_cache == null)
+ return null;
+ try {
+ return _cache.getPartition(name, create);
+ } catch (RuntimeException re) {
+ throw translate(re);
+ }
+ }
+
+ public Set<String> getPartitionNames() {
+ if (_cache == null)
+ return null;
+ try {
+ return _cache.getPartitionNames();
+ } catch (RuntimeException re) {
+ throw translate(re);
+ }
+ }
+
+ public boolean isPartitioned() {
+ if (_cache == null)
+ return false;
+ try {
+ return _cache.isPartitioned();
+ } catch (RuntimeException re) {
+ throw translate(re);
+ }
+ }
}
Added: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/PartitionedDataCache.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/PartitionedDataCache.java?rev=825768&view=auto
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/PartitionedDataCache.java (added)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/PartitionedDataCache.java Fri Oct 16 05:07:56 2009
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.openjpa.datacache;
+
+import java.lang.reflect.Array;
+import java.security.AccessController;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.openjpa.lib.conf.PluginListValue;
+import org.apache.openjpa.lib.conf.Value;
+import org.apache.openjpa.lib.util.J2DoPrivHelper;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * A partitioned data cache maintains a set of partitions that are DataCache themselves.
+ * Each of the partitioned DataCaches can be individually configured.
+ * However, all partitions must be of the same type. By default, this cache uses
+ * {@linkplain ConcurrentDataCache} as its partitions.
+ * <br>
+ * This cache can be configured as a plug-in as follows:
+ * <br>
+ * <code><property name='openjpa.DataCache"
+ * value="partitioned(name=X, PartitionType=concurrent,Partitions='(name=a,cacheSize=100),
+ * (name=b,cacheSize=200)')</code>
+ * <br>
+ * Notice that the individual partition properties are enclosed parentheses, separated by comma
+ * and finally the whole property string is enclosed in single quote.
+ * Each partition must have a non-empty name that are unique among the partitions.
+ * The {@linkplain CacheDistributionPolicy policy} can return
+ * the name of a partition to distribute the managed instances to be cached in respective partition.
+ *
+ * The above configuration will configure a partitioned cache named <code>X</code> with two partitions named
+ * <code>a</code> and <code>b</code> with cache size <code>100</code> and <code>200</code> respectively.
+ * Besides the two partitions, this cache instance itself can store data and referred by its own name
+ * (<code>X</code> in the above example).
+ * <br>
+ *
+ * @author Pinaki Poddar
+ *
+ * @since 2.0.0
+ */
+@SuppressWarnings("serial")
+public class PartitionedDataCache extends ConcurrentDataCache {
+ private static final Localizer _loc = Localizer.forPackage(PartitionedDataCache.class);
+ private Class<? extends DataCache> _type = ConcurrentDataCache.class;
+ private final List<String> _partProperties = new ArrayList<String>();
+ private final Map<String, DataCache> _partitions = new HashMap<String, DataCache>();
+
+ /**
+ * Sets the type of the partitions.
+ * Each partition is a DataCache itself.
+ *
+ * @param type the name of the type that implements {@linkplain DataCache} interface.
+ * Aliases such as <code>"concurrent"</code> is also recognized.
+ *
+ * @throws Exception if the given type is not resolvable to a loadable type.
+ */
+ public void setPartitionType(String type) throws Exception {
+ Value value = conf.getValue("DataCache");
+ ClassLoader ctxLoader = AccessController.doPrivileged(J2DoPrivHelper.getContextClassLoaderAction());
+ ClassLoader loader = conf.getClassResolverInstance().getClassLoader(null, ctxLoader);
+ _type = (Class<? extends DataCache>) AccessController.doPrivileged(
+ J2DoPrivHelper.getForNameAction(value.unalias(type), true, loader));
+ }
+
+ /**
+ * Set partitions from a String configuration.
+ *
+ * @param parts a String of the form <code>(p1, p2, p3)</code> where p1, p2 etc. itself are plug-in strings
+ * for individual Data Cache configuration.
+ */
+ public void setPartitions(String parts) {
+ _partProperties.clear();
+ parsePartitionProperties(parts);
+ PluginListValue partitions = new PluginListValue("partitions");
+ String[] types = (String[])Array.newInstance(String.class, _partProperties.size());
+ Arrays.fill(types, _type.getName());
+ partitions.setClassNames(types);
+ partitions.setProperties(_partProperties.toArray(new String[_partProperties.size()]));
+ DataCache[] array = (DataCache[])partitions.instantiate(_type, conf);
+ for (DataCache part : array) {
+ if (part.getName() == null)
+ throw new UserException(_loc.get("partition-cache-null-partition", parts));
+ if (_partitions.containsKey(part.getName()))
+ throw new UserException(_loc.get("partition-cache-duplicate-partition", part.getName(), parts));
+ if (part.getName().equals(DataCache.NAME_DEFAULT))
+ throw new UserException(_loc.get("partition-cache-default-partition", part.getName(), parts));
+ _partitions.put(part.getName(), part);
+ }
+ }
+
+ /**
+ * Returns the individual partition configuration properties.
+ */
+ public List<String> getPartitions() {
+ return _partProperties;
+ }
+
+ public DataCache getPartition(String name, boolean create) {
+ return _partitions.get(name);
+ }
+
+ /**
+ * Gets the name of the configured partitions.
+ */
+ public Set<String> getPartitionNames() {
+ return _partitions.keySet();
+ }
+
+ /**
+ * Always returns true.
+ */
+ public final boolean isPartitioned() {
+ return !_partitions.isEmpty();
+ }
+
+ public void endConfiguration() {
+ if (!isPartitioned())
+ conf.getConfigurationLog().warn(_loc.get("partition-cache-no-config"));
+ }
+
+ /**
+ * Parses property string of the form <code>(p1),(p2),(p3)</code> to produce a list of
+ * <code>p1</code>, <code>p2</code> and <code>p3</code>. The component strings
+ * <code>p1</code> etc. must be enclosed in parentheses and separated by comma.
+ * plug-in string to produce a list of
+ *
+ * @param properties property string of the form <code>(p1),(p2),(p3)</code>
+ */
+ private void parsePartitionProperties(String full) {
+ String properties = new String(full);
+ while (true) {
+ if (properties == null)
+ break;
+ properties = properties.trim();
+ if (properties.length() == 0)
+ break;
+ if (properties.startsWith(",")) {
+ properties = properties.substring(1);
+ } else if (!_partProperties.isEmpty()) {
+ throw new UserException(_loc.get("partition-cache-parse-error-comma", full, properties));
+ }
+ if (properties.startsWith("(") && properties.endsWith(")")) {
+ int i = properties.indexOf(")");
+ String p = properties.substring(1,i); // exclude the end parentheses
+ _partProperties.add(p);
+ if (i < properties.length()-1) {
+ properties = properties.substring(i+1);
+ } else {
+ break;
+ }
+ } else {
+ throw new UserException(_loc.get("partition-cache-parse-error-paren", full, properties));
+ }
+ }
+ }
+}
Propchange: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/PartitionedDataCache.java
------------------------------------------------------------------------------
svn:eol-style = native
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?rev=825768&r1=825767&r2=825768&view=diff
==============================================================================
--- 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 Oct 16 05:07:56 2009
@@ -3212,7 +3212,7 @@
sm.evict();
if (_evictDataCache && sm.getObjectId() != null) {
- DataCache cache = sm.getMetaData().getDataCache();
+ DataCache cache = _conf.getDataCacheManagerInstance().selectCache(sm);
if (cache != null)
cache.remove(sm.getObjectId());
}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/InverseManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/InverseManager.java?rev=825768&r1=825767&r2=825768&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/InverseManager.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/InverseManager.java Fri Oct 16 05:07:56 2009
@@ -25,6 +25,7 @@
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.datacache.DataCache;
+import org.apache.openjpa.datacache.DataCacheManager;
import org.apache.openjpa.lib.conf.Configurable;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.lib.log.Log;
@@ -43,10 +44,11 @@
*/
public class InverseManager implements Configurable {
- private static final Localizer _loc = Localizer.forPackage
- (InverseManager.class);
+ private static final Localizer _loc = Localizer.forPackage(InverseManager.class);
protected static final Object NONE = new Object();
+
+ protected DataCacheManager _mgr;
/**
* Constant representing the {@link #ACTION_MANAGE} action
@@ -121,6 +123,7 @@
public void setConfiguration(Configuration conf) {
_log = conf.getLog(OpenJPAConfiguration.LOG_RUNTIME);
+ _mgr = ((OpenJPAConfiguration)conf).getDataCacheManagerInstance();
}
/**
@@ -214,7 +217,7 @@
// if the field isn't loaded in the state manager, it still might be
// loaded in the data cache, in which case we still have to correct
// it to keep the cache in sync
- DataCache cache = sm.getMetaData().getDataCache();
+ DataCache cache = _mgr.selectCache(sm);
if (cache == null)
return false;
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCData.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCData.java?rev=825768&r1=825767&r2=825768&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCData.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCData.java Fri Oct 16 05:07:56 2009
@@ -104,4 +104,9 @@
* Whether the given field index has stored data.
*/
public boolean isLoaded(int i);
+
+ /**
+ * Get the name of the cache where this data is stored.
+ */
+ public String getCache();
}
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?rev=825768&r1=825767&r2=825768&view=diff
==============================================================================
--- 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 Oct 16 05:07:56 2009
@@ -34,7 +34,8 @@
extends AbstractPCData {
private final Object _oid;
- private final Class _type;
+ private final Class<?> _type;
+ private final String _cache;
private final Object[] _data;
private final BitSet _loaded;
private Object _version = null;
@@ -44,9 +45,10 @@
/**
* Constructor.
*/
- public PCDataImpl(Object oid, ClassMetaData meta) {
+ public PCDataImpl(Object oid, ClassMetaData meta, String name) {
_oid = oid;
_type = meta.getDescribedType();
+ _cache = name;
int len = meta.getFields().length;
_data = new Object[len];
@@ -57,7 +59,7 @@
return _oid;
}
- public Class getType() {
+ public Class<?> getType() {
return _type;
}
@@ -317,6 +319,10 @@
* embedded instances. Returns a {@link PCDataImpl} by default.
*/
public AbstractPCData newEmbeddedPCData(OpenJPAStateManager sm) {
- return new PCDataImpl(sm.getId (), sm.getMetaData ());
+ return new PCDataImpl(sm.getId (), sm.getMetaData (), _cache);
}
+
+ public String getCache() {
+ return _cache;
+ }
}
Modified: openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/datacache/localizer.properties
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/datacache/localizer.properties?rev=825768&r1=825767&r2=825768&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/datacache/localizer.properties (original)
+++ openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/datacache/localizer.properties Fri Oct 16 05:07:56 2009
@@ -83,4 +83,33 @@
configuration string "{0}" are configured to be the default data cache. \
There must be one and only one cache whose name is "{1}", or whose name is \
not specified.
-
+partition-cache-no-config: You have specified a partitioned cache but have not \
+ configured any partition. Consult OpenJPA documentation at \
+ http://openjpa.apache.org/builds/latest/docs/manual/manual.html on how to \
+ configure partitioned cache.
+partition-cache-parse-error-paren: Failed to configure cache partitions from the \
+ supplied configuration "{0}" while parsing the part "{1}" because this part \
+ is not enclosed by parentheses. The proper \
+ configuration string for cache partitions is '(p1),(p2),(p3)' i.e. each \
+ partition plug-in is enclosed in parentheses, separated by comma and the \
+ final string is enclosed by single quote.
+partition-cache-parse-error-comma: Failed to configure cache partitions from the \
+ supplied configuration "{0}" while parsing the part "{1}" because this part \
+ is not separated by comma. The proper \
+ configuration string for cache partitions is '(p1),(p2),(p3)' i.e. each \
+ partition plug-in is enclosed in parentheses, separated by comma and the \
+ final string is enclosed by single quote.
+partition-cache-null-partition: You have not specified any name for a partition in \
+ the configuration "{0}". Each partition must have a name. \
+ Consult OpenJPA documentation at \
+ http://openjpa.apache.org/builds/latest/docs/manual/manual.html \
+ on how to configure partitioned cache.
+partition-cache-duplicate-partition: You have specified duplicate name "{0}" for \
+ partitions in the configuration "{0}". The partition names must be unique. \
+ Consult OpenJPA documentation at \
+ http://openjpa.apache.org/builds/latest/docs/manual/manual.html \
+ on how to configure partitioned cache.
+partition-cache-default-partition: You have specified name "{0}" for a \
+ partition in the configuration "{0}". The partition name matches the default \
+ name reserved by OpenJPA for internal use and hence can not be used.
+
\ No newline at end of file
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestPartionedDataCache.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestPartionedDataCache.java?rev=825768&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestPartionedDataCache.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestPartionedDataCache.java Fri Oct 16 05:07:56 2009
@@ -0,0 +1,92 @@
+package org.apache.openjpa.persistence.datacache;
+
+import org.apache.openjpa.datacache.CacheDistributionPolicy;
+import org.apache.openjpa.datacache.ConcurrentDataCache;
+import org.apache.openjpa.datacache.DataCache;
+import org.apache.openjpa.datacache.PartitionedDataCache;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.persistence.StoreCacheImpl;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+import org.apache.openjpa.util.UserException;
+
+public class TestPartionedDataCache extends SingleEMFTestCase {
+ public void setUp() {
+ super.setUp("openjpa.DataCache", "partitioned(PartitionType=concurrent,partitions="+
+ "'(name=a,cacheSize=100),(name=b,cacheSize=200)')",
+ "openjpa.RemoteCommitProvider", "sjvm",
+ "openjpa.DataCacheManager",
+ "DistributionPolicy=org.apache.openjpa.persistence.datacache.TestPartionedDataCache$TestPolicy");
+ }
+
+ public void testPropertyParsing() {
+ PartitionedDataCache cache = new PartitionedDataCache();
+ String badProperty = "(name=a,cacheSize=100),(name=b,cacheSize=200";// missing last bracket
+ try {
+ cache.setPartitions(badProperty);
+ fail("Expected parse error on " + badProperty);
+ } catch (UserException e) {
+ System.err.println(e);
+ }
+ badProperty = "(name=a,cacheSize=100)(name=b,cacheSize=200)";// missing comma
+ try {
+ cache.setPartitions(badProperty);
+ fail("Expected parse error on " + badProperty);
+ } catch (UserException e) {
+ System.err.println(e);
+ }
+ badProperty = "(cacheSize=100),(name=b,cacheSize=200)";// missing name
+ try {
+ cache.setPartitions(badProperty);
+ fail("Expected parse error on " + badProperty);
+ } catch (UserException e) {
+ System.err.println(e);
+ }
+ badProperty = "(name=a,cacheSize=100),(name=a,cacheSize=200)";// duplicate name
+ try {
+ cache.setPartitions(badProperty);
+ fail("Expected parse error on " + badProperty);
+ } catch (UserException e) {
+ System.err.println(e);
+ }
+ badProperty = "(name=default,cacheSize=100),(name=a,cacheSize=200)";// default name
+ try {
+ cache.setPartitions(badProperty);
+ fail("Expected parse error on " + badProperty);
+ } catch (UserException e) {
+ System.err.println(e);
+ }
+
+ }
+
+ public void testPolicy() {
+ CacheDistributionPolicy policy = emf.getConfiguration().getDataCacheManagerInstance().getDistributionPolicy();
+ assertNotNull(policy);
+ assertTrue(policy.getClass() + " not TestPolicy", policy instanceof TestPolicy);
+
+ }
+ public void testPluginConfiguration() {
+ DataCache cache = ((StoreCacheImpl)emf.getStoreCache()).getDelegate();
+ assertTrue(cache instanceof PartitionedDataCache);
+ assertFalse(cache.getPartitionNames().isEmpty());
+ assertNotNull(cache.getPartition("a", false));
+ assertNotNull(cache.getPartition("b", false));
+ assertNull(cache.getPartition("c", false));
+ assertCacheConfiguration("a", 100);
+ assertCacheConfiguration("b", 200);
+ }
+
+ void assertCacheConfiguration(String name, int size) {
+ DataCache cache = emf.getConfiguration().getDataCacheManagerInstance().getDataCache(name);
+ assertNotNull(cache);
+ assertTrue(cache instanceof ConcurrentDataCache);
+ assertEquals(size, ((ConcurrentDataCache)cache).getCacheSize());
+ }
+
+ public static class TestPolicy implements CacheDistributionPolicy {
+
+ public String selectCache(OpenJPAStateManager sm, Object context) {
+ return "a";
+ }
+
+ }
+}
Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestPartionedDataCache.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml?rev=825768&r1=825767&r2=825768&view=diff
==============================================================================
--- openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml (original)
+++ openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml Fri Oct 16 05:07:56 2009
@@ -151,6 +151,44 @@
</programlisting>
</example>
<para>
+OpenJPA also supports a partitioned cache configuration where the cached
+instances can be distributed across partitions by a application-defined
+policy. Each partition is a data cache by itself, identified by its name and can
+configured individually. The distribution policy
+determines the specific partition that stores the state of a managed instance.
+The default distribution policy distributes the instances by their type
+as specified by the <literal>name</literal> attribute in <literal>@DataCache</literal>
+annotation. Cache distribution policy is a simple interface that can be implemented
+by an application to distribute among the partitions per instance basis.
+To enable a partitioned cache set the <literal>openjpa.DataCache</literal>
+property to <literal>partitioned</literal>, and configure individual partitions
+as follows:
+ </para>
+ <example id="ref_guide_cache_conf_partition">
+ <title>
+ Partitioned Data Cache
+ </title>
+<programlisting>
+<property name="openjpa.DataCacheManager" value="DistributionPolicy=org.acme.foo.DistributionPolicy"/>
+<property name="openjpa.DataCache" value="partitioned(PartitionType=concurrent,partitions=
+ '(name=a,cacheSize=100),(name=b,cacheSize=200)')"/>
+</programlisting>
+ </example>
+ <para>
+The distribution policy is configured by a full-qualified class name that implements
+<literal>org.apache.openjpa.datacahe.CacheDistributionPolicy</lietral>. The partitions
+are specified as value of <literal>partitions</literal> attribute as a series of
+individually configurable plug-in strings. As the example shows, i) each partition plug-in configuration
+must be enclosed in parentheses, ii) must be separated by comma and iii) the complete
+set be enclosed in single quote. Each individual partition is a Data Cache by itself and
+class that implements the partition can be configured via <literal>PartitionType</literal>
+attribute. The above example configuration will configure a partitioned cache with
+two partitions named <literal>a</literal> and <literal>b</literal> of cache size 100 and 200
+respectively. The partitions are of <literal>concurrent</literal> type which is a mnemonic or alias
+for <literal>org.apache.openjpa.datacache.ConcurrentDataCache</literal>. The <literal>PartitionType</literal>
+is defaulted to <literal>concurrent</literal> though explicitly mentioned in this example.
+ </para>
+ <para>
To configure the data cache to remain up-to-date in a distributed environment,
set the <link linkend="openjpa.RemoteCommitProvider"><literal>
openjpa.RemoteCommitProvider</literal></link> property appropriately, or