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;
}
/**