You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ace.apache.org by br...@apache.org on 2013/05/01 19:08:00 UTC
svn commit: r1478099 -
/ace/trunk/org.apache.ace.obr/src/org/apache/ace/obr/storage/file/BundleFileStore.java
Author: bramk
Date: Wed May 1 17:08:00 2013
New Revision: 1478099
URL: http://svn.apache.org/r1478099
Log:
ACE-346 Switched dir check from lastmodified to checksum
Last-modified is not good enough as some filesystems (eg ext3) round it to a seconds..
Modified:
ace/trunk/org.apache.ace.obr/src/org/apache/ace/obr/storage/file/BundleFileStore.java
Modified: ace/trunk/org.apache.ace.obr/src/org/apache/ace/obr/storage/file/BundleFileStore.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.obr/src/org/apache/ace/obr/storage/file/BundleFileStore.java?rev=1478099&r1=1478098&r2=1478099&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.obr/src/org/apache/ace/obr/storage/file/BundleFileStore.java (original)
+++ ace/trunk/org.apache.ace.obr/src/org/apache/ace/obr/storage/file/BundleFileStore.java Wed May 1 17:08:00 2013
@@ -25,7 +25,10 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.math.BigInteger;
import java.nio.channels.FileChannel;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.util.Dictionary;
import java.util.Stack;
import java.util.jar.Attributes;
@@ -58,7 +61,7 @@ public class BundleFileStore implements
private volatile MetadataGenerator m_metadata;
private volatile LogService m_log;
- private volatile long m_dirLastModified;
+ private volatile String m_dirChecksum;
private volatile File m_dir;
/**
@@ -69,10 +72,9 @@ public class BundleFileStore implements
public void synchronizeMetadata() throws IOException {
File dir = m_dir;
synchronized (REPOSITORY_XML) {
- long dirLastmodified = getDirLastModified(dir);
- if (dirLastmodified > m_dirLastModified) {
+ if (m_dirChecksum == null || !m_dirChecksum.equals(getDirChecksum(dir))) {
m_metadata.generateMetadata(dir);
- m_dirLastModified = getDirLastModified(dir);
+ m_dirChecksum = getDirChecksum(dir);
}
}
}
@@ -155,13 +157,9 @@ public class BundleFileStore implements
}
m_dir = newDir;
- m_dirLastModified = 0l;
+ m_dirChecksum = "";
}
}
- else {
- // clean up after getting a null as dictionary, as the service is going to be pulled afterwards
- m_dirLastModified = 0l;
- }
}
/**
@@ -176,35 +174,46 @@ public class BundleFileStore implements
}
}
+
/**
- * Returns the highest last-modified for the directory by recursively looking at all directories and files.
+ * Computes a magic checksum used to determine whether there where changes in the directory without actually looking
+ * into the files or using observation.
*
* @param dir
* The directory
- * @return the Last-modified
+ * @return The checksum
*/
- private long getDirLastModified(File dir) {
- long highest = 0l;
+ private String getDirChecksum(File dir) {
+ long start = System.nanoTime();
+
+ MessageDigest digest = null;
+ try {
+ digest = MessageDigest.getInstance("MD5");
+ }
+ catch (NoSuchAlgorithmException e) {
+ // really should not happen
+ m_log.log(LogService.LOG_WARNING, "Unable to get an MD5 digest. Metadata will refresh every ten minutes.", e);
+ return "" + (System.currentTimeMillis() / 600000);
+ }
+
Stack<File> dirs = new Stack<File>();
dirs.push(dir);
while (!dirs.isEmpty()) {
File pwd = dirs.pop();
- long modified = pwd.lastModified();
- if (modified > highest) {
- highest = modified;
- }
for (File file : pwd.listFiles()) {
if (file.isDirectory()) {
dirs.push(file);
continue;
}
- modified = file.lastModified();
- if (modified > highest) {
- highest = modified;
- }
+ // basically we hash the filenames, but...
+ // include last-modified to detect touched files
+ // include length to work around last-modified rounding issues
+ String magic = file.getName() + file.length() + file.lastModified();
+ digest.update(magic.getBytes());
}
}
- return highest;
+ String checksum = new BigInteger(digest.digest()).toString();
+ return checksum;
}
/**