/* * JBoss, Home of Professional Open Source * Copyright 2009 Red Hat Inc. and/or its affiliates and other * contributors as indicated by the @author tags. All rights reserved. * See the copyright.txt in the distribution for a full listing of * individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.infinispan.loaders.bdbje; import com.sleepycat.bind.EntryBinding; import com.sleepycat.bind.serial.SerialBinding; import com.sleepycat.bind.serial.StoredClassCatalog; import com.sleepycat.collections.CurrentTransaction; import com.sleepycat.collections.StoredMap; import com.sleepycat.collections.StoredSortedMap; import com.sleepycat.je.*; import com.sleepycat.util.ExceptionUnwrapper; import org.infinispan.CacheException; import org.infinispan.container.entries.InternalCacheEntry; import org.infinispan.marshall.StreamingMarshaller; import org.infinispan.util.logging.Log; import org.infinispan.util.logging.LogFactory; import java.io.File; import java.util.Properties; import java.util.concurrent.TimeUnit; /** * Factory that assembles objects specific to the SleepyCat JE API. * * @author Adrian Cole * @since 4.0 */ public class BdbjeResourceFactory { private static final Log log = LogFactory.getLog(BdbjeResourceFactory.class); private static final boolean trace = log.isTraceEnabled(); private BdbjeCacheStoreConfig config; public BdbjeResourceFactory(BdbjeCacheStoreConfig config) { this.config = config; } /** * @return PreparableTransactionRunner that will try to resolve deadlocks maximum of {@link * BdbjeCacheStoreConfig#getMaxTxRetries()} times. */ public PreparableTransactionRunner createPreparableTransactionRunner(Environment env) { return new PreparableTransactionRunner(env, config.getMaxTxRetries(), null); } public CurrentTransaction createCurrentTransaction(Environment env) { return CurrentTransaction.getInstance(env); } /** * Open the environment, creating it if it doesn't exist. * * @param envLocation base directory where the Environment will write files * @return open Environment with a lock timeout of {@link org.infinispan.loaders.bdbje.BdbjeCacheStoreConfig#getLockAcquistionTimeout()} * milliseconds. */ public Environment createEnvironment(File envLocation, Properties environmentProperties) throws DatabaseException { EnvironmentConfig envConfig = environmentProperties == null ? new EnvironmentConfig() : new EnvironmentConfig(environmentProperties); envConfig.setAllowCreate(true); envConfig.setTransactional(true); envConfig.setLockTimeout(config.getLockAcquistionTimeout(), TimeUnit.MILLISECONDS); if (trace) log.tracef("opening or creating je environment at %s", envLocation); Environment env = new Environment(envLocation, envConfig); log.debugf("opened je environment at %s", envLocation); return env; } public StoredClassCatalog createStoredClassCatalog(Database catalogDb) throws DatabaseException { StoredClassCatalog catalog = new StoredClassCatalog(catalogDb); log.debugf("created stored class catalog from database %s", config.getCatalogDbName()); return catalog; } /** * Open the database, creating it if it doesn't exist. * * @return open transactional Database */ public Database createDatabase(Environment env, String name) throws DatabaseException { DatabaseConfig dbConfig = new DatabaseConfig(); dbConfig.setTransactional(true); dbConfig.setAllowCreate(true); if (trace) log.tracef("opening or creating database %s", name); Database db = env.openDatabase(null, name, dbConfig); log.debugf("opened database %s", name); return db; } /** * create a {@link com.sleepycat.collections.StoredMap} persisted by the <code>database</code> * * @param database where entries in the StoredMap are persisted * @param classCatalog location to store class descriptions * @return StoredMap backed by the database and classCatalog * @throws com.sleepycat.je.DatabaseException * if the StoredMap cannot be opened. */ public StoredMap<Object, InternalCacheEntry> createStoredMapViewOfDatabase(Database database, StoredClassCatalog classCatalog, StreamingMarshaller m) throws DatabaseException { EntryBinding<Object> storedEntryKeyBinding = new SerialBinding<Object>(classCatalog, Object.class); EntryBinding<InternalCacheEntry> storedEntryValueBinding = new InternalCacheEntryBinding(m); try { return new StoredMap<Object, InternalCacheEntry>(database, storedEntryKeyBinding, storedEntryValueBinding, true); } catch (Exception caught) { caught = ExceptionUnwrapper.unwrap(caught); throw new CacheException("Error opening stored map", caught); } } /** * create a {@link com.sleepycat.collections.StoredMap} persisted by the <code>database</code> * * @param database where entries in the StoredMap are persisted * @param classCatalog location to store class descriptions * @return StoredMap backed by the database and classCatalog * @throws com.sleepycat.je.DatabaseException * if the StoredMap cannot be opened. */ public StoredSortedMap<Long, Object> createStoredSortedMapForKeyExpiry(Database database, StoredClassCatalog classCatalog, StreamingMarshaller marshaller) throws DatabaseException { EntryBinding<Long> expiryKeyBinding = new SerialBinding<Long>(classCatalog, Long.class); EntryBinding<Object> expiryValueBinding = new SerialBinding<Object>(classCatalog, Object.class); try { return new StoredSortedMap<Long, Object>(database, expiryKeyBinding, expiryValueBinding, true); } catch (Exception caught) { caught = ExceptionUnwrapper.unwrap(caught); throw new CacheException("error opening stored map", caught); } } }