From commits-return-5423-apmail-jackrabbit-commits-archive=jackrabbit.apache.org@jackrabbit.apache.org Wed Mar 05 13:45:55 2008 Return-Path: Delivered-To: apmail-jackrabbit-commits-archive@www.apache.org Received: (qmail 84003 invoked from network); 5 Mar 2008 13:45:55 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 5 Mar 2008 13:45:55 -0000 Received: (qmail 79740 invoked by uid 500); 5 Mar 2008 13:45:51 -0000 Delivered-To: apmail-jackrabbit-commits-archive@jackrabbit.apache.org Received: (qmail 79711 invoked by uid 500); 5 Mar 2008 13:45:51 -0000 Mailing-List: contact commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@jackrabbit.apache.org Delivered-To: mailing list commits@jackrabbit.apache.org Received: (qmail 79702 invoked by uid 99); 5 Mar 2008 13:45:51 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 05 Mar 2008 05:45:51 -0800 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 05 Mar 2008 13:45:24 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 88E9B1A9832; Wed, 5 Mar 2008 05:45:34 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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... Date: Wed, 05 Mar 2008 13:45:32 -0000 To: commits@jackrabbit.apache.org From: jukka@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080305134534.88E9B1A9832@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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;