diff options
author | Harald Musum <musum@yahooinc.com> | 2022-11-15 19:32:18 +0100 |
---|---|---|
committer | Harald Musum <musum@yahooinc.com> | 2022-11-15 19:32:18 +0100 |
commit | a3d5726785108b5a670f0f40b315bd2e3b70f138 (patch) | |
tree | 0b698d78fc02f3866d61b81e6ec7ec268f98bf49 | |
parent | 9a35cc0b67c8d9e5abe0b5b66ed7fc0a67498c07 (diff) |
No need to add file if it already exists
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); |