You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by mr...@apache.org on 2014/04/22 08:32:21 UTC
svn commit: r1589025 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java
test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java
Author: mreutegg
Date: Tue Apr 22 06:32:20 2014
New Revision: 1589025
URL: http://svn.apache.org/r1589025
Log:
OAK-1749: AsyncIndexUpdate may resurrect nodes
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java?rev=1589025&r1=1589024&r2=1589025&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java Tue Apr 22 06:32:20 2014
@@ -148,7 +148,7 @@ public class AsyncIndexUpdate implements
return;
}
- NodeBuilder builder = store.getRoot().builder();
+ NodeBuilder builder = after.builder();
NodeBuilder async = builder.child(ASYNC);
NodeState before = null;
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java?rev=1589025&r1=1589024&r2=1589025&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java Tue Apr 22 06:32:20 2014
@@ -20,11 +20,17 @@ import static org.apache.jackrabbit.oak.
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_CONTENT_NODE_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.createIndexDefinition;
+import static org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider.TYPE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
+import java.util.Collections;
import java.util.Set;
+import java.util.concurrent.Semaphore;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
@@ -138,10 +144,10 @@ public class AsyncIndexUpdateTest {
PropertyIndexLookup lookup = new PropertyIndexLookup(root);
assertEquals(ImmutableSet.of("testRoot"), find(lookup, "foo", "abc"));
- assertEquals(ImmutableSet.of(), find(lookup, "foo", "def"));
- assertEquals(ImmutableSet.of(), find(lookup, "foo", "ghi"));
+ assertEquals(ImmutableSet.<String>of(), find(lookup, "foo", "def"));
+ assertEquals(ImmutableSet.<String>of(), find(lookup, "foo", "ghi"));
- assertEquals(ImmutableSet.of(), find(lookup, "bar", "abc"));
+ assertEquals(ImmutableSet.<String>of(), find(lookup, "bar", "abc"));
assertEquals(ImmutableSet.of("testRoot"), find(lookup, "bar", "def"));
assertEquals(ImmutableSet.of("testSecond"), find(lookup, "bar", "ghi"));
@@ -195,7 +201,76 @@ public class AsyncIndexUpdateTest {
.getChildNode("newchild").getChildNode("other"));
assertEquals(ImmutableSet.of("testChild"),
find(lookupChild, "foo", "xyz"));
- assertEquals(ImmutableSet.of(), find(lookupChild, "foo", "abc"));
+ assertEquals(ImmutableSet.<String>of(), find(lookupChild, "foo", "abc"));
}
+ // OAK-1749
+ @Test
+ public void branchBaseOnCheckpoint() throws Exception {
+ final Semaphore retrieve = new Semaphore(1);
+ final Semaphore checkpoint = new Semaphore(0);
+ NodeStore store = new MemoryNodeStore() {
+ @CheckForNull
+ @Override
+ public NodeState retrieve(@Nonnull String checkpoint) {
+ retrieve.acquireUninterruptibly();
+ try {
+ return super.retrieve(checkpoint);
+ } finally {
+ retrieve.release();
+ }
+ }
+
+ @Nonnull
+ @Override
+ public String checkpoint(long lifetime) {
+ try {
+ return super.checkpoint(lifetime);
+ } finally {
+ checkpoint.release();
+ }
+ }
+ };
+ IndexEditorProvider provider = new PropertyIndexEditorProvider();
+
+ NodeBuilder builder = store.getRoot().builder();
+ createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME), "foo", false, ImmutableSet.of("foo"), null, TYPE, Collections.singletonMap(ASYNC_PROPERTY_NAME, "async"));
+
+ builder.child("test").setProperty("foo", "a");
+ builder.child("child");
+
+ store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+
+ final AsyncIndexUpdate async = new AsyncIndexUpdate("async", store, provider);
+ async.run();
+
+ builder = store.getRoot().builder();
+ builder.child("test").setProperty("foo", "b");
+ builder.child("child").setProperty("prop", "value");
+ store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+
+ Thread t = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ async.run();
+ }
+ });
+ // drain checkpoint permits
+ checkpoint.acquireUninterruptibly(checkpoint.availablePermits());
+ // block NodeStore.retrieve()
+ retrieve.acquireUninterruptibly();
+ t.start();
+
+ // wait until async update called checkpoint
+ checkpoint.acquireUninterruptibly();
+ builder = store.getRoot().builder();
+ builder.child("child").remove();
+ store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+
+ // allow async update to proceed with NodeStore.retrieve()
+ retrieve.release();
+ t.join();
+
+ assertFalse(store.getRoot().hasChildNode("child"));
+ }
}