
org.terracotta.modules.ehcache.transaction.ReadCommittedClusteredSoftLockFactory Maven / Gradle / Ivy
Go to download
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.
/*
* All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
*/
package org.terracotta.modules.ehcache.transaction;
import net.sf.ehcache.Element;
import net.sf.ehcache.store.Store;
import net.sf.ehcache.transaction.SoftLock;
import net.sf.ehcache.transaction.SoftLockID;
import net.sf.ehcache.transaction.SoftLockManager;
import net.sf.ehcache.transaction.TransactionID;
import net.sf.ehcache.transaction.local.LocalTransactionContext;
import org.terracotta.modules.ehcache.ToolkitInstanceFactory;
import org.terracotta.modules.ehcache.collections.SerializedToolkitCache;
import org.terracotta.toolkit.collections.ToolkitMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author Ludovic Orban
*/
public class ReadCommittedClusteredSoftLockFactory implements SoftLockManager {
private static final Integer DEFAULT_DUMMY_VALUE = Integer
.valueOf(0);
private final String cacheName;
private final String cacheManagerName;
private final ToolkitInstanceFactory toolkitInstanceFactory;
// actually all we need would be a ConcurrentSet...
private final ToolkitMap newKeyLocks;
// locks must be inserted in a clustered collection b/c they must be managed by the L1 before they are returned
private final SerializedToolkitCache allLocks;
public ReadCommittedClusteredSoftLockFactory(ToolkitInstanceFactory toolkitInstanceFactory, String cacheManagerName,
String cacheName) {
this.toolkitInstanceFactory = toolkitInstanceFactory;
this.cacheManagerName = cacheManagerName;
this.cacheName = cacheName;
allLocks = toolkitInstanceFactory.getOrCreateAllSoftLockMap(cacheManagerName, cacheName);
newKeyLocks = toolkitInstanceFactory.getOrCreateNewSoftLocksSet(cacheManagerName, cacheName);
}
@Override
public SoftLockID createSoftLockID(TransactionID transactionID, Object key, Element newElement, Element oldElement) {
if (newElement != null && newElement.getObjectValue() instanceof SoftLockID) { throw new AssertionError(
"newElement must not contain a soft lock ID"); }
if (oldElement != null && oldElement.getObjectValue() instanceof SoftLockID) { throw new AssertionError(
"oldElement must not contain a soft lock ID"); }
SoftLockID lockId = new SoftLockID(transactionID, key, newElement, oldElement);
ClusteredSoftLockIDKey clusteredId = new ClusteredSoftLockIDKey(lockId);
if (allLocks.containsKey(clusteredId)) {
return lockId;
} else {
SerializedReadCommittedClusteredSoftLock softLock = new SerializedReadCommittedClusteredSoftLock(transactionID,
key);
if (allLocks.putIfAbsent(clusteredId, softLock) != null) {
throw new AssertionError();
} else {
if (oldElement == null) {
newKeyLocks.put(softLock, DEFAULT_DUMMY_VALUE);
}
return lockId;
}
}
}
@Override
public SoftLock findSoftLockById(SoftLockID softLockId) {
SerializedReadCommittedClusteredSoftLock serializedSoftLock = allLocks.get(new ClusteredSoftLockIDKey(softLockId));
if (serializedSoftLock == null) {
return null;
}
return serializedSoftLock.getSoftLock(toolkitInstanceFactory, this);
}
ReadCommittedClusteredSoftLock getLock(TransactionID transactionId, Object key) {
for (Map.Entry entry : allLocks.entrySet()) {
SerializedReadCommittedClusteredSoftLock serialized = entry.getValue();
ReadCommittedClusteredSoftLock readCommittedSoftLock = serialized.getSoftLock(toolkitInstanceFactory, this);
if (readCommittedSoftLock.getTransactionID().equals(transactionId) && readCommittedSoftLock.getKey().equals(key)) { return readCommittedSoftLock; }
}
return null;
}
@Override
public Set
© 2015 - 2025 Weber Informatics LLC | Privacy Policy