use of org.apache.jackrabbit.oak.plugins.document.NodeDocument in project jackrabbit-oak by apache.
the class NodeDocumentCache method putIfAbsent.
/**
* Puts document into cache iff no entry with the given key is cached
* already. This operation is atomic.
*
* @param doc the document to add to the cache.
* @return either the given <code>doc</code> or the document already present
* in the cache.
*/
@Nonnull
public NodeDocument putIfAbsent(@Nonnull final NodeDocument doc) {
if (doc == NodeDocument.NULL) {
throw new IllegalArgumentException("doc must not be NULL document");
}
doc.seal();
String id = doc.getId();
// make sure we only cache the document if it wasn't
// changed and cached by some other thread in the
// meantime. That is, use get() with a Callable,
// which is only used when the document isn't there
Lock lock = locks.acquire(id);
try {
for (; ; ) {
NodeDocument cached = get(id, new Callable<NodeDocument>() {
@Override
public NodeDocument call() {
return doc;
}
});
if (cached != NodeDocument.NULL) {
return cached;
} else {
invalidate(id);
}
}
} catch (ExecutionException e) {
// the already available doc
throw new IllegalStateException(e);
} finally {
lock.unlock();
}
}
use of org.apache.jackrabbit.oak.plugins.document.NodeDocument in project jackrabbit-oak by apache.
the class NodeDocumentCache method invalidateOutdated.
/**
* Invalidate document with given keys iff their modification stamps are
* different as passed in the map.
*
* @param modStamps map where key is the document id and the value is the
* modification stamps.
* @return number of invalidated entries
*/
@Nonnegative
public int invalidateOutdated(@Nonnull Map<String, ModificationStamp> modStamps) {
int invalidatedCount = 0;
for (Entry<String, ModificationStamp> e : modStamps.entrySet()) {
String id = e.getKey();
ModificationStamp stamp = e.getValue();
NodeDocument doc = getIfPresent(id);
if (doc == null) {
continue;
}
if (!Objects.equal(stamp.modCount, doc.getModCount()) || !Objects.equal(stamp.modified, doc.getModified())) {
invalidate(id);
invalidatedCount++;
}
}
return invalidatedCount;
}
use of org.apache.jackrabbit.oak.plugins.document.NodeDocument in project jackrabbit-oak by apache.
the class NodeDocumentCache method replaceCachedDocument.
/**
* Replaces the cached value if the old document is currently present in
* the cache. If the {@code oldDoc} is not cached, nothing will happen. If
* {@code oldDoc} does not match the document currently in the cache, then
* the cached document is invalidated.
*
* @param oldDoc the old document
* @param newDoc the replacement
*/
public void replaceCachedDocument(@Nonnull final NodeDocument oldDoc, @Nonnull final NodeDocument newDoc) {
if (newDoc == NodeDocument.NULL) {
throw new IllegalArgumentException("doc must not be NULL document");
}
String key = oldDoc.getId();
Lock lock = locks.acquire(key);
try {
NodeDocument cached = getIfPresent(key);
if (cached != null) {
if (Objects.equal(cached.getModCount(), oldDoc.getModCount())) {
putInternal(newDoc);
} else {
// the cache entry was modified by some other thread in
// the meantime. the updated cache entry may or may not
// include this update. we cannot just apply our update
// on top of the cached entry.
// therefore we must invalidate the cache entry
invalidate(key);
}
}
} finally {
lock.unlock();
}
}
use of org.apache.jackrabbit.oak.plugins.document.NodeDocument in project jackrabbit-oak by apache.
the class NodeDocumentCache method get.
/**
* Return the document matching given key, optionally loading it from an
* external source.
* <p>
* This method can modify the cache, so it's synchronized. The {@link #getIfPresent(String)}
* is not synchronized and will be faster if you need to get the cached value
* outside the critical section.
*
* @see Cache#get(Object, Callable)
* @param key document key
* @param valueLoader object used to retrieve the document
* @return document matching given key
*/
@Nonnull
public NodeDocument get(@Nonnull final String key, @Nonnull final Callable<NodeDocument> valueLoader) throws ExecutionException {
Callable<NodeDocument> wrappedLoader = new Callable<NodeDocument>() {
@Override
public NodeDocument call() throws Exception {
for (CacheChangesTracker tracker : changeTrackers) {
tracker.putDocument(key);
}
return valueLoader.call();
}
};
Lock lock = locks.acquire(key);
try {
if (isLeafPreviousDocId(key)) {
return prevDocumentsCache.get(new StringValue(key), wrappedLoader);
} else {
return nodeDocumentsCache.get(new StringValue(key), wrappedLoader);
}
} finally {
lock.unlock();
}
}
use of org.apache.jackrabbit.oak.plugins.document.NodeDocument in project jackrabbit-oak by apache.
the class CacheChangesTrackerTest method createCache.
private NodeDocumentCache createCache() {
Cache<CacheValue, NodeDocument> nodeDocumentsCache = new CacheLIRS<CacheValue, NodeDocument>(10);
Cache<StringValue, NodeDocument> prevDocumentsCache = new CacheLIRS<StringValue, NodeDocument>(10);
CacheStats nodeDocumentsCacheStats = Mockito.mock(CacheStats.class);
CacheStats prevDocumentsCacheStats = Mockito.mock(CacheStats.class);
NodeDocumentLocks locks = new StripedNodeDocumentLocks();
return new NodeDocumentCache(nodeDocumentsCache, nodeDocumentsCacheStats, prevDocumentsCache, prevDocumentsCacheStats, locks);
}
Aggregations