Mercurial > jhg
comparison src/org/tmatesoft/hg/internal/DataAccessProvider.java @ 617:65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Wed, 15 May 2013 20:10:09 +0200 |
parents | e1b29756f901 |
children | 7c0d2ce340b8 |
comparison
equal
deleted
inserted
replaced
616:5e0313485eef | 617:65c01508f002 |
---|---|
27 import java.io.OutputStream; | 27 import java.io.OutputStream; |
28 import java.nio.ByteBuffer; | 28 import java.nio.ByteBuffer; |
29 import java.nio.MappedByteBuffer; | 29 import java.nio.MappedByteBuffer; |
30 import java.nio.channels.FileChannel; | 30 import java.nio.channels.FileChannel; |
31 | 31 |
32 import org.tmatesoft.hg.core.HgIOException; | |
32 import org.tmatesoft.hg.core.SessionContext; | 33 import org.tmatesoft.hg.core.SessionContext; |
33 import org.tmatesoft.hg.util.LogFacility; | 34 import org.tmatesoft.hg.util.LogFacility; |
34 | 35 |
35 /** | 36 /** |
36 * | 37 * |
78 public DataAccess createReader(File f, boolean shortRead) { | 79 public DataAccess createReader(File f, boolean shortRead) { |
79 if (!f.exists()) { | 80 if (!f.exists()) { |
80 return new DataAccess(); | 81 return new DataAccess(); |
81 } | 82 } |
82 try { | 83 try { |
83 FileChannel fc = new FileInputStream(f).getChannel(); | 84 FileChannel fc = new FileInputStream(f).getChannel(); // FIXME SHALL CLOSE FIS, not only channel |
84 long flen = fc.size(); | 85 long flen = fc.size(); |
85 if (!shortRead && flen > mapioMagicBoundary) { | 86 if (!shortRead && flen > mapioMagicBoundary) { |
86 // TESTS: bufLen of 1024 was used to test MemMapFileAccess | 87 // TESTS: bufLen of 1024 was used to test MemMapFileAccess |
87 return new MemoryMapFileAccess(fc, flen, mapioBufSize, context.getLog()); | 88 return new MemoryMapFileAccess(fc, flen, mapioBufSize, context.getLog()); |
88 } else { | 89 } else { |
98 context.getLog().dump(getClass(), Error, ex, null); | 99 context.getLog().dump(getClass(), Error, ex, null); |
99 } | 100 } |
100 return new DataAccess(); // non-null, empty. | 101 return new DataAccess(); // non-null, empty. |
101 } | 102 } |
102 | 103 |
103 public DataSerializer createWriter(File f, boolean createNewIfDoesntExist) { | 104 public DataSerializer createWriter(final Transaction tr, File f, boolean createNewIfDoesntExist) throws HgIOException { |
104 if (!f.exists() && !createNewIfDoesntExist) { | 105 if (!f.exists() && !createNewIfDoesntExist) { |
105 return new DataSerializer(); | 106 return new DataSerializer(); |
106 } | 107 } |
107 try { | 108 try { |
108 return new StreamDataSerializer(context.getLog(), new FileOutputStream(f, true)); | 109 final File transactionFile = tr.prepare(f); |
110 return new StreamDataSerializer(context.getLog(), new FileOutputStream(transactionFile, true)) { | |
111 @Override | |
112 public void done() { | |
113 super.done(); | |
114 // FIXME invert RevlogStreamWriter to send DataSource here instead of grabbing DataSerializer | |
115 // besides, DataSerializer#done is invoked regardless of whether write was successful or not, | |
116 // while Transaction#done() assumes there's no error | |
117 try { | |
118 tr.done(transactionFile); | |
119 } catch (HgIOException ex) { | |
120 context.getLog().dump(DataAccessProvider.class, Error, ex, null); | |
121 } | |
122 } | |
123 }; | |
109 } catch (final FileNotFoundException ex) { | 124 } catch (final FileNotFoundException ex) { |
110 context.getLog().dump(getClass(), Error, ex, null); | 125 context.getLog().dump(getClass(), Error, ex, null); |
111 return new DataSerializer() { | 126 return new DataSerializer() { |
112 public void write(byte[] data, int offset, int length) throws IOException { | 127 public void write(byte[] data, int offset, int length) throws IOException { |
113 throw ex; | 128 throw ex; |