diff src/org/tmatesoft/hg/internal/FNCacheFile.java @ 664:ae2d439fbed3

Utilize transaction when writing fncache. Better HgIOException
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 10 Jul 2013 19:33:51 +0200
parents 46b56864b483
children fba85bc1dfb8
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/internal/FNCacheFile.java	Wed Jul 10 16:41:49 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/FNCacheFile.java	Wed Jul 10 19:33:51 2013 +0200
@@ -28,6 +28,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.tmatesoft.hg.core.HgIOException;
 import org.tmatesoft.hg.util.Path;
 
 /**
@@ -76,7 +77,7 @@
 	}
 	*/
 	
-	public void write() throws IOException { // FIXME transaction! and HgIOException
+	public void write(Transaction tr) throws HgIOException {
 		if (addedDotI.isEmpty() && addedDotD.isEmpty()) {
 			return;
 		}
@@ -97,14 +98,26 @@
 			cb.flip();
 			added.add(cb);
 		}
-		FileChannel fncacheFile = new FileOutputStream(f, true).getChannel();
-		ByteBuffer lf = ByteBuffer.wrap(new byte[] { 0x0A });
-		for (CharBuffer b : added) {
-			fncacheFile.write(filenameEncoding.encode(b));
-			fncacheFile.write(lf);
-			lf.rewind();
+		FileOutputStream fos = null;
+		f = tr.prepare(f);
+		try {
+			fos = new FileOutputStream(f, true);
+			FileChannel fncacheFile = fos.getChannel();
+			ByteBuffer lf = ByteBuffer.wrap(new byte[] { 0x0A });
+			for (CharBuffer b : added) {
+				fncacheFile.write(filenameEncoding.encode(b));
+				fncacheFile.write(lf);
+				lf.rewind();
+			}
+			fncacheFile.force(true);
+			tr.done(f);
+		} catch (IOException ex) {
+			tr.failure(f, ex);
+			throw new HgIOException("Failed to write fncache", ex, f);
+		} finally {
+			new FileUtils(repo.getLog(), this).closeQuietly(fos, f);
 		}
-		fncacheFile.close();
+		
 	}
 
 	public void addIndex(Path p) {
@@ -121,9 +134,11 @@
 	public static class Mediator {
 		private final Internals repo;
 		private FNCacheFile fncache;
+		private final Transaction tr;
 
-		public Mediator(Internals internalRepo) {
+		public Mediator(Internals internalRepo, Transaction transaction) {
 			repo = internalRepo;
+			tr = transaction;
 		}
 		
 		public void registerNew(Path f, RevlogStream rs) {
@@ -138,9 +153,9 @@
 			}
 		}
 		
-		public void complete() throws IOException {
+		public void complete() throws HgIOException {
 			if (fncache != null) {
-				fncache.write();
+				fncache.write(tr);
 			}
 		}
 	}