![JAR search and dependency download from the Maven repository](/logo.png)
net.sf.ehcache.store.TxCopyingCacheStore Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ehcache Show documentation
Show all versions of ehcache Show documentation
Ehcache is an open source, standards-based cache used to boost performance,
offload the database and simplify scalability. Ehcache is robust, proven and full-featured and
this has made it the most widely-used Java-based cache.
/**
* Copyright Terracotta, Inc.
*
* Licensed 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 net.sf.ehcache.store;
import net.sf.ehcache.Element;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.store.compound.ReadWriteCopyStrategy;
import net.sf.ehcache.transaction.AbstractTransactionStore;
import net.sf.ehcache.transaction.SoftLockID;
/**
* Copies elements, either on read, write or both before using the underlying store to actually store things.
* When copying both ways, the store might not see the same types being stored.
* Also exposes a method to get the old value from an entry currently mutated in a transaction.
*
* @param the store type it wraps
*
* @author ljacomet
*/
public final class TxCopyingCacheStore extends AbstractCopyingCacheStore {
/**
* Creates a copying instance of store, that wraps the actual storage
*
* @param store the real store
* @param copyOnRead whether to copy on reads
* @param copyOnWrite whether to copy on writes
* @param copyStrategyInstance the copy strategy to use on every copy operation
* @param loader classloadaer of the containing cache
*/
public TxCopyingCacheStore(T store, boolean copyOnRead, boolean copyOnWrite, ReadWriteCopyStrategy copyStrategyInstance, ClassLoader loader) {
super(store, copyOnRead, copyOnWrite, copyStrategyInstance, loader);
if (!(store instanceof AbstractTransactionStore)) {
throw new IllegalArgumentException("TxCopyingCacheStore can only wrap a transactional store");
}
}
/**
* Gets an element from the store, choosing the old value in case the element is currently mutated inside a transaction.
*
* @param key the key to look for
* @return the matching element, null if not found
*/
public Element getOldElement(Object key) {
return getCopyStrategyHandler().copyElementForReadIfNeeded(((AbstractTransactionStore)getUnderlyingStore()).getOldElement(key));
}
/**
* Wraps the Store instance passed in, should any copy occur
* @param cacheStore the store
* @param cacheConfiguration the cache config for that store
* @return the wrapped Store if copying is required, or the Store instance passed in
*/
public static Store wrapTxStore(final AbstractTransactionStore cacheStore, final CacheConfiguration cacheConfiguration) {
if (CopyingCacheStore.requiresCopy(cacheConfiguration)) {
return wrap(cacheStore, cacheConfiguration);
}
return cacheStore;
}
/**
* Wraps (always) with the proper configured CopyingCacheStore
* @param cacheStore the store to wrap
* @param cacheConfiguration the cache config backed by this store
* @param the Store type
* @return the wrapped store
*/
private static TxCopyingCacheStore wrap(final T cacheStore, final CacheConfiguration cacheConfiguration) {
final ReadWriteCopyStrategy copyStrategyInstance = cacheConfiguration.getCopyStrategyConfiguration()
.getCopyStrategyInstance(cacheConfiguration.getClassLoader());
return new TxCopyingCacheStore(cacheStore, cacheConfiguration.isCopyOnRead(), cacheConfiguration.isCopyOnWrite(), copyStrategyInstance, cacheConfiguration.getClassLoader());
}
/**
* Wraps the given {@link net.sf.ehcache.store.ElementValueComparator} if the configuration requires copy on read
*
* @param comparator the comparator to wrap
* @param cacheConfiguration the cache configuration
* @return the comparator passed if no copy needed, a wrapped comparator otherwise
*/
public static ElementValueComparator wrap(final ElementValueComparator comparator, final CacheConfiguration cacheConfiguration) {
final ReadWriteCopyStrategy copyStrategyInstance = cacheConfiguration.getCopyStrategyConfiguration()
.getCopyStrategyInstance(cacheConfiguration.getClassLoader());
CopyStrategyHandler copyStrategyHandler = new CopyStrategyHandler(cacheConfiguration.isCopyOnRead(),
cacheConfiguration.isCopyOnWrite(),
copyStrategyInstance, cacheConfiguration.getClassLoader());
return new TxCopyingElementValueComparator(comparator, copyStrategyHandler);
}
/**
* An {@link net.sf.ehcache.store.ElementValueComparator} which handles copy on read and {@link SoftLockID}
*/
private static class TxCopyingElementValueComparator implements ElementValueComparator {
private final ElementValueComparator delegate;
private final CopyStrategyHandler copyStrategyHandler;
public TxCopyingElementValueComparator(ElementValueComparator delegate, CopyStrategyHandler copyStrategyHandler) {
this.delegate = delegate;
this.copyStrategyHandler = copyStrategyHandler;
}
@Override
public boolean equals(Element e1, Element e2) {
if (e1 == null && e2 == null) {
return true;
} else if (e1 == null || e2 == null) {
return false;
}
if (!(e1.getObjectValue() instanceof SoftLockID)) {
e1 = copyStrategyHandler.copyElementForReadIfNeeded(e1);
}
if (!(e2.getObjectValue() instanceof SoftLockID)) {
e2 = copyStrategyHandler.copyElementForReadIfNeeded(e2);
}
return delegate.equals(e1, e2);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy