You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2008/03/05 14:45:32 UTC

svn commit: r633844 - in /jackrabbit/branches/1.4/jackrabbit-core/src: main/java/org/apache/jackrabbit/core/data/ main/java/org/apache/jackrabbit/core/data/db/ main/java/org/apache/jackrabbit/core/persistence/bundle/ test/java/org/apache/jackrabbit/cor...

Author: jukka
Date: Wed Mar  5 05:45:30 2008
New Revision: 633844

URL: http://svn.apache.org/viewvc?rev=633844&view=rev
Log:
1.4: Merged revision 631905 (JCR-1414)

Added:
    jackrabbit/branches/1.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/GCConcurrentTest.java
      - copied unchanged from r631905, jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/GCConcurrentTest.java
    jackrabbit/branches/1.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/GCThread.java
      - copied unchanged from r631905, jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/GCThread.java
Modified:
    jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/FileDataStore.java
    jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/GarbageCollector.java
    jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java
    jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java
    jackrabbit/branches/1.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TestAll.java

Modified: jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/FileDataStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/FileDataStore.java?rev=633844&r1=633843&r2=633844&view=diff
==============================================================================
--- jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/FileDataStore.java (original)
+++ jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/FileDataStore.java Wed Mar  5 05:45:30 2008
@@ -25,8 +25,10 @@
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.WeakHashMap;
 
 /**
@@ -94,7 +96,7 @@
     /**
      * All data identifiers that are currently in use are in this set until they are garbage collected.
      */
-    private WeakHashMap inUse = new WeakHashMap();
+    protected Map inUse = Collections.synchronizedMap(new WeakHashMap());
 
     /**
      * Creates a uninitialized data store.
@@ -129,12 +131,14 @@
      */
     public DataRecord getRecord(DataIdentifier identifier) {
         File file = getFile(identifier);
-        if (minModifiedDate != 0 && file.exists() && file.canWrite()) {
-            if (file.lastModified() < minModifiedDate) {
-                file.setLastModified(System.currentTimeMillis());
+        synchronized (this) {
+            if (minModifiedDate != 0 && file.exists() && file.canWrite()) {
+                if (file.lastModified() < minModifiedDate) {
+                    file.setLastModified(System.currentTimeMillis());
+                }
             }
+            usesIdentifier(identifier);
         }
-        usesIdentifier(identifier);
         return new FileDataRecord(identifier, file);
     }
     
@@ -173,35 +177,40 @@
             } finally {
                 output.close();
             }
-
-            // Check if the same record already exists, or
-            // move the temporary file in place if needed
             DataIdentifier identifier = new DataIdentifier(digest.digest());
-            usesIdentifier(identifier);
-            File file = getFile(identifier);
-            File parent = file.getParentFile();
-            if (!parent.isDirectory()) {
-                parent.mkdirs();
-            }
-            if (!file.exists()) {
-                temporary.renameTo(file);
+            File file;
+
+            synchronized (this) {
+                // Check if the same record already exists, or
+                // move the temporary file in place if needed
+                usesIdentifier(identifier);
+                file = getFile(identifier);
+                File parent = file.getParentFile();
+                if (!parent.isDirectory()) {
+                    parent.mkdirs();
+                }
                 if (!file.exists()) {
-                    throw new IOException("Can not rename " + temporary.getAbsolutePath() + " to " + file.getAbsolutePath() + " (media read only?)");
+                    temporary.renameTo(file);
+                    if (!file.exists()) {
+                        throw new IOException(
+                                "Can not rename " + temporary.getAbsolutePath()
+                                + " to " + file.getAbsolutePath()
+                                + " (media read only?)");
+                    }
+                } else {
+                    long now = System.currentTimeMillis();
+                    if (file.lastModified() < now) {
+                        file.setLastModified(now);
+                    }
                 }
-            } else {
-                long now = System.currentTimeMillis();
-                if (file.lastModified() < now) {
-                    file.setLastModified(now);
+                // Sanity checks on the record file. These should never fail,
+                // but better safe than sorry...
+                if (!file.isFile()) {
+                    throw new IOException("Not a file: " + file);
+                }
+                if (file.length() != length) {
+                    throw new IOException(DIGEST + " collision: " + file);
                 }
-            }
-
-            // Sanity checks on the record file. These should never fail,
-            // but better safe than sorry...
-            if (!file.isFile()) {
-                throw new IOException("Not a file: " + file);
-            }
-            if (file.length() != length) {
-                throw new IOException(DIGEST + " collision: " + file);
             }
 
             return new FileDataRecord(identifier, file);
@@ -266,17 +275,26 @@
     private int deleteOlderRecursive(File file, long min) {
         int count = 0;
         if (file.isFile() && file.exists() && file.canWrite()) {
-            if (file.lastModified() < min) {
-                DataIdentifier id = new DataIdentifier(file.getName());
-                if (!inUse.containsKey(id)) {
-                    file.delete();
-                    count++;
+            synchronized (this) {
+                if (file.lastModified() < min) {
+                    DataIdentifier id = new DataIdentifier(file.getName());
+                    if (!inUse.containsKey(id)) {
+                        file.delete();
+                        count++;
+                    }
                 }
             }
         } else if (file.isDirectory()) {
             File[] list = file.listFiles();
             for (int i = 0; i < list.length; i++) {
                 count += deleteOlderRecursive(list[i], min);
+            }
+            // JCR-1396: FileDataStore Garbage Collector and empty directories
+            // Automatic removal of empty directories (but not the root!)
+            synchronized (this) {
+                if (file != directory && file.list().length == 0) {
+                    file.delete();
+                }
             }
         }
         return count;

Modified: jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/GarbageCollector.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/GarbageCollector.java?rev=633844&r1=633843&r2=633844&view=diff
==============================================================================
--- jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/GarbageCollector.java (original)
+++ jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/GarbageCollector.java Wed Mar  5 05:45:30 2008
@@ -23,6 +23,7 @@
 import org.apache.jackrabbit.core.observation.SynchronousEventListener;
 import org.apache.jackrabbit.core.persistence.IterablePersistenceManager;
 import org.apache.jackrabbit.core.state.ItemStateException;
+import org.apache.jackrabbit.core.state.NoSuchItemStateException;
 import org.apache.jackrabbit.core.state.NodeState;
 import org.apache.jackrabbit.core.state.PropertyState;
 import org.apache.jackrabbit.core.value.InternalValue;
@@ -175,19 +176,24 @@
             Iterator it = pm.getAllNodeIds(null, 0);
             while (it.hasNext()) {
                 NodeId id = (NodeId) it.next();
-                NodeState state = pm.load(id);
-                Set propertyNames = state.getPropertyNames();
-                for (Iterator nameIt = propertyNames.iterator(); nameIt
-                        .hasNext();) {
-                    Name name = (Name) nameIt.next();
-                    PropertyId pid = new PropertyId(id, name);
-                    PropertyState ps = pm.load(pid);
-                    if (ps.getType() == PropertyType.BINARY) {
-                        InternalValue[] values = ps.getValues();
-                        for (int j = 0; j < values.length; j++) {
-                            values[j].getBLOBFileValue().getLength();
+                try {
+                    NodeState state = pm.load(id);
+                    Set propertyNames = state.getPropertyNames();
+                    for (Iterator nameIt = propertyNames.iterator(); nameIt
+                            .hasNext();) {
+                        Name name = (Name) nameIt.next();
+                        PropertyId pid = new PropertyId(id, name);
+                        PropertyState ps = pm.load(pid);
+                        if (ps.getType() == PropertyType.BINARY) {
+                            InternalValue[] values = ps.getValues();
+                            for (int j = 0; j < values.length; j++) {
+                                values[j].getBLOBFileValue().getLength();
+                            }
                         }
                     }
+                } catch (NoSuchItemStateException e) {
+                    // the node may have been deleted or moved in the meantime
+                    // ignore it
                 }
             }
         }

Modified: jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java?rev=633844&r1=633843&r2=633844&view=diff
==============================================================================
--- jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java (original)
+++ jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java Wed Mar  5 05:45:30 2008
@@ -40,7 +40,9 @@
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Iterator;
+import java.util.Map;
 import java.util.Properties;
 import java.util.WeakHashMap;
 
@@ -263,7 +265,7 @@
     /**
      * All data identifiers that are currently in use are in this set until they are garbage collected.
      */
-    protected WeakHashMap inUse = new WeakHashMap();    
+    protected Map inUse = Collections.synchronizedMap(new WeakHashMap());
 
     /**
      * {@inheritDoc}
@@ -384,7 +386,7 @@
     public synchronized int deleteAllOlderThan(long min) throws DataStoreException {
         ConnectionRecoveryManager conn = getConnection();
         try {
-            Iterator it = inUse.keySet().iterator();
+            Iterator it = new ArrayList(inUse.keySet()).iterator();
             while (it.hasNext()) {
                 DataIdentifier identifier = (DataIdentifier) it.next();
                 if (identifier != null) {
@@ -519,20 +521,18 @@
                 return;
             }
         }
-
         Properties prop = new Properties();
         try {
             try {
                 prop.load(in);
             } finally {
-                in.close();
+            in.close();
             }
         } catch (IOException e) {
             String msg = "Configuration error: Could not read properties '" + databaseType + ".properties'";
             log.debug(msg);
             throw new DataStoreException(msg);
         }
-
         if (driver == null) {
             driver = getProperty(prop, "driver", driver);
         }

Modified: jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java?rev=633844&r1=633843&r2=633844&view=diff
==============================================================================
--- jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java (original)
+++ jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java Wed Mar  5 05:45:30 2008
@@ -932,7 +932,7 @@
                 // see also bundleSelectAllIdsFrom SQL statement
                 maxCount += 10;
             }
-            Statement stmt = connectionManager.executeStmt(sql, keys, false, maxCount + 10);
+            Statement stmt = connectionManager.executeStmt(sql, keys, false, maxCount);
             rs = stmt.getResultSet();
             ArrayList result = new ArrayList();
             while ((maxCount == 0 || result.size() < maxCount) && rs.next()) {

Modified: jackrabbit/branches/1.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TestAll.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TestAll.java?rev=633844&r1=633843&r2=633844&view=diff
==============================================================================
--- jackrabbit/branches/1.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TestAll.java (original)
+++ jackrabbit/branches/1.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TestAll.java Wed Mar  5 05:45:30 2008
@@ -35,6 +35,7 @@
         suite.addTestSuite(NodeTypeTest.class);
         suite.addTestSuite(ExportImportTest.class);
         suite.addTestSuite(GarbageCollectorTest.class);
+        suite.addTestSuite(GCConcurrentTest.class);
         suite.addTestSuite(PersistenceManagerIteratorTest.class);
         suite.addTestSuite(CopyValueTest.class);
         return suite;