org.modeshape.persistence.relational.TransactionalCaches Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of modeshape-persistence-relational Show documentation
Show all versions of modeshape-persistence-relational Show documentation
ModeShape Persistence Provider which stores content in relational databases
The newest version!
/*
* ModeShape (http://www.modeshape.org)
*
* 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 org.modeshape.persistence.relational;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;
import org.modeshape.common.annotation.ThreadSafe;
import org.modeshape.schematic.document.Document;
import org.modeshape.schematic.internal.document.BasicDocument;
/**
* Class which provides a set of in-memory caches for each ongoing transaction, attempting to relieve some of the "read pressure"
* for transactions.
*
* @author Horia Chiorean ([email protected])
* @since 5.0
*/
@ThreadSafe
public final class TransactionalCaches {
protected static final Document REMOVED = new BasicDocument() {
@Override
public String toString() {
return "DOCUMENT_REMOVED";
}
};
private final Map cachesByTxId;
protected TransactionalCaches() {
this.cachesByTxId = new ConcurrentHashMap<>();
}
protected Document search(String key) {
TransactionalCache cache = cacheForActiveTransaction();
Document doc = cache.getFromWriteCache(key);
if (doc != null) {
return doc;
}
return cache.getFromReadCache(key);
}
protected Document getForWriting(String key) {
return cacheForActiveTransaction().getFromWriteCache(key);
}
protected void putForReading(String key, Document doc) {
if (!TransactionsHolder.hasActiveTransaction()) {
return;
}
cacheForActiveTransaction().putForReading(key, doc);
}
protected Document putForWriting(String key, Document doc) {
return cacheForActiveTransaction().putForWriting(key, doc);
}
protected Set documentKeys() {
TransactionalCache transactionalCache = cacheForActiveTransaction();
return transactionalCache.writeCache().entrySet()
.stream()
.filter(entry -> !transactionalCache.isRemoved(entry.getKey()))
.map(Map.Entry::getKey)
.collect(Collectors.toSet());
}
protected boolean isRemoved(String key) {
return cacheForActiveTransaction().isRemoved(key);
}
protected void remove(String key) {
cacheForActiveTransaction().remove(key);
}
protected boolean isNew(String key) {
return cacheForActiveTransaction().isNew(key);
}
protected void putNew(String key) {
if (!TransactionsHolder.hasActiveTransaction()) {
return;
}
cacheForActiveTransaction().putNew(key);
}
protected void putNew(Collection keys) {
if (!TransactionsHolder.hasActiveTransaction()) {
return;
}
cacheForActiveTransaction().putNew(keys);
}
protected void clearCache(String txId) {
cachesByTxId.remove(txId);
}
protected void stop() {
cachesByTxId.clear();
}
private TransactionalCache cacheForActiveTransaction() {
String activeTxId = TransactionsHolder.requireActiveTransaction();
return cachesByTxId.computeIfAbsent(activeTxId, TransactionalCache::new);
}
protected TransactionalCache cacheForTransaction(String txId) {
return cachesByTxId.get(txId);
}
protected static class TransactionalCache {
private final ConcurrentMap read = new ConcurrentHashMap<>();
private final ConcurrentMap write = new ConcurrentHashMap<>();
private final Set newIds = Collections.newSetFromMap(new ConcurrentHashMap<>());
protected TransactionalCache(String txId) {
}
protected Document getFromReadCache(String id) {
return read.get(id);
}
protected Document getFromWriteCache(String id) {
return write.get(id);
}
protected void putForReading(String id, Document doc) {
read.put(id, doc);
}
protected Document putForWriting(String id, Document doc) {
if (write.replace(id, doc) == null) {
// when storing a value for the first time, clone it for the write cache
write.putIfAbsent(id, doc.clone());
}
return write.get(id);
}
protected void putNew(String id) {
newIds.add(id);
}
protected void putNew(Collection ids) {
newIds.addAll(ids);
}
protected boolean isNew(String id) {
return newIds.contains(id);
}
protected boolean isRemoved(String id) {
return write.get(id) == REMOVED;
}
protected void remove(String id) {
write.put(id, REMOVED);
}
protected ConcurrentMap writeCache() {
return write;
}
protected ConcurrentMap readCache() {
return read;
}
protected void clear() {
read.clear();
write.clear();
newIds.clear();
}
}
}