Author: chetanm
Date: Fri May  8 10:36:44 2015
New Revision: 1678323

URL: http://svn.apache.org/r1678323
Log:
OAK-2855 - CopyOnReadDirectory mode might delete a valid local file upon close

While deleting ensure that list of local file is only containing those file 
name which were added by current directory + the list of files which existed 
before current directory was opened.

This would avoid picking up those files which might have been added by a newly 
opened wrapper directory for same local dir

Modified:
    
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexCopier.java
    
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexCopierTest.java

Modified: 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexCopier.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexCopier.java?rev=1678323&r1=1678322&r2=1678323&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexCopier.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexCopier.java
 Fri May  8 10:36:44 2015
@@ -21,6 +21,7 @@ package org.apache.jackrabbit.oak.plugin
 
 import java.io.File;
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
@@ -164,10 +165,16 @@ class IndexCopier implements CopyOnReadS
         private final Directory local;
 
         private final ConcurrentMap<String, FileReference> files = 
newConcurrentMap();
+        /**
+         * Set of fileNames bound to current local dir. It is updated with any 
new file
+         * which gets added by this directory
+         */
+        private final Set<String> localFileNames = Sets.newConcurrentHashSet();
 
         public CopyOnReadDirectory(Directory remote, Directory local) throws 
IOException {
             this.remote = remote;
             this.local = local;
+            this.localFileNames.addAll(Arrays.asList(local.listAll()));
         }
 
         @Override
@@ -334,7 +341,7 @@ class IndexCopier implements CopyOnReadS
         private void removeDeletedFiles() throws IOException {
             //Files present in dest but not present in source have to be 
deleted
             Set<String> filesToBeDeleted = Sets.difference(
-                    ImmutableSet.copyOf(local.listAll()),
+                    ImmutableSet.copyOf(localFileNames),
                     ImmutableSet.copyOf(remote.listAll())
             );
 
@@ -384,6 +391,7 @@ class IndexCopier implements CopyOnReadS
 
             void markValid(){
                 this.valid = true;
+                localFileNames.add(name);
             }
         }
     }

Modified: 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexCopierTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexCopierTest.java?rev=1678323&r1=1678322&r2=1678323&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexCopierTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexCopierTest.java
 Fri May  8 10:36:44 2015
@@ -436,6 +436,34 @@ public class IndexCopierTest {
         assertEquals(0, c1.getFailedToDeleteFiles().size());
     }
 
+    @Test
+    public void deletedOnlyFilesForOlderVersion() throws Exception{
+        Directory baseDir = new CloseSafeDir();
+
+        IndexDefinition defn = new IndexDefinition(root, 
builder.getNodeState());
+        IndexCopier copier = new RAMIndexCopier(baseDir, sameThreadExecutor(), 
getWorkDir());
+
+        //1. Open a local and read t1 from remote
+        Directory remote1 = new RAMDirectory();
+        byte[] t1 = writeFile(remote1, "t1");
+
+        Directory local1 = copier.wrap("/foo", defn, remote1);
+        readAndAssert(local1, "t1", t1);
+
+        //While local1 is open , open another local2 and read t2
+        Directory remote2 = new RAMDirectory();
+        byte[] t2 = writeFile(remote2, "t2");
+
+        Directory local2 = copier.wrap("/foo", defn, remote2);
+        readAndAssert(local2, "t2", t2);
+
+        //Close local1
+        local1.close();
+
+        //t2 should still be readable
+        readAndAssert(local2, "t2", t2);
+    }
+
     private byte[] writeFile(Directory dir, String name) throws IOException {
         byte[] data = randomBytes(rnd.nextInt(maxFileSize) + 1);
         IndexOutput o = dir.createOutput(name, IOContext.DEFAULT);


Reply via email to