use of org.apache.jackrabbit.oak.plugins.document.NodeDocument in project jackrabbit-oak by apache.
the class MongoDocumentStore method getMongoReadPreference.
<T extends Document> ReadPreference getMongoReadPreference(@Nonnull Collection<T> collection, @Nullable String parentId, @Nullable String documentId, @Nonnull DocumentReadPreference preference) {
switch(preference) {
case PRIMARY:
return ReadPreference.primary();
case PREFER_PRIMARY:
return ReadPreference.primaryPreferred();
case PREFER_SECONDARY:
return getConfiguredReadPreference(collection);
case PREFER_SECONDARY_IF_OLD_ENOUGH:
if (collection != Collection.NODES) {
return ReadPreference.primary();
}
boolean secondarySafe;
if (fallbackSecondaryStrategy) {
// This is not quite accurate, because ancestors
// are updated in a background thread (_lastRev). We
// will need to revise this for low maxReplicationLagMillis
// values
long replicationSafeLimit = getTime() - maxReplicationLagMillis;
if (parentId == null) {
secondarySafe = false;
} else {
//If parent has been modified loooong time back then there children
//would also have not be modified. In that case we can read from secondary
NodeDocument cachedDoc = nodesCache.getIfPresent(parentId);
secondarySafe = cachedDoc != null && !cachedDoc.hasBeenModifiedSince(replicationSafeLimit);
}
} else if (localChanges != null) {
secondarySafe = true;
secondarySafe &= collection == Collection.NODES;
secondarySafe &= documentId == null || !localChanges.mayContain(documentId);
secondarySafe &= parentId == null || !localChanges.mayContainChildrenOf(parentId);
secondarySafe &= mostRecentAccessedRevisions == null || replicaInfo.isMoreRecentThan(mostRecentAccessedRevisions);
} else {
// localChanges not initialized yet
secondarySafe = false;
}
ReadPreference readPreference;
if (secondarySafe) {
readPreference = getConfiguredReadPreference(collection);
} else {
readPreference = ReadPreference.primary();
}
return readPreference;
default:
throw new IllegalArgumentException("Unsupported usage " + preference);
}
}
use of org.apache.jackrabbit.oak.plugins.document.NodeDocument in project jackrabbit-oak by apache.
the class NodeDocumentCache method putNonConflictingDocs.
/**
* Updates the cache with all the documents that:
*
* (1) currently have their older versions in the cache or
* (2) have been neither put nor invalidated during the tracker lifetime.
*
* We can't cache documents that has been invalidated during the tracker
* lifetime, as it's possible that the invalidated version was newer than
* the one passed in the docs parameter.
*
* If the document has been added during the tracker lifetime, but it is not
* present in the cache anymore, it means it may have been evicted, so we
* can't re-add it for the same reason as above.
*
* @param tracker
* used to decide whether the docs should be put into cache
* @param docs
* to put into cache
*/
public void putNonConflictingDocs(CacheChangesTracker tracker, Iterable<NodeDocument> docs) {
for (NodeDocument d : docs) {
if (d == null || d == NodeDocument.NULL) {
continue;
}
String id = d.getId();
Lock lock = locks.acquire(id);
try {
NodeDocument cachedDoc = getIfPresent(id);
// if an old document is present in the cache, we can simply update it
if (cachedDoc != null && isNewer(cachedDoc, d)) {
putInternal(d);
// if the document hasn't been invalidated or added during the tracker lifetime,
// we can put it as well
} else if (cachedDoc == null && !tracker.mightBeenAffected(id)) {
putInternal(d);
}
} finally {
lock.unlock();
}
}
}
use of org.apache.jackrabbit.oak.plugins.document.NodeDocument in project jackrabbit-oak by apache.
the class NodeDocumentCache method putIfNewer.
/**
* Puts document into cache iff no entry with the given key is cached
* already or the cached document is older (has smaller {@link Document#MOD_COUNT}).
*
* @param doc the document to add to the cache
* @return either the given <code>doc</code> or the document already present
* in the cache if it's newer
*/
@Nonnull
public NodeDocument putIfNewer(@Nonnull final NodeDocument doc) {
if (doc == NodeDocument.NULL) {
throw new IllegalArgumentException("doc must not be NULL document");
}
doc.seal();
NodeDocument newerDoc;
String id = doc.getId();
Lock lock = locks.acquire(id);
try {
NodeDocument cachedDoc = getIfPresent(id);
if (isNewer(cachedDoc, doc)) {
newerDoc = doc;
putInternal(doc);
} else {
newerDoc = cachedDoc;
}
} finally {
lock.unlock();
}
return newerDoc;
}
use of org.apache.jackrabbit.oak.plugins.document.NodeDocument in project jackrabbit-oak by apache.
the class RDBCacheConsistencyIT method runTest.
private void runTest() throws Throwable {
addNodes(null, "/test", "/test/foo");
final List<Throwable> exceptions = Collections.synchronizedList(new ArrayList<Throwable>());
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
String id = Utils.getIdFromPath("/test/foo");
List<String> ids = Lists.newArrayList();
ids.add(id);
long v = 0;
while (exceptions.isEmpty()) {
try {
UpdateOp op = new UpdateOp(ids.get(0), false);
op.set("p", ++v);
op.set("mb", "update");
store.update(NODES, ids, op);
NodeDocument doc = store.find(NODES, id);
Object p = doc.get("p");
assertEquals("Unexpected result after update-then-find sequence, last modification of document by '" + doc.get("mb") + "' thread @" + doc.getModCount(), v, ((Long) p).longValue());
// System.out.println("u @" + doc.getModCount() + " p=" + v + "; q=" + doc.get("q"));
} catch (Throwable e) {
exceptions.add(e);
}
}
}
}, "update");
t1.start();
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
String id = Utils.getIdFromPath("/test/foo");
long v = 0;
long lastWrittenV = 0;
while (exceptions.isEmpty()) {
try {
UpdateOp op = new UpdateOp(id, false);
op.set("q", ++v);
op.set("mb", "findAndUpdate");
NodeDocument old = store.findAndUpdate(NODES, op);
Object q = old.get("q");
if (q != null) {
assertEquals("Unexpected result after findAndUpdate, last modification of document by '" + old.get("mb") + "' thread @" + old.getModCount(), lastWrittenV, ((Long) q).longValue());
}
lastWrittenV = v;
// System.out.println("f @" + old.getModCount() + " p=" + old.get("p") + "; q=" + q);
} catch (DocumentStoreException e) {
// System.err.println("f update of v to " + v + " failed: " + e.getMessage());
// keep going, RDBDocumentStore might have given up due
// to race conditions
} catch (Throwable e) {
exceptions.add(e);
}
}
}
}, "findAndUpdate");
t2.start();
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
String id = Utils.getIdFromPath("/test/foo");
long p = 0;
long q = 0;
long mc = 0;
while (exceptions.isEmpty()) {
try {
NodeDocument doc = store.find(NODES, id);
if (doc != null) {
Object value = doc.get("p");
if (value != null) {
assertTrue("reader thread at @" + doc.getModCount() + ": observed property value for 'p' (incremented by 'update' thread) decreased, last change by '" + doc.get("mb") + "' thread; previous: " + p + " (at @" + mc + "), now: " + value, (Long) value >= p);
p = (Long) value;
}
value = doc.get("q");
if (value != null) {
assertTrue("reader thread at @" + doc.getModCount() + ": observed property value for 'q' (incremented by 'findAndUpdate' thread) decreased, last change by '" + doc.get("mb") + "' thread; previous: " + q + " (at @" + mc + "), now: " + value, (Long) value >= q);
q = (Long) value;
}
}
mc = doc.getModCount();
} catch (Throwable e) {
exceptions.add(e);
}
}
}
}, "reader");
t3.start();
NodeDocumentCache cache = store.getNodeDocumentCache();
// run for at most five seconds
long end = System.currentTimeMillis() + 1000;
String id = Utils.getIdFromPath("/test/foo");
while (t1.isAlive() && t2.isAlive() && t3.isAlive() && System.currentTimeMillis() < end) {
if (cache.getIfPresent(id) != null) {
Thread.sleep(0, (int) (Math.random() * 100));
// simulate eviction
cache.invalidate(id);
}
}
for (Throwable e : exceptions) {
throw e;
}
exceptions.add(new Exception("end"));
t1.join();
t2.join();
t3.join();
}
use of org.apache.jackrabbit.oak.plugins.document.NodeDocument in project jackrabbit-oak by apache.
the class RDBDocumentSerializerTest method testNullModified.
@Test
public void testNullModified() throws UnsupportedEncodingException {
RDBRow row = new RDBRow("_foo", 1L, true, null, 2l, 3l, "{}", null);
NodeDocument doc = this.ser.fromRow(Collection.NODES, row);
assertNull(doc.getModified());
}
Aggregations