[infinispan-commits] Infinispan SVN: r1584 - in trunk: cachestore/bdbje/src/test/java/org/infinispan/loaders/bdbje and 16 other directories.
infinispan-commits at lists.jboss.org
infinispan-commits at lists.jboss.org
Wed Mar 10 08:42:41 EST 2010
Author: manik.surtani at jboss.com
Date: 2010-03-10 08:42:39 -0500 (Wed, 10 Mar 2010)
New Revision: 1584
Added:
trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/DatabaseType.java
Modified:
trunk/cachestore/bdbje/src/main/java/org/infinispan/loaders/bdbje/BdbjeCacheStore.java
trunk/cachestore/bdbje/src/test/java/org/infinispan/loaders/bdbje/BdbjeCacheStoreFunctionalIntegrationTest.java
trunk/cachestore/bdbje/src/test/java/org/infinispan/loaders/bdbje/BdbjeCacheStoreIntegrationTest.java
trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudCacheStore.java
trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/DataManipulationHelper.java
trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/TableManipulation.java
trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/binary/JdbcBinaryCacheStore.java
trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/binary/JdbcBinaryCacheStoreConfig.java
trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStore.java
trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStoreConfig.java
trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStore.java
trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStoreConfig.java
trunk/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStoreTest2.java
trunk/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStoreTest2.java
trunk/cachestore/jdbm/src/main/java/org/infinispan/loaders/jdbm/JdbmCacheStore.java
trunk/cachestore/jdbm/src/test/java/org/infinispan/loaders/jdbm/JdbmCacheStoreFunctionalTest.java
trunk/cachestore/jdbm/src/test/java/org/infinispan/loaders/jdbm/JdbmCacheStoreTest.java
trunk/core/src/main/java/org/infinispan/eviction/EvictionStrategy.java
trunk/core/src/main/java/org/infinispan/loaders/CacheLoader.java
trunk/core/src/main/java/org/infinispan/loaders/CacheLoaderManagerImpl.java
trunk/core/src/main/java/org/infinispan/loaders/LockSupportCacheStore.java
trunk/core/src/main/java/org/infinispan/loaders/cluster/ClusterCacheLoader.java
trunk/core/src/main/java/org/infinispan/loaders/decorators/AbstractDelegatingStore.java
trunk/core/src/main/java/org/infinispan/loaders/decorators/ChainingCacheStore.java
trunk/core/src/main/java/org/infinispan/loaders/file/FileCacheStore.java
trunk/core/src/test/java/org/infinispan/loaders/BaseCacheStoreTest.java
trunk/core/src/test/java/org/infinispan/loaders/dummy/DummyInMemoryCacheStore.java
Log:
[ISPN-310] (CacheLoader preload should only load as many entries as configured by eviction max entries)
Modified: trunk/cachestore/bdbje/src/main/java/org/infinispan/loaders/bdbje/BdbjeCacheStore.java
===================================================================
--- trunk/cachestore/bdbje/src/main/java/org/infinispan/loaders/bdbje/BdbjeCacheStore.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/cachestore/bdbje/src/main/java/org/infinispan/loaders/bdbje/BdbjeCacheStore.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -4,7 +4,15 @@
import com.sleepycat.collections.CurrentTransaction;
import com.sleepycat.collections.StoredMap;
import com.sleepycat.collections.StoredSortedMap;
-import com.sleepycat.je.*;
+import com.sleepycat.je.Cursor;
+import com.sleepycat.je.Database;
+import com.sleepycat.je.DatabaseEntry;
+import com.sleepycat.je.DatabaseException;
+import com.sleepycat.je.Environment;
+import com.sleepycat.je.EnvironmentConfig;
+import com.sleepycat.je.JEVersion;
+import com.sleepycat.je.OperationStatus;
+import com.sleepycat.je.Transaction;
import com.sleepycat.util.ExceptionUnwrapper;
import org.infinispan.Cache;
import org.infinispan.container.entries.InternalCacheEntry;
@@ -24,6 +32,7 @@
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -40,8 +49,8 @@
* <p/>
* All data access is transactional. Any attempted reads to locked records will block. The maximum duration of this is
* set in nanoseconds via the parameter {@link org.infinispan.loaders.bdbje.BdbjeCacheStoreConfig#getLockAcquistionTimeout()}.
- * Calls to {@link org.infinispan.loaders.CacheStore#prepare(java.util.List, org.infinispan.transaction.xa.GlobalTransaction, boolean)} will attempt
- * to resolve deadlocks, retrying up to {@link org.infinispan.loaders.bdbje.BdbjeCacheStoreConfig#getMaxTxRetries()}
+ * Calls to {@link org.infinispan.loaders.CacheStore#prepare(java.util.List, org.infinispan.transaction.xa.GlobalTransaction,
+ * boolean)} will attempt to resolve deadlocks, retrying up to {@link org.infinispan.loaders.bdbje.BdbjeCacheStoreConfig#getMaxTxRetries()}
* attempts.
* <p/>
* Unlike the C version of SleepyCat, JE does not support MVCC or READ_COMMITTED isolation. In other words, readers
@@ -56,503 +65,518 @@
@CacheLoaderMetadata(configurationClass = BdbjeCacheStoreConfig.class)
public class BdbjeCacheStore extends AbstractCacheStore {
- private static final Log log = LogFactory.getLog(BdbjeCacheStore.class);
- private static final boolean trace = log.isTraceEnabled();
+ private static final Log log = LogFactory.getLog(BdbjeCacheStore.class);
+ private static final boolean trace = log.isTraceEnabled();
- private BdbjeCacheStoreConfig cfg;
+ private BdbjeCacheStoreConfig cfg;
- private Environment env;
- private StoredClassCatalog catalog;
- private Database cacheDb;
- private Database expiryDb;
- private StoredMap<Object, InternalCacheEntry> cacheMap;
- private StoredSortedMap<Long, Object> expiryMap;
+ private Environment env;
+ private StoredClassCatalog catalog;
+ private Database cacheDb;
+ private Database expiryDb;
+ private StoredMap<Object, InternalCacheEntry> cacheMap;
+ private StoredSortedMap<Long, Object> expiryMap;
- private PreparableTransactionRunner transactionRunner;
- private Map<GlobalTransaction, Transaction> txnMap;
- private CurrentTransaction currentTransaction;
- private BdbjeResourceFactory factory;
+ private PreparableTransactionRunner transactionRunner;
+ private Map<GlobalTransaction, Transaction> txnMap;
+ private CurrentTransaction currentTransaction;
+ private BdbjeResourceFactory factory;
- /**
- * {@inheritDoc} This implementation expects config to be an instance of {@link BdbjeCacheStoreConfig} <p /> note
- * that the <code>m</code> is not currently used as SleepyCat has its own efficient solution.
- *
- * @see BdbjeCacheStoreConfig
- */
- @Override
- public void init(CacheLoaderConfig config, Cache cache, Marshaller m) throws CacheLoaderException {
- BdbjeCacheStoreConfig cfg = (BdbjeCacheStoreConfig) config;
- init(cfg, new BdbjeResourceFactory(cfg), cache, m);
- }
+ /**
+ * {@inheritDoc} This implementation expects config to be an instance of {@link BdbjeCacheStoreConfig} <p /> note
+ * that the <code>m</code> is not currently used as SleepyCat has its own efficient solution.
+ *
+ * @see BdbjeCacheStoreConfig
+ */
+ @Override
+ public void init(CacheLoaderConfig config, Cache cache, Marshaller m) throws CacheLoaderException {
+ BdbjeCacheStoreConfig cfg = (BdbjeCacheStoreConfig) config;
+ init(cfg, new BdbjeResourceFactory(cfg), cache, m);
+ }
- void init(BdbjeCacheStoreConfig cfg, BdbjeResourceFactory factory, Cache cache, Marshaller m) throws CacheLoaderException {
- if (trace) log.trace("initializing BdbjeCacheStore");
- printLicense();
- super.init(cfg, cache, m);
- this.cfg = cfg;
- this.factory = factory;
- }
+ void init(BdbjeCacheStoreConfig cfg, BdbjeResourceFactory factory, Cache cache, Marshaller m) throws CacheLoaderException {
+ if (trace) log.trace("initializing BdbjeCacheStore");
+ printLicense();
+ super.init(cfg, cache, m);
+ this.cfg = cfg;
+ this.factory = factory;
+ }
- /**
- * {@inheritDoc}
- *
- * @return {@link BdbjeCacheStoreConfig}
- */
- public Class<? extends CacheLoaderConfig> getConfigurationClass() {
- return BdbjeCacheStoreConfig.class;
- }
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@link BdbjeCacheStoreConfig}
+ */
+ public Class<? extends CacheLoaderConfig> getConfigurationClass() {
+ return BdbjeCacheStoreConfig.class;
+ }
- /**
- * {@inheritDoc} Validates configuration, configures and opens the {@link Environment}, then {@link
- * org.infinispan.loaders.bdbje.BdbjeCacheStore#openSleepyCatResources() opens the databases}. When this is
- * finished, transactional and purging services are instantiated.
- */
- public void start() throws CacheLoaderException {
- if (trace) log.trace("starting BdbjeCacheStore");
+ /**
+ * {@inheritDoc} Validates configuration, configures and opens the {@link Environment}, then {@link
+ * org.infinispan.loaders.bdbje.BdbjeCacheStore#openSleepyCatResources() opens the databases}. When this is
+ * finished, transactional and purging services are instantiated.
+ */
+ public void start() throws CacheLoaderException {
+ if (trace) log.trace("starting BdbjeCacheStore");
- openSleepyCatResources();
- openTransactionServices();
- super.start();
+ openSleepyCatResources();
+ openTransactionServices();
+ super.start();
- log.debug("started cache store {1}", this);
- }
+ log.debug("started cache store {1}", this);
+ }
- private void openTransactionServices() {
- txnMap = new ConcurrentHashMap<GlobalTransaction, Transaction>(64, 0.75f, getConcurrencyLevel());
- currentTransaction = factory.createCurrentTransaction(env);
- transactionRunner = factory.createPreparableTransactionRunner(env);
- }
+ private void openTransactionServices() {
+ txnMap = new ConcurrentHashMap<GlobalTransaction, Transaction>(64, 0.75f, getConcurrencyLevel());
+ currentTransaction = factory.createCurrentTransaction(env);
+ transactionRunner = factory.createPreparableTransactionRunner(env);
+ }
- /**
- * Opens the SleepyCat environment and all databases. A {@link StoredMap} instance is provided which persists the
- * CacheStore.
- */
- private void openSleepyCatResources() throws CacheLoaderException {
- if (trace) log.trace("creating je environment with home dir {0}", cfg.getLocation());
+ /**
+ * Opens the SleepyCat environment and all databases. A {@link StoredMap} instance is provided which persists the
+ * CacheStore.
+ */
+ private void openSleepyCatResources() throws CacheLoaderException {
+ if (trace) log.trace("creating je environment with home dir {0}", cfg.getLocation());
- cfg.setCacheName(cache.getName());
- if (cfg.getCatalogDbName() == null)
- cfg.setCatalogDbName(cfg.getCacheDbName() + "_class_catalog");
+ cfg.setCacheName(cache.getName());
+ if (cfg.getCatalogDbName() == null)
+ cfg.setCatalogDbName(cfg.getCacheDbName() + "_class_catalog");
- File location = verifyOrCreateEnvironmentDirectory(new File(cfg.getLocation()));
- try {
- env = factory.createEnvironment(location);
- cacheDb = factory.createDatabase(env, cfg.getCacheDbName());
- Database catalogDb = factory.createDatabase(env, cfg.getCatalogDbName());
- expiryDb = factory.createDatabase(env, cfg.getExpiryDbName());
- catalog = factory.createStoredClassCatalog(catalogDb);
- cacheMap = factory.createStoredMapViewOfDatabase(cacheDb, catalog, marshaller);
- expiryMap = factory.createStoredSortedMapForKeyExpiry(expiryDb, catalog, marshaller);
- } catch (DatabaseException e) {
- throw convertToCacheLoaderException("could not open sleepycat je resource", e);
- }
- }
+ File location = verifyOrCreateEnvironmentDirectory(new File(cfg.getLocation()));
+ try {
+ env = factory.createEnvironment(location);
+ cacheDb = factory.createDatabase(env, cfg.getCacheDbName());
+ Database catalogDb = factory.createDatabase(env, cfg.getCatalogDbName());
+ expiryDb = factory.createDatabase(env, cfg.getExpiryDbName());
+ catalog = factory.createStoredClassCatalog(catalogDb);
+ cacheMap = factory.createStoredMapViewOfDatabase(cacheDb, catalog, marshaller);
+ expiryMap = factory.createStoredSortedMapForKeyExpiry(expiryDb, catalog, marshaller);
+ } catch (DatabaseException e) {
+ throw convertToCacheLoaderException("could not open sleepycat je resource", e);
+ }
+ }
- // not private so that this can be unit tested
- File verifyOrCreateEnvironmentDirectory(File location) throws CacheLoaderException {
- if (!location.exists()) {
- boolean created = location.mkdirs();
- if (!created) throw new CacheLoaderException("Unable to create cache loader location " + location);
+ // not private so that this can be unit tested
- }
- if (!location.isDirectory()) {
- throw new CacheLoaderException("Cache loader location [" + location + "] is not a directory!");
- }
- return location;
- }
+ File verifyOrCreateEnvironmentDirectory(File location) throws CacheLoaderException {
+ if (!location.exists()) {
+ boolean created = location.mkdirs();
+ if (!created) throw new CacheLoaderException("Unable to create cache loader location " + location);
- /**
- * Stops transaction and purge processing and closes the SleepyCat environment. The environment and databases are
- * not removed from the file system. Exceptions during close of databases are ignored as closing the environment will
- * ensure the databases are also.
- */
- public void stop() throws CacheLoaderException {
- if (trace) log.trace("stopping BdbjeCacheStore");
- super.stop();
- closeTransactionServices();
- closeSleepyCatResources();
- log.debug("started cache store {1}", this);
- }
+ }
+ if (!location.isDirectory()) {
+ throw new CacheLoaderException("Cache loader location [" + location + "] is not a directory!");
+ }
+ return location;
+ }
- private void closeTransactionServices() {
- transactionRunner = null;
- currentTransaction = null;
- txnMap = null;
- }
+ /**
+ * Stops transaction and purge processing and closes the SleepyCat environment. The environment and databases are
+ * not removed from the file system. Exceptions during close of databases are ignored as closing the environment
+ * will ensure the databases are also.
+ */
+ public void stop() throws CacheLoaderException {
+ if (trace) log.trace("stopping BdbjeCacheStore");
+ super.stop();
+ closeTransactionServices();
+ closeSleepyCatResources();
+ log.debug("started cache store {1}", this);
+ }
- private void closeSleepyCatResources() throws CacheLoaderException {
- cacheMap = null;
- expiryMap = null;
- closeDatabases();
- closeEnvironment();
- }
+ private void closeTransactionServices() {
+ transactionRunner = null;
+ currentTransaction = null;
+ txnMap = null;
+ }
- /**
- * Exceptions are ignored so that {@link org.infinispan.loaders.bdbje.BdbjeCacheStore#closeEnvironment()} will
- * execute.
- */
- private void closeDatabases() {
- if (trace) log.trace("closing databases");
- try {
- cacheDb.close();
- } catch (Exception e) {
- log.error("Error closing database", e);
- }
- try {
- expiryDb.close();
- } catch (Exception e) {
- log.error("Error closing database", e);
- }
- try {
- catalog.close();
- } catch (Exception e) {
- log.error("Error closing catalog", e);
- }
- catalog = null;
- cacheDb = null;
- expiryDb = null;
- }
+ private void closeSleepyCatResources() throws CacheLoaderException {
+ cacheMap = null;
+ expiryMap = null;
+ closeDatabases();
+ closeEnvironment();
+ }
- private void closeEnvironment() throws CacheLoaderException {
- if (env != null) {
- try {
- env.close();
- } catch (DatabaseException e) {
- throw new CacheLoaderException("Unexpected exception closing cacheStore", e);
- }
- }
- env = null;
- }
+ /**
+ * Exceptions are ignored so that {@link org.infinispan.loaders.bdbje.BdbjeCacheStore#closeEnvironment()} will
+ * execute.
+ */
+ private void closeDatabases() {
+ if (trace) log.trace("closing databases");
+ try {
+ cacheDb.close();
+ } catch (Exception e) {
+ log.error("Error closing database", e);
+ }
+ try {
+ expiryDb.close();
+ } catch (Exception e) {
+ log.error("Error closing database", e);
+ }
+ try {
+ catalog.close();
+ } catch (Exception e) {
+ log.error("Error closing catalog", e);
+ }
+ catalog = null;
+ cacheDb = null;
+ expiryDb = null;
+ }
- /**
- * {@inheritDoc} delegates to {@link BdbjeCacheStore#applyModifications(java.util.List)}, if <code>isOnePhase</code>.
- * Otherwise, delegates to {@link BdbjeCacheStore#prepare(java.util.List, org.infinispan.transaction.xa.GlobalTransaction)}
- */
- public void prepare(List<? extends Modification> mods, GlobalTransaction tx, boolean isOnePhase) throws CacheLoaderException {
- if (isOnePhase) {
- applyModifications(mods);
- } else {
- prepare(mods, tx);
- }
- }
+ private void closeEnvironment() throws CacheLoaderException {
+ if (env != null) {
+ try {
+ env.close();
+ } catch (DatabaseException e) {
+ throw new CacheLoaderException("Unexpected exception closing cacheStore", e);
+ }
+ }
+ env = null;
+ }
- /**
- * Perform the <code>mods</code> atomically by creating a {@link ModificationsTransactionWorker worker} and invoking
- * them in {@link PreparableTransactionRunner#run(com.sleepycat.collections.TransactionWorker)}.
- *
- * @param mods actions to perform atomically
- * @throws CacheLoaderException on problems during the transaction
- */
- @Override
- protected void applyModifications(List<? extends Modification> mods) throws CacheLoaderException {
- if (trace) log.trace("performing one phase transaction");
- try {
- transactionRunner.run(new ModificationsTransactionWorker(this, mods));
- } catch (Exception caught) {
- throw convertToCacheLoaderException("Problem committing modifications: " + mods, caught);
- }
- }
+ /**
+ * {@inheritDoc} delegates to {@link BdbjeCacheStore#applyModifications(java.util.List)}, if
+ * <code>isOnePhase</code>. Otherwise, delegates to {@link BdbjeCacheStore#prepare(java.util.List,
+ * org.infinispan.transaction.xa.GlobalTransaction)}
+ */
+ public void prepare(List<? extends Modification> mods, GlobalTransaction tx, boolean isOnePhase) throws CacheLoaderException {
+ if (isOnePhase) {
+ applyModifications(mods);
+ } else {
+ prepare(mods, tx);
+ }
+ }
- /**
- * Looks up the {@link Transaction SleepyCat transaction} associated with <code>tx</code>. Creates a {@link
- * org.infinispan.loaders.bdbje.ModificationsTransactionWorker} instance from <code>mods</code>. Then prepares the
- * transaction via {@link PreparableTransactionRunner#prepare(com.sleepycat.collections.TransactionWorker)}. Finally,
- * it invalidates {@link com.sleepycat.collections.CurrentTransaction#getTransaction()} so that no other thread can
- * accidentally commit this.
- *
- * @param mods modifications to be applied
- * @param tx transaction identifier
- * @throws CacheLoaderException in the event of problems writing to the store
- */
- protected void prepare(List<? extends Modification> mods, GlobalTransaction tx) throws CacheLoaderException {
- if (trace) log.trace("preparing transaction {0}", tx);
- try {
- transactionRunner.prepare(new ModificationsTransactionWorker(this, mods));
- Transaction txn = currentTransaction.getTransaction();
- if (trace) log.trace("transaction {0} == sleepycat transaction {1}", tx, txn);
- txnMap.put(tx, txn);
- ReflectionUtil.setValue(currentTransaction, "localTrans", new ThreadLocal());
- } catch (Exception e) {
- throw convertToCacheLoaderException("Problem preparing transaction", e);
- }
- }
+ /**
+ * Perform the <code>mods</code> atomically by creating a {@link ModificationsTransactionWorker worker} and invoking
+ * them in {@link PreparableTransactionRunner#run(com.sleepycat.collections.TransactionWorker)}.
+ *
+ * @param mods actions to perform atomically
+ * @throws CacheLoaderException on problems during the transaction
+ */
+ @Override
+ protected void applyModifications(List<? extends Modification> mods) throws CacheLoaderException {
+ if (trace) log.trace("performing one phase transaction");
+ try {
+ transactionRunner.run(new ModificationsTransactionWorker(this, mods));
+ } catch (Exception caught) {
+ throw convertToCacheLoaderException("Problem committing modifications: " + mods, caught);
+ }
+ }
+ /**
+ * Looks up the {@link Transaction SleepyCat transaction} associated with <code>tx</code>. Creates a {@link
+ * org.infinispan.loaders.bdbje.ModificationsTransactionWorker} instance from <code>mods</code>. Then prepares the
+ * transaction via {@link PreparableTransactionRunner#prepare(com.sleepycat.collections.TransactionWorker)}.
+ * Finally, it invalidates {@link com.sleepycat.collections.CurrentTransaction#getTransaction()} so that no other
+ * thread can accidentally commit this.
+ *
+ * @param mods modifications to be applied
+ * @param tx transaction identifier
+ * @throws CacheLoaderException in the event of problems writing to the store
+ */
+ protected void prepare(List<? extends Modification> mods, GlobalTransaction tx) throws CacheLoaderException {
+ if (trace) log.trace("preparing transaction {0}", tx);
+ try {
+ transactionRunner.prepare(new ModificationsTransactionWorker(this, mods));
+ Transaction txn = currentTransaction.getTransaction();
+ if (trace) log.trace("transaction {0} == sleepycat transaction {1}", tx, txn);
+ txnMap.put(tx, txn);
+ ReflectionUtil.setValue(currentTransaction, "localTrans", new ThreadLocal());
+ } catch (Exception e) {
+ throw convertToCacheLoaderException("Problem preparing transaction", e);
+ }
+ }
- /**
- * {@inheritDoc}
- * <p/>
- * This implementation calls {@link BdbjeCacheStore#completeTransaction(org.infinispan.transaction.xa.GlobalTransaction, boolean)}
- * completeTransaction} with an argument of false.
- */
- public void rollback(GlobalTransaction tx) {
- try {
- completeTransaction(tx, false);
- } catch (Exception e) {
- log.error("Error rolling back transaction", e);
- }
- }
- /**
- * {@inheritDoc}
- * <p/>
- * This implementation calls {@link BdbjeCacheStore#completeTransaction(org.infinispan.transaction.xa.GlobalTransaction, boolean)}
- * completeTransaction} with an argument of true.
- */
- public void commit(GlobalTransaction tx) throws CacheLoaderException {
- completeTransaction(tx, true);
- }
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * This implementation calls {@link BdbjeCacheStore#completeTransaction(org.infinispan.transaction.xa.GlobalTransaction,
+ * boolean)} completeTransaction} with an argument of false.
+ */
+ public void rollback(GlobalTransaction tx) {
+ try {
+ completeTransaction(tx, false);
+ } catch (Exception e) {
+ log.error("Error rolling back transaction", e);
+ }
+ }
- /**
- * Looks up the SleepyCat transaction associated with the parameter <code>tx</code>. If there is no associated
- * sleepycat transaction, an error is logged.
- *
- * @param tx java transaction used to lookup a SleepyCat transaction
- * @param commit true to commit false to abort
- * @throws CacheLoaderException if there are problems committing or aborting the transaction
- */
- protected void completeTransaction(GlobalTransaction tx, boolean commit) throws CacheLoaderException {
- Transaction txn = txnMap.remove(tx);
- if (txn != null) {
- if (trace) log.trace("{0} sleepycat transaction {1}", commit ? "committing" : "aborting", txn);
- try {
- if (commit)
- txn.commit();
- else
- txn.abort();
- } catch (Exception caught) {
- throw convertToCacheLoaderException("Problem completing transaction", caught);
- }
- } else {
- if (trace) log.trace("no sleepycat transaction associated transaction {0}", tx);
- }
- }
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * This implementation calls {@link BdbjeCacheStore#completeTransaction(org.infinispan.transaction.xa.GlobalTransaction,
+ * boolean)} completeTransaction} with an argument of true.
+ */
+ public void commit(GlobalTransaction tx) throws CacheLoaderException {
+ completeTransaction(tx, true);
+ }
- /**
- * commits or aborts the {@link com.sleepycat.collections.CurrentTransaction#getTransaction() current transaction}
- *
- * @param commit true to commit, false to abort
- * @throws CacheLoaderException if there was a problem completing the transaction
- */
- private void completeCurrentTransaction(boolean commit) throws CacheLoaderException {
- try {
- if (trace)
- log.trace("{0} current sleepycat transaction {1}", commit ? "committing" : "aborting", currentTransaction.getTransaction());
+ /**
+ * Looks up the SleepyCat transaction associated with the parameter <code>tx</code>. If there is no associated
+ * sleepycat transaction, an error is logged.
+ *
+ * @param tx java transaction used to lookup a SleepyCat transaction
+ * @param commit true to commit false to abort
+ * @throws CacheLoaderException if there are problems committing or aborting the transaction
+ */
+ protected void completeTransaction(GlobalTransaction tx, boolean commit) throws CacheLoaderException {
+ Transaction txn = txnMap.remove(tx);
+ if (txn != null) {
+ if (trace) log.trace("{0} sleepycat transaction {1}", commit ? "committing" : "aborting", txn);
+ try {
if (commit)
- currentTransaction.commitTransaction();
+ txn.commit();
else
- currentTransaction.abortTransaction();
- } catch (Exception caught) {
+ txn.abort();
+ } catch (Exception caught) {
throw convertToCacheLoaderException("Problem completing transaction", caught);
- }
- }
+ }
+ } else {
+ if (trace) log.trace("no sleepycat transaction associated transaction {0}", tx);
+ }
+ }
- /**
- * {@inheritDoc} This implementation delegates to {@link StoredMap#remove(Object)}
- */
- public boolean remove(Object key) throws CacheLoaderException {
- try {
- if (cacheMap.containsKey(key)) {
- cacheMap.remove(key);
- return true;
- }
- return false;
- } catch (RuntimeException caught) {
- throw convertToCacheLoaderException("error removing key " + key, caught);
- }
- }
+ /**
+ * commits or aborts the {@link com.sleepycat.collections.CurrentTransaction#getTransaction() current transaction}
+ *
+ * @param commit true to commit, false to abort
+ * @throws CacheLoaderException if there was a problem completing the transaction
+ */
+ private void completeCurrentTransaction(boolean commit) throws CacheLoaderException {
+ try {
+ if (trace)
+ log.trace("{0} current sleepycat transaction {1}", commit ? "committing" : "aborting", currentTransaction.getTransaction());
+ if (commit)
+ currentTransaction.commitTransaction();
+ else
+ currentTransaction.abortTransaction();
+ } catch (Exception caught) {
+ throw convertToCacheLoaderException("Problem completing transaction", caught);
+ }
+ }
- /**
- * {@inheritDoc} This implementation delegates to {@link StoredMap#get(Object)}. If the object is expired, it will
- * not be returned.
- */
- public InternalCacheEntry load(Object key) throws CacheLoaderException {
- try {
- InternalCacheEntry s = cacheMap.get(key);
- if (s != null && s.isExpired()) {
- s = null;
- }
- return s;
- } catch (RuntimeException caught) {
- throw convertToCacheLoaderException("error loading key " + key, caught);
- }
- }
+ /**
+ * {@inheritDoc} This implementation delegates to {@link StoredMap#remove(Object)}
+ */
+ public boolean remove(Object key) throws CacheLoaderException {
+ try {
+ if (cacheMap.containsKey(key)) {
+ cacheMap.remove(key);
+ return true;
+ }
+ return false;
+ } catch (RuntimeException caught) {
+ throw convertToCacheLoaderException("error removing key " + key, caught);
+ }
+ }
- /**
- * {@inheritDoc} This implementation delegates to {@link StoredMap#put(Object, Object)}
- */
- public void store(InternalCacheEntry ed) throws CacheLoaderException {
- try {
- cacheMap.put(ed.getKey(), ed);
- if (ed.canExpire())
- addNewExpiry(ed);
- } catch (IOException caught) {
- throw convertToCacheLoaderException("error storing entry " + ed, caught);
- }
- }
+ /**
+ * {@inheritDoc} This implementation delegates to {@link StoredMap#get(Object)}. If the object is expired, it will
+ * not be returned.
+ */
+ public InternalCacheEntry load(Object key) throws CacheLoaderException {
+ try {
+ InternalCacheEntry s = cacheMap.get(key);
+ if (s != null && s.isExpired()) {
+ s = null;
+ }
+ return s;
+ } catch (RuntimeException caught) {
+ throw convertToCacheLoaderException("error loading key " + key, caught);
+ }
+ }
+ /**
+ * {@inheritDoc} This implementation delegates to {@link StoredMap#put(Object, Object)}
+ */
+ public void store(InternalCacheEntry ed) throws CacheLoaderException {
+ try {
+ cacheMap.put(ed.getKey(), ed);
+ if (ed.canExpire())
+ addNewExpiry(ed);
+ } catch (IOException caught) {
+ throw convertToCacheLoaderException("error storing entry " + ed, caught);
+ }
+ }
- private void addNewExpiry(InternalCacheEntry entry) throws IOException {
- long expiry = entry.getExpiryTime();
- if (entry.getMaxIdle() > 0) {
- // Coding getExpiryTime() for transient entries has the risk of being a moving target
- // which could lead to unexpected results, hence, InternalCacheEntry calls are required
- expiry = entry.getMaxIdle() + System.currentTimeMillis();
- }
- Long at = expiry;
- Object key = entry.getKey();
- expiryMap.put(at, key);
- }
- /**
- * {@inheritDoc} This implementation delegates to {@link StoredMap#clear()}
- */
- public void clear() throws CacheLoaderException {
- try {
- cacheMap.clear();
- } catch (RuntimeException caught) {
- throw convertToCacheLoaderException("error clearing store", caught);
- }
- }
+ private void addNewExpiry(InternalCacheEntry entry) throws IOException {
+ long expiry = entry.getExpiryTime();
+ if (entry.getMaxIdle() > 0) {
+ // Coding getExpiryTime() for transient entries has the risk of being a moving target
+ // which could lead to unexpected results, hence, InternalCacheEntry calls are required
+ expiry = entry.getMaxIdle() + System.currentTimeMillis();
+ }
+ Long at = expiry;
+ Object key = entry.getKey();
+ expiryMap.put(at, key);
+ }
- /**
- * {@inheritDoc} This implementation returns a Set from {@link StoredMap#values()}
- */
- public Set<InternalCacheEntry> loadAll() throws CacheLoaderException {
- try {
- return new HashSet<InternalCacheEntry>(cacheMap.values());
- } catch (RuntimeException caught) {
- throw convertToCacheLoaderException("error loading all entries", caught);
- }
- }
+ /**
+ * {@inheritDoc} This implementation delegates to {@link StoredMap#clear()}
+ */
+ public void clear() throws CacheLoaderException {
+ try {
+ cacheMap.clear();
+ } catch (RuntimeException caught) {
+ throw convertToCacheLoaderException("error clearing store", caught);
+ }
+ }
- /**
- * {@inheritDoc} This implementation reads the number of entries to load from the stream, then begins a transaction.
- * During that transaction, the cachestore is cleared and replaced with entries from the stream. If there are any
- * errors during the process, the entire transaction is rolled back. Deadlock handling is not addressed, as there is
- * no means to rollback reads from the input stream.
- *
- * @see BdbjeCacheStore#toStream(java.io.ObjectOutput)
- */
- public void fromStream(ObjectInput ois) throws CacheLoaderException {
- try {
- currentTransaction.beginTransaction(null);
- cacheMap.clear();
- expiryMap.clear();
- for (Database db : new Database[]{cacheDb, expiryDb}) {
- long recordCount = ois.readLong();
- log.debug("clearing and reading {0} records from stream", recordCount);
- Cursor cursor = null;
- try {
- cursor = db.openCursor(currentTransaction.getTransaction(), null);
- for (int i = 0; i < recordCount; i++) {
- byte[] keyBytes = (byte[]) ois.readObject();
- byte[] dataBytes = (byte[]) ois.readObject();
+ /**
+ * {@inheritDoc} This implementation returns a Set from {@link StoredMap#values()}
+ */
+ public Set<InternalCacheEntry> loadAll() throws CacheLoaderException {
+ try {
+ return new HashSet<InternalCacheEntry>(cacheMap.values());
+ } catch (RuntimeException caught) {
+ throw convertToCacheLoaderException("error loading all entries", caught);
+ }
+ }
- DatabaseEntry key = new DatabaseEntry(keyBytes);
- DatabaseEntry data = new DatabaseEntry(dataBytes);
- cursor.put(key, data);
- }
- } finally {
- if (cursor != null) cursor.close();
- }
+ @Override
+ public Set<InternalCacheEntry> load(int numEntries) throws CacheLoaderException {
+ if (numEntries < 0) return loadAll();
+ try {
+ Set<InternalCacheEntry> s = new HashSet<InternalCacheEntry>(numEntries);
+ for (Iterator<InternalCacheEntry> i = cacheMap.values().iterator(); i.hasNext() && s.size() < numEntries;)
+ s.add(i.next());
+ return s;
+ } catch (RuntimeException caught) {
+ throw convertToCacheLoaderException("error loading all entries", caught);
+ }
+ }
+
+ /**
+ * {@inheritDoc} This implementation reads the number of entries to load from the stream, then begins a transaction.
+ * During that transaction, the cachestore is cleared and replaced with entries from the stream. If there are any
+ * errors during the process, the entire transaction is rolled back. Deadlock handling is not addressed, as there
+ * is no means to rollback reads from the input stream.
+ *
+ * @see BdbjeCacheStore#toStream(java.io.ObjectOutput)
+ */
+ public void fromStream(ObjectInput ois) throws CacheLoaderException {
+ try {
+ currentTransaction.beginTransaction(null);
+ cacheMap.clear();
+ expiryMap.clear();
+ for (Database db : new Database[]{cacheDb, expiryDb}) {
+ long recordCount = ois.readLong();
+ log.debug("clearing and reading {0} records from stream", recordCount);
+ Cursor cursor = null;
+ try {
+ cursor = db.openCursor(currentTransaction.getTransaction(), null);
+ for (int i = 0; i < recordCount; i++) {
+ byte[] keyBytes = (byte[]) ois.readObject();
+ byte[] dataBytes = (byte[]) ois.readObject();
+
+ DatabaseEntry key = new DatabaseEntry(keyBytes);
+ DatabaseEntry data = new DatabaseEntry(dataBytes);
+ cursor.put(key, data);
+ }
+ } finally {
+ if (cursor != null) cursor.close();
}
- completeCurrentTransaction(true);
- } catch (Exception caught) {
- completeCurrentTransaction(false);
- clear();
- throw convertToCacheLoaderException("Problems reading from stream", caught);
- }
- }
+ }
+ completeCurrentTransaction(true);
+ } catch (Exception caught) {
+ completeCurrentTransaction(false);
+ clear();
+ throw convertToCacheLoaderException("Problems reading from stream", caught);
+ }
+ }
- /**
- * Writes the current count of cachestore entries followed by a pair of byte[]s corresponding to the SleepyCat binary
- * representation of {@link InternalCacheEntry#getKey() key} {@link InternalCacheEntry value}.
- * <p/>
- * This implementation holds a transaction open to ensure that we see no new records added while iterating.
- */
- public void toStream(ObjectOutput oos) throws CacheLoaderException {
- try {
- currentTransaction.beginTransaction(null);
- for (Database db : new Database[]{cacheDb, expiryDb}) {
- long recordCount = db.count();
- oos.writeLong(recordCount);
- if (trace) log.trace("writing {0} records to stream", recordCount);
- Cursor cursor = null;
- try {
- cursor = db.openCursor(currentTransaction.getTransaction(), null);
- DatabaseEntry key = new DatabaseEntry();
- DatabaseEntry data = new DatabaseEntry();
- int recordsWritten = 0;
- while (cursor.getNext(key, data, null) ==
- OperationStatus.SUCCESS) {
- oos.writeObject(key.getData());
- oos.writeObject(data.getData());
- recordsWritten++;
- }
- if (trace) log.trace("wrote {0} records to stream", recordsWritten);
- if (recordsWritten != recordCount)
- log.warn("expected to write {0} records, but wrote {1}", recordCount, recordsWritten);
- } finally {
- if (cursor != null) cursor.close();
- }
+ /**
+ * Writes the current count of cachestore entries followed by a pair of byte[]s corresponding to the SleepyCat
+ * binary representation of {@link InternalCacheEntry#getKey() key} {@link InternalCacheEntry value}.
+ * <p/>
+ * This implementation holds a transaction open to ensure that we see no new records added while iterating.
+ */
+ public void toStream(ObjectOutput oos) throws CacheLoaderException {
+ try {
+ currentTransaction.beginTransaction(null);
+ for (Database db : new Database[]{cacheDb, expiryDb}) {
+ long recordCount = db.count();
+ oos.writeLong(recordCount);
+ if (trace) log.trace("writing {0} records to stream", recordCount);
+ Cursor cursor = null;
+ try {
+ cursor = db.openCursor(currentTransaction.getTransaction(), null);
+ DatabaseEntry key = new DatabaseEntry();
+ DatabaseEntry data = new DatabaseEntry();
+ int recordsWritten = 0;
+ while (cursor.getNext(key, data, null) ==
+ OperationStatus.SUCCESS) {
+ oos.writeObject(key.getData());
+ oos.writeObject(data.getData());
+ recordsWritten++;
+ }
+ if (trace) log.trace("wrote {0} records to stream", recordsWritten);
+ if (recordsWritten != recordCount)
+ log.warn("expected to write {0} records, but wrote {1}", recordCount, recordsWritten);
+ } finally {
+ if (cursor != null) cursor.close();
}
- completeCurrentTransaction(true);
- } catch (Exception caught) {
- completeCurrentTransaction(false);
- throw convertToCacheLoaderException("Problems writing to stream", caught);
- }
- }
+ }
+ completeCurrentTransaction(true);
+ } catch (Exception caught) {
+ completeCurrentTransaction(false);
+ throw convertToCacheLoaderException("Problems writing to stream", caught);
+ }
+ }
- /**
- * In order to adhere to APIs which do not throw checked exceptions, BDBJE wraps IO and DatabaseExceptions inside
- * RuntimeExceptions. These special Exceptions implement {@link com.sleepycat.util.ExceptionWrapper}. This method
- * will look for any of that type of Exception and encapsulate it into a CacheLoaderException. In doing so, the real
- * root cause can be obtained.
- *
- * @param message what to attach to the CacheLoaderException
- * @param caught exception to parse
- * @return CacheLoaderException with the correct cause
- */
- CacheLoaderException convertToCacheLoaderException(String message, Exception caught) {
- caught = ExceptionUnwrapper.unwrap(caught);
- return (caught instanceof CacheLoaderException) ? (CacheLoaderException) caught :
- new CacheLoaderException(message, caught);
- }
+ /**
+ * In order to adhere to APIs which do not throw checked exceptions, BDBJE wraps IO and DatabaseExceptions inside
+ * RuntimeExceptions. These special Exceptions implement {@link com.sleepycat.util.ExceptionWrapper}. This method
+ * will look for any of that type of Exception and encapsulate it into a CacheLoaderException. In doing so, the
+ * real root cause can be obtained.
+ *
+ * @param message what to attach to the CacheLoaderException
+ * @param caught exception to parse
+ * @return CacheLoaderException with the correct cause
+ */
+ CacheLoaderException convertToCacheLoaderException(String message, Exception caught) {
+ caught = ExceptionUnwrapper.unwrap(caught);
+ return (caught instanceof CacheLoaderException) ? (CacheLoaderException) caught :
+ new CacheLoaderException(message, caught);
+ }
- /**
- * Iterate through {@link com.sleepycat.collections.StoredMap#entrySet()} and remove, if expired.
- */
- @Override
- protected void purgeInternal() throws CacheLoaderException {
- try {
- Map<Long, Object> expired = expiryMap.tailMap(System.currentTimeMillis(), true);
- for (Map.Entry<Long, Object> entry : expired.entrySet()) {
- expiryMap.remove(entry.getKey());
- cacheMap.remove(entry.getValue());
- }
- } catch (RuntimeException caught) {
- throw convertToCacheLoaderException("error purging expired entries", caught);
- }
- }
+ /**
+ * Iterate through {@link com.sleepycat.collections.StoredMap#entrySet()} and remove, if expired.
+ */
+ @Override
+ protected void purgeInternal() throws CacheLoaderException {
+ try {
+ Map<Long, Object> expired = expiryMap.tailMap(System.currentTimeMillis(), true);
+ for (Map.Entry<Long, Object> entry : expired.entrySet()) {
+ expiryMap.remove(entry.getKey());
+ cacheMap.remove(entry.getValue());
+ }
+ } catch (RuntimeException caught) {
+ throw convertToCacheLoaderException("error purging expired entries", caught);
+ }
+ }
- /**
- * prints terms of use for Berkeley DB JE
- */
- public void printLicense() {
- String license = "\n*************************************************************************************\n" +
- "Berkeley DB Java Edition version: " + JEVersion.CURRENT_VERSION.toString() + "\n" +
- "JBoss Cache can use Berkeley DB Java Edition from Oracle \n" +
- "(http://www.oracle.com/database/berkeley-db/je/index.html)\n" +
- "for persistent, reliable and transaction-protected data storage.\n" +
- "If you choose to use Berkeley DB Java Edition with JBoss Cache, you must comply with the terms\n" +
- "of Oracle's public license, included in the file LICENSE.txt.\n" +
- "If you prefer not to release the source code for your own application in order to comply\n" +
- "with the Oracle public license, you may purchase a different license for use of\n" +
- "Berkeley DB Java Edition with JBoss Cache.\n" +
- "See http://www.oracle.com/database/berkeley-db/je/index.html for pricing and license terms\n" +
- "*************************************************************************************";
- System.out.println(license);
- }
+ /**
+ * prints terms of use for Berkeley DB JE
+ */
+ public void printLicense() {
+ String license = "\n*************************************************************************************\n" +
+ "Berkeley DB Java Edition version: " + JEVersion.CURRENT_VERSION.toString() + "\n" +
+ "JBoss Cache can use Berkeley DB Java Edition from Oracle \n" +
+ "(http://www.oracle.com/database/berkeley-db/je/index.html)\n" +
+ "for persistent, reliable and transaction-protected data storage.\n" +
+ "If you choose to use Berkeley DB Java Edition with JBoss Cache, you must comply with the terms\n" +
+ "of Oracle's public license, included in the file LICENSE.txt.\n" +
+ "If you prefer not to release the source code for your own application in order to comply\n" +
+ "with the Oracle public license, you may purchase a different license for use of\n" +
+ "Berkeley DB Java Edition with JBoss Cache.\n" +
+ "See http://www.oracle.com/database/berkeley-db/je/index.html for pricing and license terms\n" +
+ "*************************************************************************************";
+ System.out.println(license);
+ }
}
Modified: trunk/cachestore/bdbje/src/test/java/org/infinispan/loaders/bdbje/BdbjeCacheStoreFunctionalIntegrationTest.java
===================================================================
--- trunk/cachestore/bdbje/src/test/java/org/infinispan/loaders/bdbje/BdbjeCacheStoreFunctionalIntegrationTest.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/cachestore/bdbje/src/test/java/org/infinispan/loaders/bdbje/BdbjeCacheStoreFunctionalIntegrationTest.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -28,6 +28,7 @@
import org.infinispan.test.TestingUtil;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
@@ -38,8 +39,8 @@
@BeforeTest
@Parameters({"basedir"})
- protected void setUpTempDir(String basedir) {
- tmpDirectory = basedir + TestingUtil.TEST_PATH + File.separator + getClass().getSimpleName();
+ protected void setUpTempDir(@Optional("/tmp") String basedir) {
+ tmpDirectory = TestingUtil.tmpDirectory(basedir, this);
}
@AfterClass
Modified: trunk/cachestore/bdbje/src/test/java/org/infinispan/loaders/bdbje/BdbjeCacheStoreIntegrationTest.java
===================================================================
--- trunk/cachestore/bdbje/src/test/java/org/infinispan/loaders/bdbje/BdbjeCacheStoreIntegrationTest.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/cachestore/bdbje/src/test/java/org/infinispan/loaders/bdbje/BdbjeCacheStoreIntegrationTest.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -12,7 +12,9 @@
import org.infinispan.transaction.xa.GlobalTransaction;
import org.infinispan.transaction.xa.GlobalTransactionFactory;
import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
@@ -30,10 +32,10 @@
private String tmpDirectory;
private GlobalTransactionFactory gts = new GlobalTransactionFactory();
- @BeforeTest
+ @BeforeClass
@Parameters({"basedir"})
- protected void setUpTempDir(String basedir) {
- tmpDirectory = basedir + TestingUtil.TEST_PATH + File.separator + getClass().getSimpleName();
+ protected void setUpTempDir(@Optional("/tmp") String basedir) {
+ tmpDirectory = TestingUtil.tmpDirectory(basedir, this);
}
@AfterClass
Modified: trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudCacheStore.java
===================================================================
--- trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudCacheStore.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudCacheStore.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -32,6 +32,7 @@
import java.io.ObjectOutput;
import java.util.Collections;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -154,6 +155,20 @@
}
@Override
+ protected Set<InternalCacheEntry> loadLockSafe(int maxEntries) throws CacheLoaderException {
+ Set<InternalCacheEntry> result = new HashSet<InternalCacheEntry>(maxEntries);
+
+ for (Map.Entry<String, Blob> entry : ctx.createBlobMap(containerName).entrySet()) {
+ Bucket bucket = readFromBlob(entry.getValue(), entry.getKey());
+ if (bucket.removeExpiredEntries()) updateBucket(bucket);
+ for (Iterator<? extends InternalCacheEntry> i = bucket.getStoredEntries().iterator(); i.hasNext() && result.size() < maxEntries;)
+ result.add(i.next());
+ if (result.size() >= maxEntries) break;
+ }
+ return result;
+ }
+
+ @Override
protected void fromStreamLockSafe(ObjectInput objectInput) throws CacheLoaderException {
String source;
try {
Modified: trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/DataManipulationHelper.java
===================================================================
--- trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/DataManipulationHelper.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/DataManipulationHelper.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -176,6 +176,34 @@
}
}
+ public final Set<InternalCacheEntry> loadSome(int maxEntries) throws CacheLoaderException {
+ Connection conn = null;
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+ try {
+ String sql = tableManipulation.getLoadSomeRowsSql();
+ if (log.isTraceEnabled()) log.trace("Running sql '" + sql);
+ conn = connectionFactory.getConnection();
+ ps = conn.prepareStatement(sql);
+ ps.setInt(1, maxEntries);
+ rs = ps.executeQuery();
+ rs.setFetchSize(tableManipulation.getFetchSize());
+ Set<InternalCacheEntry> result = new HashSet<InternalCacheEntry>(maxEntries);
+ while (rs.next()) {
+ loadAllProcess(rs, result);
+ }
+ return result;
+ } catch (SQLException e) {
+ String message = "SQL error while fetching all StoredEntries";
+ log.error(message, e);
+ throw new CacheLoaderException(message, e);
+ } finally {
+ JdbcUtil.safeClose(rs);
+ JdbcUtil.safeClose(ps);
+ connectionFactory.releaseConnection(conn);
+ }
+ }
+
public abstract void loadAllProcess(ResultSet rs, Set<InternalCacheEntry> result) throws SQLException, CacheLoaderException;
public abstract void toStreamProcess(ResultSet rs, InputStream is, ObjectOutput objectOutput) throws CacheLoaderException, SQLException, IOException;
Added: trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/DatabaseType.java
===================================================================
--- trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/DatabaseType.java (rev 0)
+++ trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/DatabaseType.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -0,0 +1,17 @@
+package org.infinispan.loaders.jdbc;
+
+import java.util.Arrays;
+
+/**
+ * Supported database dialects for the Jdbc cache stores
+ *
+ * @author Manik Surtani
+ * @since 4.1
+ */
+public enum DatabaseType {
+ MYSQL, POSTGRES, DERBY, HSQL, H2, SQLITE,
+ DB2,
+ INFORMIX, INTERBASE, FIREBIRD,
+ SQL_SERVER, ACCESS,
+ ORACLE;
+}
Property changes on: trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/DatabaseType.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/TableManipulation.java
===================================================================
--- trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/TableManipulation.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/TableManipulation.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -21,6 +21,7 @@
*/
package org.infinispan.loaders.jdbc;
+import org.infinispan.config.ConfigurationException;
import org.infinispan.loaders.CacheLoaderException;
import org.infinispan.loaders.jdbc.connectionfactory.ConnectionFactory;
import org.infinispan.util.logging.Log;
@@ -31,6 +32,7 @@
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
+import java.util.Arrays;
import java.util.Locale;
/**
@@ -76,6 +78,8 @@
private String deleteAllRows;
private String selectExpiredRowsSql;
private String deleteExpiredRowsSql;
+ private String loadSomeRowsSql;
+ public DatabaseType databaseType;
public TableManipulation(String idColumnName, String idColumnType, String tableNamePrefix, String dataColumnName,
String dataColumnType, String timestampColumnName, String timestampColumnType) {
@@ -417,4 +421,94 @@
this.cacheName = cacheName;
this.tableName = null;
}
+
+ public String getLoadSomeRowsSql() {
+ if (loadSomeRowsSql == null) {
+ // this stuff is going to be database specific!!
+ // see http://stackoverflow.com/questions/595123/is-there-an-ansi-sql-alternative-to-the-mysql-limit-keyword
+
+ switch (getDatabaseType()) {
+ case ORACLE:
+ loadSomeRowsSql = "SELECT " + dataColumnName + "," + idColumnName + " FROM " + getTableName() + " LIMIT ?";
+ break;
+ case DB2:
+ loadSomeRowsSql = "SELECT " + dataColumnName + "," + idColumnName + " FROM " + getTableName() + " LIMIT ?";
+ break;
+ case INFORMIX:
+ case INTERBASE:
+ case FIREBIRD:
+ loadSomeRowsSql = "SELECT " + dataColumnName + "," + idColumnName + " FROM " + getTableName() + " LIMIT ?";
+ break;
+ case SQL_SERVER:
+ case ACCESS:
+ loadSomeRowsSql = "SELECT " + dataColumnName + "," + idColumnName + " FROM " + getTableName() + " LIMIT ?";
+ break;
+ default:
+ // the MySQL-style LIMIT clause
+ loadSomeRowsSql = "SELECT " + dataColumnName + "," + idColumnName + " FROM " + getTableName() + " LIMIT ?";
+ break;
+ }
+
+ }
+ return loadSomeRowsSql;
+ }
+
+ private DatabaseType getDatabaseType() {
+ if (databaseType == null) {
+ // need to guess from the database type!
+ try {
+ String dbProduct = connectionFactory.getConnection().getMetaData().getDatabaseProductName();
+ databaseType = guessDatabaseType(dbProduct);
+ } catch (Exception e) {
+ log.debug("Unable to guess database type from JDBC metadata.", e);
+ }
+ if (databaseType == null) log.info("Unable to detect database type using connection metadata. Attempting to guess on driver name.");
+ try {
+ String dbProduct = connectionFactory.getConnection().getMetaData().getDriverName();
+ databaseType = guessDatabaseType(dbProduct);
+ } catch (Exception e) {
+ log.debug("Unable to guess database type from JDBC driver name.", e);
+ }
+
+ if (databaseType == null)
+ throw new ConfigurationException("Unable to detect database type from JDBC driver name or connection metadata. Please provide this manually using the 'databaseType' property in your configuration. Supported database type strings are " + Arrays.toString(DatabaseType.values()));
+ else
+ log.info("Guessing database type as '" + databaseType + "'. If this is incorrect, please specify the correct type using the 'databaseType' property in your configuration. Supported database type strings are " + Arrays.toString(DatabaseType.values()));
+ }
+ return databaseType;
+ }
+
+ private DatabaseType guessDatabaseType(String name) {
+ DatabaseType type = null;
+ if (name != null) {
+ if (name.toLowerCase().contains("mysql"))
+ type = DatabaseType.MYSQL;
+ else if (name.toLowerCase().contains("postgres"))
+ type = DatabaseType.POSTGRES;
+ else if (name.toLowerCase().contains("derby"))
+ type = DatabaseType.DERBY;
+ else if (name.toLowerCase().contains("hsql") || name.toLowerCase().contains("hypersonic"))
+ type = DatabaseType.HSQL;
+ else if (name.toLowerCase().contains("h2"))
+ type = DatabaseType.H2;
+ else if (name.toLowerCase().contains("sqlite"))
+ type = DatabaseType.SQLITE;
+ else if (name.toLowerCase().contains("db2"))
+ type = DatabaseType.DB2;
+ else if (name.toLowerCase().contains("informix"))
+ type = DatabaseType.INFORMIX;
+ else if (name.toLowerCase().contains("interbase"))
+ type = DatabaseType.INTERBASE;
+ else if (name.toLowerCase().contains("firebird"))
+ type = DatabaseType.FIREBIRD;
+ else if (name.toLowerCase().contains("sqlserver") || name.toLowerCase().contains("microsoft"))
+ type = DatabaseType.SQL_SERVER;
+ else if (name.toLowerCase().contains("access"))
+ type = DatabaseType.ACCESS;
+ else if (name.toLowerCase().contains("oracle"))
+ type = DatabaseType.ORACLE;
+ }
+ return type;
+ }
}
+
Modified: trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/binary/JdbcBinaryCacheStore.java
===================================================================
--- trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/binary/JdbcBinaryCacheStore.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/binary/JdbcBinaryCacheStore.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -223,6 +223,11 @@
return dmHelper.loadAllSupport(false);
}
+ @Override
+ protected Set<InternalCacheEntry> loadLockSafe(int maxEntries) throws CacheLoaderException {
+ return dmHelper.loadSome(maxEntries);
+ }
+
protected void fromStreamLockSafe(ObjectInput objectInput) throws CacheLoaderException {
dmHelper.fromStreamSupport(objectInput);
}
Modified: trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/binary/JdbcBinaryCacheStoreConfig.java
===================================================================
--- trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/binary/JdbcBinaryCacheStoreConfig.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/binary/JdbcBinaryCacheStoreConfig.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -22,6 +22,7 @@
package org.infinispan.loaders.jdbc.binary;
import org.infinispan.loaders.LockSupportCacheStoreConfig;
+import org.infinispan.loaders.jdbc.DatabaseType;
import org.infinispan.loaders.jdbc.TableManipulation;
import org.infinispan.loaders.jdbc.connectionfactory.ConnectionFactoryConfig;
@@ -213,4 +214,18 @@
public int getBatchSize() {
return this.tableManipulation.getBatchSize();
}
+
+ public String getDatabaseType() {
+ return this.tableManipulation.databaseType == null ? "" : this.tableManipulation.databaseType.toString();
+ }
+
+ /**
+ * Sets the database dialect. Valid types are reflected in the DatabaseType enum. If unspecified, will attempt to
+ * "guess" appropriate dialect from the JDBC driver specified.
+ * @param dbType
+ */
+ public void setDatabaseType(String dbType) {
+ if (dbType != null)
+ this.tableManipulation.databaseType = DatabaseType.valueOf(dbType.toUpperCase().trim());
+ }
}
Modified: trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStore.java
===================================================================
--- trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStore.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStore.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -116,6 +116,19 @@
return fromBuckets;
}
+ @Override
+ public Set<InternalCacheEntry> load(int numEntries) throws CacheLoaderException {
+ if (numEntries < 0) return loadAll();
+ Set<InternalCacheEntry> fromBuckets = binaryCacheStore.load(numEntries);
+
+ if (fromBuckets.size() < numEntries) {
+ Set<InternalCacheEntry> fromStrings = stringBasedCacheStore.load(numEntries - fromBuckets.size());
+ fromBuckets.addAll(fromStrings);
+ }
+
+ return fromBuckets;
+ }
+
public void store(InternalCacheEntry ed) throws CacheLoaderException {
getCacheStore(ed.getKey()).store(ed);
}
Modified: trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStoreConfig.java
===================================================================
--- trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStoreConfig.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStoreConfig.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -23,6 +23,7 @@
import org.infinispan.loaders.AbstractCacheStoreConfig;
import org.infinispan.loaders.LockSupportCacheStoreConfig;
+import org.infinispan.loaders.jdbc.DatabaseType;
import org.infinispan.loaders.jdbc.TableManipulation;
import org.infinispan.loaders.jdbc.binary.JdbcBinaryCacheStoreConfig;
import org.infinispan.loaders.jdbc.connectionfactory.ConnectionFactoryConfig;
@@ -264,6 +265,20 @@
this.stringsTableManipulation.setBatchSize(batchSize);
}
+ public String getDatabaseType() {
+ return this.binaryTableManipulation.databaseType == null ? "" : this.binaryTableManipulation.databaseType.toString();
+ }
+
+ /**
+ * Sets the database dialect. Valid types are reflected in the DatabaseType enum. If unspecified, will attempt to
+ * "guess" appropriate dialect from the JDBC driver specified.
+ * @param dbType
+ */
+ public void setDatabaseType(String dbType) {
+ if (dbType != null)
+ this.binaryTableManipulation.databaseType = DatabaseType.valueOf(dbType.toUpperCase().trim());
+ }
+
@Override
public JdbcMixedCacheStoreConfig clone() {
JdbcMixedCacheStoreConfig dolly = (JdbcMixedCacheStoreConfig) super.clone();
Modified: trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStore.java
===================================================================
--- trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStore.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStore.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -220,6 +220,11 @@
}
@Override
+ protected Set<InternalCacheEntry> loadLockSafe(int maxEntries) throws CacheLoaderException {
+ return dmHelper.loadSome(maxEntries);
+ }
+
+ @Override
public void purgeInternal() throws CacheLoaderException {
Connection conn = null;
PreparedStatement ps = null;
Modified: trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStoreConfig.java
===================================================================
--- trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStoreConfig.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStoreConfig.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -22,6 +22,7 @@
package org.infinispan.loaders.jdbc.stringbased;
import org.infinispan.loaders.LockSupportCacheStoreConfig;
+import org.infinispan.loaders.jdbc.DatabaseType;
import org.infinispan.loaders.jdbc.TableManipulation;
import org.infinispan.loaders.jdbc.connectionfactory.ConnectionFactoryConfig;
import org.infinispan.util.Util;
@@ -258,6 +259,21 @@
return this.tableManipulation.getBatchSize();
}
+ public String getDatabaseType() {
+ return this.tableManipulation.databaseType == null ? "" : this.tableManipulation.databaseType.toString();
+ }
+
+ /**
+ * Sets the database dialect. Valid types are reflected in the DatabaseType enum. If unspecified, will attempt to
+ * "guess" appropriate dialect from the JDBC driver specified.
+ * @param dbType
+ */
+ public void setDatabaseType(String dbType) {
+ if (dbType != null)
+ this.tableManipulation.databaseType = DatabaseType.valueOf(dbType.toUpperCase().trim());
+ }
+
+
@Override
public JdbcStringBasedCacheStoreConfig clone() {
JdbcStringBasedCacheStoreConfig result = (JdbcStringBasedCacheStoreConfig) super.clone();
Modified: trunk/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStoreTest2.java
===================================================================
--- trunk/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStoreTest2.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/mixed/JdbcMixedCacheStoreTest2.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -21,6 +21,8 @@
*/
package org.infinispan.loaders.jdbc.mixed;
+import org.easymock.EasyMock;
+import org.infinispan.Cache;
import org.infinispan.loaders.BaseCacheStoreTest;
import org.infinispan.loaders.CacheStore;
import org.infinispan.loaders.jdbc.TableManipulation;
@@ -43,7 +45,10 @@
jdbcCacheStoreConfig.setBinaryTableManipulation(binaryTm);
JdbcMixedCacheStore cacheStore = new JdbcMixedCacheStore();
- cacheStore.init(jdbcCacheStoreConfig, null, getMarshaller());
+ Cache<?, ?> mockCache = EasyMock.createNiceMock(Cache.class);
+ EasyMock.expect(mockCache.getName()).andReturn(getClass().getName()).anyTimes();
+ EasyMock.replay(mockCache);
+ cacheStore.init(jdbcCacheStoreConfig, mockCache, getMarshaller());
cacheStore.start();
return cacheStore;
}
Modified: trunk/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStoreTest2.java
===================================================================
--- trunk/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStoreTest2.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/cachestore/jdbc/src/test/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStoreTest2.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -21,6 +21,8 @@
*/
package org.infinispan.loaders.jdbc.stringbased;
+import org.easymock.EasyMock;
+import org.infinispan.Cache;
import org.infinispan.container.entries.InternalCacheEntry;
import org.infinispan.container.entries.InternalEntryFactory;
import org.infinispan.loaders.CacheLoaderException;
@@ -62,7 +64,10 @@
config.setKey2StringMapperClass(PersonKey2StringMapper.class.getName());
config.setPurgeSynchronously(true);
cacheStore = new JdbcStringBasedCacheStore();
- cacheStore.init(config, null, getMarshaller());
+ Cache<?, ?> mockCache = EasyMock.createNiceMock(Cache.class);
+ EasyMock.expect(mockCache.getName()).andReturn(getClass().getName()).anyTimes();
+ EasyMock.replay(mockCache);
+ cacheStore.init(config, mockCache, getMarshaller());
cacheStore.start();
}
Modified: trunk/cachestore/jdbm/src/main/java/org/infinispan/loaders/jdbm/JdbmCacheStore.java
===================================================================
--- trunk/cachestore/jdbm/src/main/java/org/infinispan/loaders/jdbm/JdbmCacheStore.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/cachestore/jdbm/src/main/java/org/infinispan/loaders/jdbm/JdbmCacheStore.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -130,7 +130,12 @@
public InternalCacheEntry load(Object key) throws CacheLoaderException {
try {
- return unmarshall(tree.get(key), key);
+ InternalCacheEntry ice = unmarshall(tree.get(key), key);
+ if (ice != null && ice.isExpired()) {
+ remove(key);
+ return null;
+ }
+ return ice;
} catch (IOException e) {
throw new CacheLoaderException(e);
} catch (ClassNotFoundException e) {
@@ -142,6 +147,11 @@
return new BTreeSet();
}
+ @Override
+ public Set<InternalCacheEntry> load(int numEntries) throws CacheLoaderException {
+ return new BTreeSet(numEntries);
+ }
+
/**
* Opens all databases and initializes database related information.
*/
@@ -436,6 +446,15 @@
private final class BTreeSet extends AbstractSet<InternalCacheEntry> {
+ int maxSize = -1;
+
+ private BTreeSet(int maxSize) {
+ this.maxSize = maxSize;
+ }
+
+ private BTreeSet() {
+ }
+
@Override
public Iterator<InternalCacheEntry> iterator() {
final FastIterator fi;
@@ -446,7 +465,7 @@
}
return new Iterator<InternalCacheEntry>() {
-
+ int entriesReturned = 0;
InternalCacheEntry current = null;
boolean next = true;
@@ -465,6 +484,7 @@
}
}
}
+ if (next == true && entriesReturned >= maxSize && maxSize > -1) next = false;
return next;
}
@@ -472,6 +492,7 @@
if (!hasNext())
throw new NoSuchElementException();
try {
+ entriesReturned ++;
return current;
} finally {
current = null;
Modified: trunk/cachestore/jdbm/src/test/java/org/infinispan/loaders/jdbm/JdbmCacheStoreFunctionalTest.java
===================================================================
--- trunk/cachestore/jdbm/src/test/java/org/infinispan/loaders/jdbm/JdbmCacheStoreFunctionalTest.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/cachestore/jdbm/src/test/java/org/infinispan/loaders/jdbm/JdbmCacheStoreFunctionalTest.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -27,7 +27,9 @@
import org.infinispan.loaders.CacheStoreConfig;
import org.infinispan.test.TestingUtil;
import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
@@ -36,10 +38,10 @@
private String tmpDirectory;
- @BeforeTest
+ @BeforeClass
@Parameters({"basedir"})
- protected void setUpTempDir(String basedir) {
- tmpDirectory = basedir + TestingUtil.TEST_PATH + File.separator + getClass().getSimpleName();
+ protected void setUpTempDir(@Optional("/tmp") String basedir) {
+ tmpDirectory = TestingUtil.tmpDirectory(basedir, this);
}
@AfterClass
Modified: trunk/cachestore/jdbm/src/test/java/org/infinispan/loaders/jdbm/JdbmCacheStoreTest.java
===================================================================
--- trunk/cachestore/jdbm/src/test/java/org/infinispan/loaders/jdbm/JdbmCacheStoreTest.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/cachestore/jdbm/src/test/java/org/infinispan/loaders/jdbm/JdbmCacheStoreTest.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -12,6 +12,7 @@
import org.infinispan.loaders.CacheStore;
import org.infinispan.test.TestingUtil;
import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
@@ -23,11 +24,10 @@
private JdbmCacheStore fcs;
private String tmpDirectory;
- @BeforeTest
+ @BeforeClass
@Parameters({"basedir"})
- protected void setUpTempDir(@Optional(value = "/tmp")String basedir) {
- tmpDirectory = basedir + File.separator +
- TestingUtil.TEST_PATH + File.separator + getClass().getSimpleName();
+ protected void setUpTempDir(@Optional("/tmp") String basedir) {
+ tmpDirectory = TestingUtil.tmpDirectory(basedir, this);
}
@AfterClass
Modified: trunk/core/src/main/java/org/infinispan/eviction/EvictionStrategy.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/eviction/EvictionStrategy.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/core/src/main/java/org/infinispan/eviction/EvictionStrategy.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -10,5 +10,9 @@
NONE,
UNORDERED,
FIFO,
- LRU
+ LRU;
+
+ public boolean isEnabled() {
+ return this != NONE;
+ }
}
Modified: trunk/core/src/main/java/org/infinispan/loaders/CacheLoader.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/loaders/CacheLoader.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/core/src/main/java/org/infinispan/loaders/CacheLoader.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -44,6 +44,15 @@
Set<InternalCacheEntry> loadAll() throws CacheLoaderException;
/**
+ * Loads up to a specific number of entries. There is no guarantee as to order of entries loaded. The set returned
+ * would contain up to a maximum of <tt>numEntries</tt> entries, and no more.
+ * @param numEntries maximum number of entries to load
+ * @return a set of entries, which would contain between 0 and numEntries entries.
+ * @throws CacheLoaderException
+ */
+ Set<InternalCacheEntry> load(int numEntries) throws CacheLoaderException;
+
+ /**
* @param key key to test
* @return true if the key exists, false otherwise
* @throws CacheLoaderException in the event of problems reading from source
Modified: trunk/core/src/main/java/org/infinispan/loaders/CacheLoaderManagerImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/loaders/CacheLoaderManagerImpl.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/core/src/main/java/org/infinispan/loaders/CacheLoaderManagerImpl.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -24,6 +24,7 @@
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
+import java.util.Collections;
import java.util.Set;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -120,7 +121,7 @@
if (log.isDebugEnabled()) start = System.currentTimeMillis();
Set<InternalCacheEntry> state;
try {
- state = loader.loadAll();
+ state = loadState();
} catch (CacheLoaderException e) {
throw new CacheException("Unable to preload!", e);
}
@@ -135,6 +136,24 @@
}
}
+ private Set<InternalCacheEntry> loadState() throws CacheLoaderException {
+ int ne = -1;
+ if (configuration.getEvictionStrategy().isEnabled()) ne = configuration.getEvictionMaxEntries();
+ Set<InternalCacheEntry> state;
+ switch (ne) {
+ case -1:
+ state = loader.loadAll();
+ break;
+ case 0:
+ state = Collections.emptySet();
+ break;
+ default:
+ state = loader.load(ne);
+ break;
+ }
+ return state;
+ }
+
@Stop
public void stop() {
if (loader != null) try {
Modified: trunk/core/src/main/java/org/infinispan/loaders/LockSupportCacheStore.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/loaders/LockSupportCacheStore.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/core/src/main/java/org/infinispan/loaders/LockSupportCacheStore.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -90,28 +90,34 @@
}
public final InternalCacheEntry load(Object key) throws CacheLoaderException {
- if (trace) log.trace("load ({0})", key);
String lockingKey = getLockFromKey(key);
lockForReading(lockingKey);
try {
return loadLockSafe(key, lockingKey);
} finally {
unlock(lockingKey);
- if (trace) log.trace("Exit load (" + key + ")");
}
}
public final Set<InternalCacheEntry> loadAll() throws CacheLoaderException {
- if (trace) log.trace("loadAll()");
acquireGlobalLock(false);
try {
return loadAllLockSafe();
} finally {
releaseGlobalLock(false);
- if (trace) log.trace("Exit loadAll()");
}
}
+ public final Set<InternalCacheEntry> load(int maxEntries) throws CacheLoaderException {
+ if (maxEntries < 0) return loadAll();
+ acquireGlobalLock(false);
+ try {
+ return loadLockSafe(maxEntries);
+ } finally {
+ releaseGlobalLock(false);
+ }
+ }
+
public final void store(InternalCacheEntry ed) throws CacheLoaderException {
if (trace) log.trace("store(" + ed + ")");
if (ed == null) return;
@@ -185,6 +191,8 @@
protected abstract Set<InternalCacheEntry> loadAllLockSafe() throws CacheLoaderException;
+ protected abstract Set<InternalCacheEntry> loadLockSafe(int maxEntries) throws CacheLoaderException;
+
protected abstract void toStreamLockSafe(ObjectOutput oos) throws CacheLoaderException;
protected abstract void fromStreamLockSafe(ObjectInput ois) throws CacheLoaderException;
Modified: trunk/core/src/main/java/org/infinispan/loaders/cluster/ClusterCacheLoader.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/loaders/cluster/ClusterCacheLoader.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/core/src/main/java/org/infinispan/loaders/cluster/ClusterCacheLoader.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -27,6 +27,8 @@
import java.util.List;
import java.util.Set;
+import static java.util.Collections.emptySet;
+
/**
* Cache loader that consults other members in the cluster for values. A <code>timeout</code> property is required, a
* <code>long</code> that specifies in milliseconds how long to wait for results before returning a null.
@@ -66,9 +68,13 @@
@SuppressWarnings(value = "unchecked")
public Set<InternalCacheEntry> loadAll() throws CacheLoaderException {
- return Collections.emptySet();
+ return emptySet();
}
+ public Set<InternalCacheEntry> load(int maxElems) throws CacheLoaderException {
+ return emptySet();
+ }
+
public void start() throws CacheLoaderException {
//nothing to do here
}
Modified: trunk/core/src/main/java/org/infinispan/loaders/decorators/AbstractDelegatingStore.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/loaders/decorators/AbstractDelegatingStore.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/core/src/main/java/org/infinispan/loaders/decorators/AbstractDelegatingStore.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -90,6 +90,11 @@
return delegate.loadAll();
}
+ @Override
+ public Set<InternalCacheEntry> load(int numEntries) throws CacheLoaderException {
+ return delegate.load(numEntries);
+ }
+
public boolean containsKey(Object key) throws CacheLoaderException {
return delegate.containsKey(key);
}
Modified: trunk/core/src/main/java/org/infinispan/loaders/decorators/ChainingCacheStore.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/loaders/decorators/ChainingCacheStore.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/core/src/main/java/org/infinispan/loaders/decorators/ChainingCacheStore.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -14,6 +14,7 @@
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -115,6 +116,19 @@
return set;
}
+ @Override
+ public Set<InternalCacheEntry> load(int numEntries) throws CacheLoaderException {
+ if (numEntries < 0) return loadAll();
+ Set<InternalCacheEntry> set = new HashSet<InternalCacheEntry>(numEntries);
+ for (CacheStore s: stores.keySet()) {
+ Set<InternalCacheEntry> localSet = s.load(numEntries);
+ Iterator<InternalCacheEntry> i = localSet.iterator();
+ while (set.size() < numEntries && i.hasNext()) set.add(i.next());
+ if (set.size() >= numEntries) break;
+ }
+ return set;
+ }
+
public boolean containsKey(Object key) throws CacheLoaderException {
for (CacheLoader l : loaders.keySet()) {
if (l.containsKey(key)) return true;
Modified: trunk/core/src/main/java/org/infinispan/loaders/file/FileCacheStore.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/loaders/file/FileCacheStore.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/core/src/main/java/org/infinispan/loaders/file/FileCacheStore.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -25,6 +25,7 @@
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.Set;
/**
@@ -73,6 +74,22 @@
return result;
}
+ protected Set<InternalCacheEntry> loadLockSafe(int max) throws CacheLoaderException {
+ Set<InternalCacheEntry> result = new HashSet<InternalCacheEntry>(max);
+ for (File bucketFile : root.listFiles()) {
+ Bucket bucket = loadBucket(bucketFile);
+ if (bucket != null) {
+ if (bucket.removeExpiredEntries()) {
+ updateBucket(bucket);
+ }
+ Iterator<? extends InternalCacheEntry> i = bucket.getStoredEntries().iterator();
+ while (result.size() < max && i.hasNext()) result.add(i.next());
+ }
+ if (result.size() >= max) break;
+ }
+ return result;
+ }
+
protected void fromStreamLockSafe(ObjectInput objectInput) throws CacheLoaderException {
try {
int numFiles = objectInput.readInt();
Modified: trunk/core/src/test/java/org/infinispan/loaders/BaseCacheStoreTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/loaders/BaseCacheStoreTest.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/core/src/test/java/org/infinispan/loaders/BaseCacheStoreTest.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -404,6 +404,22 @@
assert expected.isEmpty();
}
+ public void testPreloadWithMaxSize() throws CacheLoaderException {
+ cs.store(InternalEntryFactory.create("k1", "v1"));
+ cs.store(InternalEntryFactory.create("k2", "v2"));
+ cs.store(InternalEntryFactory.create("k3", "v3"));
+
+ Set<InternalCacheEntry> set = cs.load(2);
+
+ assert set.size() == 2;
+ Set expected = new HashSet();
+ expected.add("k1");
+ expected.add("k2");
+ expected.add("k3");
+ for (InternalCacheEntry se : set) assert expected.remove(se.getKey());
+ assert expected.size() == 1;
+ }
+
public void testStoreAndRemoveAll() throws CacheLoaderException {
cs.store(InternalEntryFactory.create("k1", "v1"));
cs.store(InternalEntryFactory.create("k2", "v2"));
Modified: trunk/core/src/test/java/org/infinispan/loaders/dummy/DummyInMemoryCacheStore.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/loaders/dummy/DummyInMemoryCacheStore.java 2010-03-10 11:17:38 UTC (rev 1583)
+++ trunk/core/src/test/java/org/infinispan/loaders/dummy/DummyInMemoryCacheStore.java 2010-03-10 13:42:39 UTC (rev 1584)
@@ -109,6 +109,21 @@
return s;
}
+ public Set<InternalCacheEntry> load(int numEntries) throws CacheLoaderException {
+ if (numEntries < 0) return loadAll();
+ Set<InternalCacheEntry> s = new HashSet<InternalCacheEntry>(numEntries);
+ for (Iterator<InternalCacheEntry> i = store.values().iterator(); i.hasNext() && s.size() < numEntries;) {
+ InternalCacheEntry se = i.next();
+ if (se.isExpired()) {
+ log.debug("Key {0} exists, but has expired. Entry is {1}", se.getKey(), se);
+ i.remove();
+ } else if (s.size() < numEntries) {
+ s.add(se);
+ }
+ }
+ return s;
+ }
+
public Class<? extends CacheLoaderConfig> getConfigurationClass() {
return Cfg.class;
}
More information about the infinispan-commits
mailing list