comparison 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
comparison
equal deleted inserted replaced
663:46b56864b483 664:ae2d439fbed3
26 import java.nio.channels.FileChannel; 26 import java.nio.channels.FileChannel;
27 import java.nio.charset.Charset; 27 import java.nio.charset.Charset;
28 import java.util.ArrayList; 28 import java.util.ArrayList;
29 import java.util.List; 29 import java.util.List;
30 30
31 import org.tmatesoft.hg.core.HgIOException;
31 import org.tmatesoft.hg.util.Path; 32 import org.tmatesoft.hg.util.Path;
32 33
33 /** 34 /**
34 * Append-only fncache support 35 * Append-only fncache support
35 * 36 *
74 files.add(pathFactory.path(e)); 75 files.add(pathFactory.path(e));
75 } 76 }
76 } 77 }
77 */ 78 */
78 79
79 public void write() throws IOException { // FIXME transaction! and HgIOException 80 public void write(Transaction tr) throws HgIOException {
80 if (addedDotI.isEmpty() && addedDotD.isEmpty()) { 81 if (addedDotI.isEmpty() && addedDotD.isEmpty()) {
81 return; 82 return;
82 } 83 }
83 File f = repo.getRepositoryFile(FNCache); 84 File f = repo.getRepositoryFile(FNCache);
84 f.getParentFile().mkdirs(); 85 f.getParentFile().mkdirs();
95 cb.append(cs); 96 cb.append(cs);
96 cb.put(cs.length()-1, 'd'); 97 cb.put(cs.length()-1, 'd');
97 cb.flip(); 98 cb.flip();
98 added.add(cb); 99 added.add(cb);
99 } 100 }
100 FileChannel fncacheFile = new FileOutputStream(f, true).getChannel(); 101 FileOutputStream fos = null;
101 ByteBuffer lf = ByteBuffer.wrap(new byte[] { 0x0A }); 102 f = tr.prepare(f);
102 for (CharBuffer b : added) { 103 try {
103 fncacheFile.write(filenameEncoding.encode(b)); 104 fos = new FileOutputStream(f, true);
104 fncacheFile.write(lf); 105 FileChannel fncacheFile = fos.getChannel();
105 lf.rewind(); 106 ByteBuffer lf = ByteBuffer.wrap(new byte[] { 0x0A });
107 for (CharBuffer b : added) {
108 fncacheFile.write(filenameEncoding.encode(b));
109 fncacheFile.write(lf);
110 lf.rewind();
111 }
112 fncacheFile.force(true);
113 tr.done(f);
114 } catch (IOException ex) {
115 tr.failure(f, ex);
116 throw new HgIOException("Failed to write fncache", ex, f);
117 } finally {
118 new FileUtils(repo.getLog(), this).closeQuietly(fos, f);
106 } 119 }
107 fncacheFile.close(); 120
108 } 121 }
109 122
110 public void addIndex(Path p) { 123 public void addIndex(Path p) {
111 addedDotI.add(p); 124 addedDotI.add(p);
112 } 125 }
119 * Register new files with fncache if one is enabled for the repo, do nothing otherwise 132 * Register new files with fncache if one is enabled for the repo, do nothing otherwise
120 */ 133 */
121 public static class Mediator { 134 public static class Mediator {
122 private final Internals repo; 135 private final Internals repo;
123 private FNCacheFile fncache; 136 private FNCacheFile fncache;
137 private final Transaction tr;
124 138
125 public Mediator(Internals internalRepo) { 139 public Mediator(Internals internalRepo, Transaction transaction) {
126 repo = internalRepo; 140 repo = internalRepo;
141 tr = transaction;
127 } 142 }
128 143
129 public void registerNew(Path f, RevlogStream rs) { 144 public void registerNew(Path f, RevlogStream rs) {
130 if (fncache != null || repo.fncacheInUse()) { 145 if (fncache != null || repo.fncacheInUse()) {
131 if (fncache == null) { 146 if (fncache == null) {
136 fncache.addData(f); 151 fncache.addData(f);
137 } 152 }
138 } 153 }
139 } 154 }
140 155
141 public void complete() throws IOException { 156 public void complete() throws HgIOException {
142 if (fncache != null) { 157 if (fncache != null) {
143 fncache.write(); 158 fncache.write(tr);
144 } 159 }
145 } 160 }
146 } 161 }
147 } 162 }