summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Musum <musum@yahooinc.com>2022-11-15 19:32:18 +0100
committerHarald Musum <musum@yahooinc.com>2022-11-15 19:32:18 +0100
commita3d5726785108b5a670f0f40b315bd2e3b70f138 (patch)
tree0b698d78fc02f3866d61b81e6ec7ec268f98bf49
parent9a35cc0b67c8d9e5abe0b5b66ed7fc0a67498c07 (diff)
No need to add file if it already exists
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileDirectory.java18
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/filedistribution/FileDirectoryTest.java32
2 files changed, 44 insertions, 6 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileDirectory.java b/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileDirectory.java
index 521f34b700f..5c8d693eeb7 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileDirectory.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileDirectory.java
@@ -98,17 +98,19 @@ public class FileDirectory {
public FileReference addFile(File source) throws IOException {
Long hash = computeHash(source);
- verifyExistingFile(source, hash);
FileReference fileReference = fileReferenceFromHash(hash);
- return addFile(source, fileReference);
+
+ if (shouldAddFile(source, hash))
+ return addFile(source, fileReference);
+
+ return fileReference;
}
- // If there exists a directory for a file reference, but content does not have correct hash or the file we want to add
- // does not exist in the directory, delete the directory
- private void verifyExistingFile(File source, Long hashOfFileToBeAdded) throws IOException {
+ // Check if we should add file, it might already exist
+ private boolean shouldAddFile(File source, Long hashOfFileToBeAdded) throws IOException {
FileReference fileReference = fileReferenceFromHash(hashOfFileToBeAdded);
File destinationDir = destinationDir(fileReference);
- if (!destinationDir.exists()) return;
+ if ( ! destinationDir.exists()) return true;
File existingFile = destinationDir.toPath().resolve(source.getName()).toFile();
if ( ! existingFile.exists() || ! computeHash(existingFile).equals(hashOfFileToBeAdded)) {
@@ -116,7 +118,11 @@ public class FileDirectory {
"' has content that does not match its hash, deleting everything in " +
destinationDir.getAbsolutePath());
IOUtils.recursiveDeleteDir(destinationDir);
+ return true;
}
+
+ log.log(Level.FINE, "Directory for file reference '" + fileReference.value() + "' already exists and has all content");
+ return false;
}
private File destinationDir(FileReference fileReference) {
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/filedistribution/FileDirectoryTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/filedistribution/FileDirectoryTest.java
index dd13a8f5f58..e5ef893d135 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/filedistribution/FileDirectoryTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/filedistribution/FileDirectoryTest.java
@@ -106,6 +106,38 @@ public class FileDirectoryTest {
assertEquals("bebc5a1aee74223d", fileReference.value());
}
+ @Test
+ public void requireThatNothingIsDoneIfFileReferenceExists() throws IOException {
+ FileDirectory fileDirectory = new FileDirectory(temporaryFolder.getRoot());
+
+ String subdirName = "subdir";
+ File subDirectory = new File(temporaryFolder.getRoot(), subdirName);
+ createFileInSubDir(subDirectory, "foo", "some content");
+ FileReference fileReference = fileDirectory.addFile(subDirectory);
+ File dir = fileDirectory.getFile(fileReference);
+ assertTrue(dir.exists());
+ File foo = new File(dir, "foo");
+ assertTrue(foo.exists());
+ FileTime fooCreatedTimestamp = Files.readAttributes(foo.toPath(), BasicFileAttributes.class).creationTime();
+ assertFalse(new File(dir, "doesnotexist").exists());
+ assertEquals("bebc5a1aee74223d", fileReference.value());
+
+ try { Thread.sleep(1000);} catch (InterruptedException e) { /*ignore */ } // Needed since we have timestamp resolution of 1 second
+ // Add a file that already exists, nothing should happen
+ createFileInSubDir(subDirectory, "foo", "some content"); // same as before, nothing should happen
+ FileReference fileReference3 = fileDirectory.addFile(subDirectory);
+ dir = fileDirectory.getFile(fileReference3);
+ assertTrue(new File(dir, "foo").exists());
+ assertEquals("bebc5a1aee74223d", fileReference3.value()); // same hash
+
+ File foo2 = new File(dir, "foo");
+ assertTrue(dir.exists());
+ assertTrue(foo2.exists());
+ FileTime barCreatedTimestamp = Files.readAttributes(foo2.toPath(), BasicFileAttributes.class).creationTime();
+ // Check that creation timestamp is newer than the old one to be sure that a new file was written
+ assertEquals(barCreatedTimestamp, fooCreatedTimestamp);
+ }
+
// Content in created file is equal to the filename string
private FileReference createFile(String filename) throws IOException {
File file = temporaryFolder.newFile(filename);