]> source.dussan.org Git - jgit.git/commitdiff
Use AtomicObjectOutputStream in CleanFilter 80/83980/1
authorMatthias Sohn <matthias.sohn@sap.com>
Wed, 26 Oct 2016 20:33:49 +0000 (22:33 +0200)
committerMatthias Sohn <matthias.sohn@sap.com>
Wed, 26 Oct 2016 21:19:49 +0000 (23:19 +0200)
Enhance and use AtomicObjectOutputStream to write temporary files in
CleanFilter.

Change-Id: I28987dad18255a9067344f94b4e836cbd183e4b1
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/CleanFilter.java
org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/AtomicObjectOutputStream.java

index fa5c74ccd9b9e9c57f6c0009bb11aff1bcbfe822..66feca751867496635c17892eb961424924d5f80 100644 (file)
@@ -48,15 +48,13 @@ import java.io.OutputStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.StandardCopyOption;
-import java.nio.file.StandardOpenOption;
-import java.security.DigestOutputStream;
 
 import org.eclipse.jgit.attributes.FilterCommand;
 import org.eclipse.jgit.attributes.FilterCommandFactory;
 import org.eclipse.jgit.attributes.FilterCommandRegistry;
 import org.eclipse.jgit.lfs.errors.CorruptMediaFile;
-import org.eclipse.jgit.lfs.lib.Constants;
-import org.eclipse.jgit.lfs.lib.LongObjectId;
+import org.eclipse.jgit.lfs.internal.AtomicObjectOutputStream;
+import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.util.FileUtils;
 
@@ -98,12 +96,8 @@ public class CleanFilter extends FilterCommand {
                                FACTORY);
        }
 
-       // The OutputStream to a temporary file which will be renamed to mediafile
-       // when the operation succeeds
-       private OutputStream tmpOut;
-
        // Used to compute the hash for the original content
-       private DigestOutputStream dOut;
+       private AtomicObjectOutputStream aOut;
 
        private Lfs lfsUtil;
 
@@ -133,11 +127,7 @@ public class CleanFilter extends FilterCommand {
                lfsUtil = new Lfs(db.getDirectory().toPath().resolve("lfs")); //$NON-NLS-1$
                Files.createDirectories(lfsUtil.getLfsTmpDir());
                tmpFile = lfsUtil.createTmpFile();
-               tmpOut = Files.newOutputStream(tmpFile,
-                               StandardOpenOption.CREATE);
-               this.dOut = new DigestOutputStream(
-                               tmpOut,
-                               Constants.newMessageDigest());
+               this.aOut = new AtomicObjectOutputStream(tmpFile.toAbsolutePath());
        }
 
        public int run() throws IOException {
@@ -145,14 +135,13 @@ public class CleanFilter extends FilterCommand {
                        byte[] buf = new byte[8192];
                        int length = in.read(buf);
                        if (length != -1) {
-                               dOut.write(buf, 0, length);
+                               aOut.write(buf, 0, length);
                                size += length;
                                return length;
                        } else {
-                               dOut.close();
-                               tmpOut.close();
-                               LongObjectId loid = LongObjectId
-                                               .fromRaw(dOut.getMessageDigest().digest());
+                               aOut.close();
+                               AnyLongObjectId loid = aOut.getId();
+                               aOut = null;
                                Path mediaFile = lfsUtil.getMediaFile(loid);
                                if (Files.isRegularFile(mediaFile)) {
                                        long fsSize = Files.size(mediaFile);
@@ -172,9 +161,10 @@ public class CleanFilter extends FilterCommand {
                                return -1;
                        }
                } catch (IOException e) {
+                       if (aOut != null) {
+                               aOut.abort();
+                       }
                        out.close();
-                       dOut.close();
-                       tmpOut.close();
                        throw e;
                }
        }
index 7e050b1e788f2a6aa3d66a821ae1da885af2e9e3..867cca50560354a11d920c8797796c89280a9694 100644 (file)
@@ -48,6 +48,7 @@ import java.nio.file.Path;
 import java.security.DigestOutputStream;
 import java.text.MessageFormat;
 
+import org.eclipse.jgit.annotations.Nullable;
 import org.eclipse.jgit.internal.storage.file.LockFile;
 import org.eclipse.jgit.lfs.errors.CorruptLongObjectException;
 import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
@@ -83,6 +84,22 @@ public class AtomicObjectOutputStream extends OutputStream {
                                Constants.newMessageDigest());
        }
 
+       /**
+        * @param path
+        * @throws IOException
+        */
+       public AtomicObjectOutputStream(Path path) throws IOException {
+               this(path, null);
+       }
+
+       /**
+        * @return content hash of the object which was streamed through this
+        *         stream. May return {@code null} if called before closing this stream.
+        */
+       public @Nullable AnyLongObjectId getId() {
+               return id;
+       }
+
        @Override
        public void write(int b) throws IOException {
                out.write(b);
@@ -102,7 +119,11 @@ public class AtomicObjectOutputStream extends OutputStream {
        public void close() throws IOException {
                out.close();
                if (!aborted) {
-                       verifyHash();
+                       if (id != null) {
+                               verifyHash();
+                       } else {
+                               id = LongObjectId.fromRaw(out.getMessageDigest().digest());
+                       }
                        locked.commit();
                }
        }