comparison src/org/tmatesoft/hg/internal/RevlogStreamWriter.java @ 663:46b56864b483

Pull: phase2 - update phases from remote, fncache with added files. Tests
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 10 Jul 2013 16:41:49 +0200
parents 4fd317a2fecf
children ae2d439fbed3
comparison
equal deleted inserted replaced
662:af5223b86dd3 663:46b56864b483
15 * contact TMate Software at support@hg4j.com 15 * contact TMate Software at support@hg4j.com
16 */ 16 */
17 package org.tmatesoft.hg.internal; 17 package org.tmatesoft.hg.internal;
18 18
19 import static org.tmatesoft.hg.internal.Internals.REVLOGV1_RECORD_SIZE; 19 import static org.tmatesoft.hg.internal.Internals.REVLOGV1_RECORD_SIZE;
20 import static org.tmatesoft.hg.repo.HgRepository.BAD_REVISION;
20 import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION; 21 import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION;
21 22
23 import java.io.File;
22 import java.io.IOException; 24 import java.io.IOException;
23 import java.nio.ByteBuffer; 25 import java.nio.ByteBuffer;
24 26
25 import org.tmatesoft.hg.core.HgIOException; 27 import org.tmatesoft.hg.core.HgIOException;
26 import org.tmatesoft.hg.core.Nodeid; 28 import org.tmatesoft.hg.core.Nodeid;
46 public class RevlogStreamWriter { 48 public class RevlogStreamWriter {
47 49
48 private final DigestHelper dh = new DigestHelper(); 50 private final DigestHelper dh = new DigestHelper();
49 private final RevlogCompressor revlogDataZip; 51 private final RevlogCompressor revlogDataZip;
50 private final Transaction transaction; 52 private final Transaction transaction;
51 private int lastEntryBase, lastEntryIndex, lastEntryActualLen; 53 // init with illegal values
54 private int lastEntryBase = BAD_REVISION, lastEntryIndex = BAD_REVISION, lastEntryActualLen = -1;
52 // record revision and its full content 55 // record revision and its full content
53 // the name might be misleading, it does not necessarily match lastEntryIndex 56 // the name might be misleading, it does not necessarily match lastEntryIndex
54 private Pair<Integer, byte[]> lastFullContent; 57 private Pair<Integer, byte[]> lastFullContent;
55 private Nodeid lastEntryRevision; 58 private Nodeid lastEntryRevision;
56 private IntMap<Nodeid> revisionCache = new IntMap<Nodeid>(32); 59 private IntMap<Nodeid> revisionCache = new IntMap<Nodeid>(32);
62 assert tr != null; 65 assert tr != null;
63 66
64 revlogDataZip = new RevlogCompressor(ctxSource.getSessionContext()); 67 revlogDataZip = new RevlogCompressor(ctxSource.getSessionContext());
65 revlogStream = stream; 68 revlogStream = stream;
66 transaction = tr; 69 transaction = tr;
70 }
71
72 public RevlogStream getRevlogStream() {
73 return revlogStream;
67 } 74 }
68 75
69 public Pair<Integer,Nodeid> addPatchRevision(GroupElement ge, RevisionToIndexMap clogRevs, RevisionToIndexMap revlogRevs) throws HgIOException, HgRuntimeException { 76 public Pair<Integer,Nodeid> addPatchRevision(GroupElement ge, RevisionToIndexMap clogRevs, RevisionToIndexMap revlogRevs) throws HgIOException, HgRuntimeException {
70 populateLastEntryIndex(); 77 populateLastEntryIndex();
71 // 78 //
108 try { 115 try {
109 if (lastEntryIndex == NO_REVISION) { 116 if (lastEntryIndex == NO_REVISION) {
110 complete = p.apply(new ByteArrayDataAccess(new byte[0]), -1); 117 complete = p.apply(new ByteArrayDataAccess(new byte[0]), -1);
111 baseRev = 0; // it's done above, but doesn't hurt 118 baseRev = 0; // it's done above, but doesn't hurt
112 } else { 119 } else {
113 ReadContentInspector insp = new ReadContentInspector().read(revlogStream, baseRev); 120 assert patchBaseRev != NO_REVISION;
121 ReadContentInspector insp = new ReadContentInspector().read(revlogStream, patchBaseRev);
114 complete = p.apply(new ByteArrayDataAccess(insp.content), -1); 122 complete = p.apply(new ByteArrayDataAccess(insp.content), -1);
115 baseRev = lastEntryIndex + 1; 123 baseRev = lastEntryIndex + 1;
116 } 124 }
117 ds = new ByteArrayDataSource(complete); 125 ds = new ByteArrayDataSource(complete);
118 revLen = complete.length; 126 revLen = complete.length;
119 } catch (IOException ex) { 127 } catch (IOException ex) {
120 // unlikely to happen, as ByteArrayDataSource doesn't throw IOException 128 // unlikely to happen, as ByteArrayDataSource throws IOException only in case of programming errors
121 throw new HgIOException("Failed to reconstruct revision", ex, null); 129 // FIXME next approach to get indexFile is awful:
130 File indexFile = revlogStream.initWithIndexFile(new HgInvalidControlFileException("", ex, null)).getFile();
131 throw new HgIOException("Failed to reconstruct revision", ex, indexFile);
122 } 132 }
123 } 133 }
124 doAdd(nodeRev, p1, p2, linkRev, baseRev, revLen, ds); 134 doAdd(nodeRev, p1, p2, linkRev, baseRev, revLen, ds);
125 if (complete != null) { 135 if (complete != null) {
126 lastFullContent = new Pair<Integer, byte[]>(lastEntryIndex, complete); 136 lastFullContent = new Pair<Integer, byte[]>(lastEntryIndex, complete);
234 return n; 244 return n;
235 } 245 }
236 246
237 private int dataLength(int revisionIndex) throws HgInvalidControlFileException, HgInvalidRevisionException { 247 private int dataLength(int revisionIndex) throws HgInvalidControlFileException, HgInvalidRevisionException {
238 assert revisionIndex >= 0; 248 assert revisionIndex >= 0;
239 if (revisionIndex == lastEntryIndex) { 249 if (revisionIndex == lastEntryIndex && lastEntryActualLen >= 0) {
250 // if the last entry is the one we've just written, we know its actual len.
251 // it's possible, however, that revisionIndex == lastEntryIndex just
252 // because revision being added comes right after last locally known one
253 // and lastEntryActualLen is not set
240 return lastEntryActualLen; 254 return lastEntryActualLen;
241 } 255 }
242 if (lastFullContent != null && lastFullContent.first() == revisionIndex) { 256 if (lastFullContent != null && lastFullContent.first() == revisionIndex) {
243 return lastFullContent.second().length; 257 return lastFullContent.second().length;
244 } 258 }