Mercurial > hg4j
annotate src/org/tmatesoft/hg/internal/RevlogStream.java @ 704:7743a9c10bfa
Merge command introduced
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> | 
|---|---|
| date | Wed, 14 Aug 2013 20:07:26 +0200 | 
| parents | ae2d439fbed3 | 
| children | 
| rev | line source | 
|---|---|
| 10 
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
9diff
changeset | 1 /* | 
| 530 
0f6fa88e2162
Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
520diff
changeset | 2 * Copyright (c) 2010-2013 TMate Software Ltd | 
| 74 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
52diff
changeset | 3 * | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
52diff
changeset | 4 * This program is free software; you can redistribute it and/or modify | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
52diff
changeset | 5 * it under the terms of the GNU General Public License as published by | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
52diff
changeset | 6 * the Free Software Foundation; version 2 of the License. | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
52diff
changeset | 7 * | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
52diff
changeset | 8 * This program is distributed in the hope that it will be useful, | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
52diff
changeset | 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
52diff
changeset | 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
52diff
changeset | 11 * GNU General Public License for more details. | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
52diff
changeset | 12 * | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
52diff
changeset | 13 * For information on how to redistribute this software under | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
52diff
changeset | 14 * the terms of a license other than GNU General Public License | 
| 102 
a3a2e5deb320
Updated contact address to support@hg4j.com
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
88diff
changeset | 15 * contact TMate Software at support@hg4j.com | 
| 0 
dbd663faec1f
Basic changelog parsing
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 16 */ | 
| 77 
c677e1593919
Moved RevlogStream implementation into .internal
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
74diff
changeset | 17 package org.tmatesoft.hg.internal; | 
| 0 
dbd663faec1f
Basic changelog parsing
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 18 | 
| 80 
4222b04f34ee
Follow history of a file
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 19 import static org.tmatesoft.hg.repo.HgRepository.BAD_REVISION; | 
| 644 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 20 import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION; | 
| 74 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
52diff
changeset | 21 import static org.tmatesoft.hg.repo.HgRepository.TIP; | 
| 530 
0f6fa88e2162
Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
520diff
changeset | 22 import static org.tmatesoft.hg.internal.Internals.REVLOGV1_RECORD_SIZE; | 
| 5 
fc265ddeab26
File content and non-effective, although working, patch application
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
4diff
changeset | 23 | 
| 3 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 24 import java.io.File; | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 25 import java.io.IOException; | 
| 593 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 26 import java.lang.ref.Reference; | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 27 import java.lang.ref.ReferenceQueue; | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 28 import java.lang.ref.SoftReference; | 
| 655 
bcbcc318f250
Performance: reuse unzip output buffer
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
644diff
changeset | 29 import java.nio.ByteBuffer; | 
| 607 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 30 import java.util.ArrayList; | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 31 import java.util.List; | 
| 263 
31f67be94e71
RevlogStream - reduce number of object instances, reuse when possible
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
258diff
changeset | 32 import java.util.zip.Inflater; | 
| 0 
dbd663faec1f
Basic changelog parsing
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 33 | 
| 617 
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
608diff
changeset | 34 import org.tmatesoft.hg.core.HgIOException; | 
| 74 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
52diff
changeset | 35 import org.tmatesoft.hg.core.Nodeid; | 
| 300 
650b45d290b1
Share range check code
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
297diff
changeset | 36 import org.tmatesoft.hg.repo.HgInternals; | 
| 423 
9c9c442b5f2e
Major refactoring of exception handling. Low-level API uses RuntimeExceptions, while checked are left for higher level
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
420diff
changeset | 37 import org.tmatesoft.hg.repo.HgInvalidControlFileException; | 
| 
9c9c442b5f2e
Major refactoring of exception handling. Low-level API uses RuntimeExceptions, while checked are left for higher level
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
420diff
changeset | 38 import org.tmatesoft.hg.repo.HgInvalidRevisionException; | 
| 
9c9c442b5f2e
Major refactoring of exception handling. Low-level API uses RuntimeExceptions, while checked are left for higher level
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
420diff
changeset | 39 import org.tmatesoft.hg.repo.HgInvalidStateException; | 
| 80 
4222b04f34ee
Follow history of a file
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 40 import org.tmatesoft.hg.repo.HgRepository; | 
| 628 
6526d8adbc0f
Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
621diff
changeset | 41 import org.tmatesoft.hg.repo.HgRuntimeException; | 
| 520 
1ee452f31187
Experimental support for inverse direction history walking. Refactored/streamlined cancellation in HgLogCommand and down the stack
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
440diff
changeset | 42 import org.tmatesoft.hg.util.Adaptable; | 
| 74 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
52diff
changeset | 43 | 
| 10 
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
9diff
changeset | 44 | 
| 0 
dbd663faec1f
Basic changelog parsing
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 45 /** | 
| 
dbd663faec1f
Basic changelog parsing
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 46 * ? Single RevlogStream per file per repository with accessor to record access session (e.g. with back/forward operations), | 
| 198 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 47 * or numerous RevlogStream with separate representation of the underlying data (cached, lazy ChunkStream)? | 
| 74 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
52diff
changeset | 48 * | 
| 0 
dbd663faec1f
Basic changelog parsing
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 49 * @see http://mercurial.selenic.com/wiki/Revlog | 
| 
dbd663faec1f
Basic changelog parsing
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 50 * @see http://mercurial.selenic.com/wiki/RevlogNG | 
| 74 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
52diff
changeset | 51 * | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
52diff
changeset | 52 * @author Artem Tikhomirov | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
52diff
changeset | 53 * @author TMate Software Ltd. | 
| 0 
dbd663faec1f
Basic changelog parsing
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 54 */ | 
| 
dbd663faec1f
Basic changelog parsing
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 55 public class RevlogStream { | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 56 | 
| 608 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 57 static final int INLINEDATA = 1 << 16; | 
| 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 58 | 
| 198 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 59 /* | 
| 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 60 * makes sense for index with inline data only - actual offset of the record in the .i file (record entry + revision * record size)) | 
| 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 61 * | 
| 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 62 * long[] in fact (there are 8-bytes field in the revlog) | 
| 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 63 * However, (a) DataAccess currently doesn't operate with long seek/length | 
| 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 64 * and, of greater significance, (b) files with inlined data are designated for smaller files, | 
| 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 65 * guess, about 130 Kb, and offset there won't ever break int capacity | 
| 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 66 */ | 
| 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 67 private int[] indexRecordOffset; | 
| 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 68 private int[] baseRevisions; | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 69 private boolean inline = false; | 
| 3 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 70 private final File indexFile; | 
| 396 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 71 private File dataFile; | 
| 608 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 72 private final Internals repo; | 
| 593 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 73 // keeps last complete revision we've read. Note, this cached revision doesn't help | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 74 // for subsequent #iterate() calls with the same revision (Inspector needs more data than | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 75 // we currently cache here, perhaps, we shall cache everything it wants to cover same | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 76 // revision case as well). Now this helps when second #iterate() call is for a revision greater | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 77 // than one from the first call, and both revisions got same base rev. It's often the case when | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 78 // parents/children are analyzed. | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 79 private SoftReference<CachedRevision> lastRevisionRead; | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 80 private final ReferenceQueue<CachedRevision> lastRevisionQueue = new ReferenceQueue<CachedRevision>(); | 
| 607 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 81 // | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 82 private final RevlogChangeMonitor changeTracker; | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 83 private List<Observer> observers; | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 84 private boolean shallDropDerivedCaches = false; | 
| 3 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 85 | 
| 608 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 86 public RevlogStream(Internals hgRepo, File indexFile) { | 
| 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 87 repo = hgRepo; | 
| 3 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 88 this.indexFile = indexFile; | 
| 608 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 89 changeTracker = repo.getRevlogTracker(indexFile); | 
| 3 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 90 } | 
| 621 
99ad1e3a4e4d
RevlogStream: be aware of existence (not HgDataFile), facilitate use of an added HgDataFile over a commit; Rollback: be more sensitive about file changes (file size is not enough: write/rollback leaves it intact); tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
617diff
changeset | 91 | 
| 
99ad1e3a4e4d
RevlogStream: be aware of existence (not HgDataFile), facilitate use of an added HgDataFile over a commit; Rollback: be more sensitive about file changes (file size is not enough: write/rollback leaves it intact); tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
617diff
changeset | 92 public boolean exists() { | 
| 
99ad1e3a4e4d
RevlogStream: be aware of existence (not HgDataFile), facilitate use of an added HgDataFile over a commit; Rollback: be more sensitive about file changes (file size is not enough: write/rollback leaves it intact); tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
617diff
changeset | 93 return indexFile.exists(); | 
| 
99ad1e3a4e4d
RevlogStream: be aware of existence (not HgDataFile), facilitate use of an added HgDataFile over a commit; Rollback: be more sensitive about file changes (file size is not enough: write/rollback leaves it intact); tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
617diff
changeset | 94 } | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 95 | 
| 606 
5daa42067e7c
Avoid mmap files when only few bytes are to be read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
594diff
changeset | 96 /** | 
| 
5daa42067e7c
Avoid mmap files when only few bytes are to be read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
594diff
changeset | 97 * @param shortRead pass <code>true</code> to indicate intention to read few revisions only (as opposed to reading most of/complete revlog) | 
| 
5daa42067e7c
Avoid mmap files when only few bytes are to be read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
594diff
changeset | 98 * @return never <code>null</code>, empty {@link DataAccess} if no stream is available | 
| 
5daa42067e7c
Avoid mmap files when only few bytes are to be read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
594diff
changeset | 99 */ | 
| 
5daa42067e7c
Avoid mmap files when only few bytes are to be read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
594diff
changeset | 100 /*package*/ DataAccess getIndexStream(boolean shortRead) { | 
| 
5daa42067e7c
Avoid mmap files when only few bytes are to be read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
594diff
changeset | 101 // shortRead hint helps to avoid mmap files when only | 
| 
5daa42067e7c
Avoid mmap files when only few bytes are to be read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
594diff
changeset | 102 // few bytes are to be read (i.e. #dataLength()) | 
| 608 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 103 DataAccessProvider dataAccess = repo.getDataAccess(); | 
| 606 
5daa42067e7c
Avoid mmap files when only few bytes are to be read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
594diff
changeset | 104 return dataAccess.createReader(indexFile, shortRead); | 
| 0 
dbd663faec1f
Basic changelog parsing
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 105 } | 
| 
dbd663faec1f
Basic changelog parsing
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 106 | 
| 9 
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
6diff
changeset | 107 /*package*/ DataAccess getDataStream() { | 
| 608 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 108 DataAccessProvider dataAccess = repo.getDataAccess(); | 
| 606 
5daa42067e7c
Avoid mmap files when only few bytes are to be read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
594diff
changeset | 109 return dataAccess.createReader(getDataFile(), false); | 
| 534 
243202f1bda5
Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
530diff
changeset | 110 } | 
| 
243202f1bda5
Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
530diff
changeset | 111 | 
| 617 
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
608diff
changeset | 112 /*package*/ DataSerializer getIndexStreamWriter(Transaction tr) throws HgIOException { | 
| 608 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 113 DataAccessProvider dataAccess = repo.getDataAccess(); | 
| 617 
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
608diff
changeset | 114 return dataAccess.createWriter(tr, indexFile, true); | 
| 534 
243202f1bda5
Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
530diff
changeset | 115 } | 
| 
243202f1bda5
Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
530diff
changeset | 116 | 
| 617 
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
608diff
changeset | 117 /*package*/ DataSerializer getDataStreamWriter(Transaction tr) throws HgIOException { | 
| 608 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 118 DataAccessProvider dataAccess = repo.getDataAccess(); | 
| 617 
65c01508f002
Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
608diff
changeset | 119 return dataAccess.createWriter(tr, getDataFile(), true); | 
| 9 
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
6diff
changeset | 120 } | 
| 
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
6diff
changeset | 121 | 
| 396 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 122 /** | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 123 * Constructs file object that corresponds to .d revlog counterpart. | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 124 * Note, it's caller responsibility to ensure this file makes any sense (i.e. check {@link #inline} attribute) | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 125 */ | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 126 private File getDataFile() { | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 127 if (dataFile == null) { | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 128 final String indexName = indexFile.getName(); | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 129 dataFile = new File(indexFile.getParentFile(), indexName.substring(0, indexName.length() - 1) + "d"); | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 130 } | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 131 return dataFile; | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 132 } | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 133 | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 134 // initialize exception with the file where revlog structure information comes from | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 135 public HgInvalidControlFileException initWithIndexFile(HgInvalidControlFileException ex) { | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 136 return ex.setFile(indexFile); | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 137 } | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 138 | 
| 664 
ae2d439fbed3
Utilize transaction when writing fncache. Better HgIOException
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
655diff
changeset | 139 public HgIOException initWithIndexFile(HgIOException ex) { | 
| 
ae2d439fbed3
Utilize transaction when writing fncache. Better HgIOException
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
655diff
changeset | 140 return ex.setFile(indexFile); | 
| 
ae2d439fbed3
Utilize transaction when writing fncache. Better HgIOException
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
655diff
changeset | 141 } | 
| 
ae2d439fbed3
Utilize transaction when writing fncache. Better HgIOException
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
655diff
changeset | 142 | 
| 396 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 143 // initialize exception with the file where revlog data comes from | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 144 public HgInvalidControlFileException initWithDataFile(HgInvalidControlFileException ex) { | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 145 // exceptions are usually raised after read attepmt, hence inline shall be initialized | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 146 // although honest approach is to call #initOutline() first | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 147 return ex.setFile(inline ? indexFile : getDataFile()); | 
| 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 148 } | 
| 534 
243202f1bda5
Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
530diff
changeset | 149 | 
| 
243202f1bda5
Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
530diff
changeset | 150 /*package-private*/String getDataFileName() { | 
| 
243202f1bda5
Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
530diff
changeset | 151 // XXX a temporary solution to provide more info to fill in exceptions other than | 
| 
243202f1bda5
Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
530diff
changeset | 152 // HgInvalidControlFileException (those benefit from initWith* methods above) | 
| 
243202f1bda5
Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
530diff
changeset | 153 // | 
| 
243202f1bda5
Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
530diff
changeset | 154 // Besides, since RevlogStream represents both revlogs with user data (those with WC representative and | 
| 
243202f1bda5
Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
530diff
changeset | 155 // system data under store/data) and system-only revlogs (like changelog and manifest), there's no | 
| 
243202f1bda5
Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
530diff
changeset | 156 // easy way to supply human-friendly name of the active file (independent from whether it's index of data) | 
| 
243202f1bda5
Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
530diff
changeset | 157 return inline ? indexFile.getPath() : getDataFile().getPath(); | 
| 
243202f1bda5
Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
530diff
changeset | 158 } | 
| 396 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 159 | 
| 628 
6526d8adbc0f
Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
621diff
changeset | 160 public boolean isInlineData() throws HgInvalidControlFileException { | 
| 534 
243202f1bda5
Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
530diff
changeset | 161 initOutline(); | 
| 
243202f1bda5
Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
530diff
changeset | 162 return inline; | 
| 
243202f1bda5
Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
530diff
changeset | 163 } | 
| 396 
0ae53c32ecef
Straighten out exceptions thrown when file access failed - three is too much
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 164 | 
| 628 
6526d8adbc0f
Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
621diff
changeset | 165 public int revisionCount() throws HgInvalidControlFileException { | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 166 initOutline(); | 
| 198 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 167 return baseRevisions.length; | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 168 } | 
| 22 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 169 | 
| 295 
981f9f50bb6c
Issue 11: Error log facility. SessionContext to share common facilities
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
288diff
changeset | 170 /** | 
| 354 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 171 * @throws HgInvalidControlFileException if attempt to read index file failed | 
| 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 172 * @throws HgInvalidRevisionException if revisionIndex argument doesn't represent a valid record in the revlog | 
| 295 
981f9f50bb6c
Issue 11: Error log facility. SessionContext to share common facilities
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
288diff
changeset | 173 */ | 
| 354 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 174 public int dataLength(int revisionIndex) throws HgInvalidControlFileException, HgInvalidRevisionException { | 
| 22 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 175 // XXX in fact, use of iterate() instead of this implementation may be quite reasonable. | 
| 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 176 // | 
| 354 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 177 revisionIndex = checkRevisionIndex(revisionIndex); | 
| 606 
5daa42067e7c
Avoid mmap files when only few bytes are to be read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
594diff
changeset | 178 DataAccess daIndex = getIndexStream(true); | 
| 22 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 179 try { | 
| 354 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 180 int recordOffset = getIndexOffsetInt(revisionIndex); | 
| 22 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 181 daIndex.seek(recordOffset + 12); // 6+2+4 | 
| 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 182 int actualLen = daIndex.readInt(); | 
| 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 183 return actualLen; | 
| 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 184 } catch (IOException ex) { | 
| 440 
299870249a28
Issue 30: bogus IOException for mmap file on linux
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
425diff
changeset | 185 throw new HgInvalidControlFileException(null, ex, indexFile).setRevisionIndex(revisionIndex); | 
| 22 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 186 } finally { | 
| 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 187 daIndex.done(); | 
| 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 188 } | 
| 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 189 } | 
| 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 190 | 
| 295 
981f9f50bb6c
Issue 11: Error log facility. SessionContext to share common facilities
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
288diff
changeset | 191 /** | 
| 354 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 192 * Read nodeid at given index | 
| 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 193 * | 
| 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 194 * @throws HgInvalidControlFileException if attempt to read index file failed | 
| 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 195 * @throws HgInvalidRevisionException if revisionIndex argument doesn't represent a valid record in the revlog | 
| 295 
981f9f50bb6c
Issue 11: Error log facility. SessionContext to share common facilities
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
288diff
changeset | 196 */ | 
| 354 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 197 public byte[] nodeid(int revisionIndex) throws HgInvalidControlFileException, HgInvalidRevisionException { | 
| 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 198 revisionIndex = checkRevisionIndex(revisionIndex); | 
| 606 
5daa42067e7c
Avoid mmap files when only few bytes are to be read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
594diff
changeset | 199 DataAccess daIndex = getIndexStream(true); | 
| 80 
4222b04f34ee
Follow history of a file
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 200 try { | 
| 354 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 201 int recordOffset = getIndexOffsetInt(revisionIndex); | 
| 80 
4222b04f34ee
Follow history of a file
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 202 daIndex.seek(recordOffset + 32); | 
| 
4222b04f34ee
Follow history of a file
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 203 byte[] rv = new byte[20]; | 
| 
4222b04f34ee
Follow history of a file
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 204 daIndex.readBytes(rv, 0, 20); | 
| 
4222b04f34ee
Follow history of a file
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 205 return rv; | 
| 
4222b04f34ee
Follow history of a file
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 206 } catch (IOException ex) { | 
| 440 
299870249a28
Issue 30: bogus IOException for mmap file on linux
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
425diff
changeset | 207 throw new HgInvalidControlFileException("Revision lookup failed", ex, indexFile).setRevisionIndex(revisionIndex); | 
| 80 
4222b04f34ee
Follow history of a file
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 208 } finally { | 
| 88 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
80diff
changeset | 209 daIndex.done(); | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
80diff
changeset | 210 } | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
80diff
changeset | 211 } | 
| 295 
981f9f50bb6c
Issue 11: Error log facility. SessionContext to share common facilities
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
288diff
changeset | 212 | 
| 
981f9f50bb6c
Issue 11: Error log facility. SessionContext to share common facilities
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
288diff
changeset | 213 /** | 
| 
981f9f50bb6c
Issue 11: Error log facility. SessionContext to share common facilities
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
288diff
changeset | 214 * Get link field from the index record. | 
| 354 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 215 * | 
| 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 216 * @throws HgInvalidControlFileException if attempt to read index file failed | 
| 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 217 * @throws HgInvalidRevisionException if revisionIndex argument doesn't represent a valid record in the revlog | 
| 295 
981f9f50bb6c
Issue 11: Error log facility. SessionContext to share common facilities
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
288diff
changeset | 218 */ | 
| 354 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 219 public int linkRevision(int revisionIndex) throws HgInvalidControlFileException, HgInvalidRevisionException { | 
| 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 220 revisionIndex = checkRevisionIndex(revisionIndex); | 
| 606 
5daa42067e7c
Avoid mmap files when only few bytes are to be read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
594diff
changeset | 221 DataAccess daIndex = getIndexStream(true); | 
| 88 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
80diff
changeset | 222 try { | 
| 354 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 223 int recordOffset = getIndexOffsetInt(revisionIndex); | 
| 88 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
80diff
changeset | 224 daIndex.seek(recordOffset + 20); | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
80diff
changeset | 225 int linkRev = daIndex.readInt(); | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
80diff
changeset | 226 return linkRev; | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
80diff
changeset | 227 } catch (IOException ex) { | 
| 440 
299870249a28
Issue 30: bogus IOException for mmap file on linux
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
425diff
changeset | 228 throw new HgInvalidControlFileException("Linked revision lookup failed", ex, indexFile).setRevisionIndex(revisionIndex); | 
| 88 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
80diff
changeset | 229 } finally { | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
80diff
changeset | 230 daIndex.done(); | 
| 80 
4222b04f34ee
Follow history of a file
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 231 } | 
| 
4222b04f34ee
Follow history of a file
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 232 } | 
| 
4222b04f34ee
Follow history of a file
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 233 | 
| 585 
b47ef0d2777b
Access to base revision filed comes handy for debug sometimes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
584diff
changeset | 234 /** | 
| 
b47ef0d2777b
Access to base revision filed comes handy for debug sometimes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
584diff
changeset | 235 * Extract base revision field from the revlog | 
| 
b47ef0d2777b
Access to base revision filed comes handy for debug sometimes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
584diff
changeset | 236 * | 
| 
b47ef0d2777b
Access to base revision filed comes handy for debug sometimes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
584diff
changeset | 237 * @throws HgInvalidControlFileException if attempt to read index file failed | 
| 
b47ef0d2777b
Access to base revision filed comes handy for debug sometimes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
584diff
changeset | 238 * @throws HgInvalidRevisionException if revisionIndex argument doesn't represent a valid record in the revlog | 
| 
b47ef0d2777b
Access to base revision filed comes handy for debug sometimes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
584diff
changeset | 239 */ | 
| 
b47ef0d2777b
Access to base revision filed comes handy for debug sometimes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
584diff
changeset | 240 public int baseRevision(int revisionIndex) throws HgInvalidControlFileException, HgInvalidRevisionException { | 
| 
b47ef0d2777b
Access to base revision filed comes handy for debug sometimes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
584diff
changeset | 241 revisionIndex = checkRevisionIndex(revisionIndex); | 
| 
b47ef0d2777b
Access to base revision filed comes handy for debug sometimes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
584diff
changeset | 242 return getBaseRevision(revisionIndex); | 
| 
b47ef0d2777b
Access to base revision filed comes handy for debug sometimes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
584diff
changeset | 243 } | 
| 
b47ef0d2777b
Access to base revision filed comes handy for debug sometimes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
584diff
changeset | 244 | 
| 644 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 245 /** | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 246 * Read indexes of parent revisions | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 247 * @param revisionIndex index of child revision | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 248 * @param parents array to hold return value, length >= 2 | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 249 * @return value of <code>parents</code> parameter for convenience | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 250 * @throws HgInvalidControlFileException if attempt to read index file failed | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 251 * @throws HgInvalidRevisionException if revisionIndex argument doesn't represent a valid record in the revlog | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 252 */ | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 253 public int[] parents(int revisionIndex, int[] parents) throws HgInvalidControlFileException, HgInvalidRevisionException { | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 254 assert parents.length > 1; | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 255 revisionIndex = checkRevisionIndex(revisionIndex); | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 256 DataAccess daIndex = getIndexStream(true); | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 257 try { | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 258 int recordOffset = getIndexOffsetInt(revisionIndex); | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 259 daIndex.seek(recordOffset + 24); | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 260 int p1 = daIndex.readInt(); | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 261 int p2 = daIndex.readInt(); | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 262 // although NO_REVISION == -1, it doesn't hurt to ensure this | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 263 parents[0] = p1 == -1 ? NO_REVISION : p1; | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 264 parents[1] = p2 == -1 ? NO_REVISION : p2; | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 265 return parents; | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 266 } catch (IOException ex) { | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 267 throw new HgInvalidControlFileException("Parents lookup failed", ex, indexFile).setRevisionIndex(revisionIndex); | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 268 } finally { | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 269 daIndex.done(); | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 270 } | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 271 } | 
| 
1deea2f33218
Push: phase1 - prepare bundle with changes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
628diff
changeset | 272 | 
| 49 
26e3eeaa3962
branch and user filtering for log operation
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
44diff
changeset | 273 // Perhaps, RevlogStream should be limited to use of plain int revisions for access, | 
| 
26e3eeaa3962
branch and user filtering for log operation
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
44diff
changeset | 274 // while Nodeids should be kept on the level up, in Revlog. Guess, Revlog better keep | 
| 
26e3eeaa3962
branch and user filtering for log operation
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
44diff
changeset | 275 // map of nodeids, and once this comes true, we may get rid of this method. | 
| 80 
4222b04f34ee
Follow history of a file
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 276 // Unlike its counterpart, {@link Revlog#getLocalRevisionNumber()}, doesn't fail with exception if node not found, | 
| 
4222b04f34ee
Follow history of a file
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 277 /** | 
| 
4222b04f34ee
Follow history of a file
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 278 * @return integer in [0..revisionCount()) or {@link HgRepository#BAD_REVISION} if not found | 
| 354 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 279 * @throws HgInvalidControlFileException if attempt to read index file failed | 
| 80 
4222b04f34ee
Follow history of a file
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 280 */ | 
| 367 
2fadf8695f8a
Use 'revision index' instead of the vague 'local revision number' concept in the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
366diff
changeset | 281 public int findRevisionIndex(Nodeid nodeid) throws HgInvalidControlFileException { | 
| 22 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 282 // XXX this one may be implemented with iterate() once there's mechanism to stop iterations | 
| 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 283 final int indexSize = revisionCount(); | 
| 606 
5daa42067e7c
Avoid mmap files when only few bytes are to be read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
594diff
changeset | 284 DataAccess daIndex = getIndexStream(false); | 
| 22 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 285 try { | 
| 24 
d4fdd1845b3f
Nodeid with array of exactly 20 bytes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
22diff
changeset | 286 byte[] nodeidBuf = new byte[20]; | 
| 22 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 287 for (int i = 0; i < indexSize; i++) { | 
| 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 288 daIndex.skip(8); | 
| 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 289 int compressedLen = daIndex.readInt(); | 
| 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 290 daIndex.skip(20); | 
| 24 
d4fdd1845b3f
Nodeid with array of exactly 20 bytes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
22diff
changeset | 291 daIndex.readBytes(nodeidBuf, 0, 20); | 
| 
d4fdd1845b3f
Nodeid with array of exactly 20 bytes
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
22diff
changeset | 292 if (nodeid.equalsTo(nodeidBuf)) { | 
| 22 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 293 return i; | 
| 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 294 } | 
| 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 295 daIndex.skip(inline ? 12 + compressedLen : 12); | 
| 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 296 } | 
| 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 297 } catch (IOException ex) { | 
| 440 
299870249a28
Issue 30: bogus IOException for mmap file on linux
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
425diff
changeset | 298 throw new HgInvalidControlFileException("Revision lookup failed", ex, indexFile).setRevision(nodeid); | 
| 22 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 299 } finally { | 
| 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 300 daIndex.done(); | 
| 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 301 } | 
| 80 
4222b04f34ee
Follow history of a file
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 302 return BAD_REVISION; | 
| 22 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
10diff
changeset | 303 } | 
| 538 
dd4f6311af52
Commit: first working version
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
534diff
changeset | 304 | 
| 539 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 305 /** | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 306 * @return value suitable for the corresponding field in the new revision's header, not physical offset in the file | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 307 * (which is different in case of inline revlogs) | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 308 */ | 
| 628 
6526d8adbc0f
Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
621diff
changeset | 309 public long newEntryOffset() throws HgInvalidControlFileException { | 
| 538 
dd4f6311af52
Commit: first working version
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
534diff
changeset | 310 if (revisionCount() == 0) { | 
| 
dd4f6311af52
Commit: first working version
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
534diff
changeset | 311 return 0; | 
| 
dd4f6311af52
Commit: first working version
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
534diff
changeset | 312 } | 
| 606 
5daa42067e7c
Avoid mmap files when only few bytes are to be read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
594diff
changeset | 313 DataAccess daIndex = getIndexStream(true); | 
| 538 
dd4f6311af52
Commit: first working version
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
534diff
changeset | 314 int lastRev = revisionCount() - 1; | 
| 
dd4f6311af52
Commit: first working version
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
534diff
changeset | 315 try { | 
| 
dd4f6311af52
Commit: first working version
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
534diff
changeset | 316 int recordOffset = getIndexOffsetInt(lastRev); | 
| 
dd4f6311af52
Commit: first working version
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
534diff
changeset | 317 daIndex.seek(recordOffset); | 
| 
dd4f6311af52
Commit: first working version
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
534diff
changeset | 318 long value = daIndex.readLong(); | 
| 
dd4f6311af52
Commit: first working version
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
534diff
changeset | 319 value = value >>> 16; | 
| 
dd4f6311af52
Commit: first working version
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
534diff
changeset | 320 int compressedLen = daIndex.readInt(); | 
| 
dd4f6311af52
Commit: first working version
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
534diff
changeset | 321 return lastRev == 0 ? compressedLen : value + compressedLen; | 
| 
dd4f6311af52
Commit: first working version
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
534diff
changeset | 322 } catch (IOException ex) { | 
| 
dd4f6311af52
Commit: first working version
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
534diff
changeset | 323 throw new HgInvalidControlFileException("Linked revision lookup failed", ex, indexFile).setRevisionIndex(lastRev); | 
| 
dd4f6311af52
Commit: first working version
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
534diff
changeset | 324 } finally { | 
| 
dd4f6311af52
Commit: first working version
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
534diff
changeset | 325 daIndex.done(); | 
| 
dd4f6311af52
Commit: first working version
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
534diff
changeset | 326 } | 
| 
dd4f6311af52
Commit: first working version
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
534diff
changeset | 327 } | 
| 
dd4f6311af52
Commit: first working version
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
534diff
changeset | 328 | 
| 628 
6526d8adbc0f
Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
621diff
changeset | 329 /** | 
| 
6526d8adbc0f
Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
621diff
changeset | 330 * should be possible to use TIP, ALL, or -1, -2, -n notation of Hg | 
| 
6526d8adbc0f
Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
621diff
changeset | 331 * ? boolean needsNodeid | 
| 
6526d8adbc0f
Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
621diff
changeset | 332 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> | 
| 
6526d8adbc0f
Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
621diff
changeset | 333 */ | 
| 
6526d8adbc0f
Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
621diff
changeset | 334 public void iterate(int start, int end, boolean needData, Inspector inspector) throws HgRuntimeException { | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 335 initOutline(); | 
| 198 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 336 final int indexSize = revisionCount(); | 
| 3 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 337 if (indexSize == 0) { | 
| 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 338 return; | 
| 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 339 } | 
| 5 
fc265ddeab26
File content and non-effective, although working, patch application
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
4diff
changeset | 340 if (end == TIP) { | 
| 3 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 341 end = indexSize - 1; | 
| 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 342 } | 
| 5 
fc265ddeab26
File content and non-effective, although working, patch application
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
4diff
changeset | 343 if (start == TIP) { | 
| 
fc265ddeab26
File content and non-effective, although working, patch application
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
4diff
changeset | 344 start = indexSize - 1; | 
| 
fc265ddeab26
File content and non-effective, although working, patch application
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
4diff
changeset | 345 } | 
| 300 
650b45d290b1
Share range check code
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
297diff
changeset | 346 HgInternals.checkRevlogRange(start, end, indexSize-1); | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 347 // XXX may cache [start .. end] from index with a single read (pre-read) | 
| 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 348 | 
| 608 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 349 ReaderN1 r = new ReaderN1(needData, inspector, repo.shallMergePatches()); | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 350 try { | 
| 593 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 351 r.start(end - start + 1, getLastRevisionRead()); | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 352 r.range(start, end); | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 353 } catch (IOException ex) { | 
| 366 
189dc6dc1c3e
Use exceptions to expose errors reading mercurial data
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
354diff
changeset | 354 throw new HgInvalidControlFileException(String.format("Failed reading [%d..%d]", start, end), ex, indexFile); | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 355 } finally { | 
| 593 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 356 CachedRevision cr = r.finish(); | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 357 setLastRevisionRead(cr); | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 358 } | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 359 } | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 360 | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 361 /** | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 362 * Effective alternative to {@link #iterate(int, int, boolean, Inspector) batch read}, when only few selected | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 363 * revisions are of interest. | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 364 * @param sortedRevisions revisions to walk, in ascending order. | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 365 * @param needData whether inspector needs access to header only | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 366 * @param inspector callback to process entries | 
| 628 
6526d8adbc0f
Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
621diff
changeset | 367 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 368 */ | 
| 628 
6526d8adbc0f
Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
621diff
changeset | 369 public void iterate(int[] sortedRevisions, boolean needData, Inspector inspector) throws HgRuntimeException { | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 370 final int indexSize = revisionCount(); | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 371 if (indexSize == 0 || sortedRevisions.length == 0) { | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 372 return; | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 373 } | 
| 347 
8da7ade36c57
Add specific IAE subclass to handle wrong (e.g. outdated after rollback) revisions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
329diff
changeset | 374 if (sortedRevisions[0] > indexSize) { | 
| 
8da7ade36c57
Add specific IAE subclass to handle wrong (e.g. outdated after rollback) revisions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
329diff
changeset | 375 throw new HgInvalidRevisionException(String.format("Can't iterate [%d, %d] in range [0..%d]", sortedRevisions[0], sortedRevisions[sortedRevisions.length - 1], indexSize), null, sortedRevisions[0]); | 
| 
8da7ade36c57
Add specific IAE subclass to handle wrong (e.g. outdated after rollback) revisions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
329diff
changeset | 376 } | 
| 
8da7ade36c57
Add specific IAE subclass to handle wrong (e.g. outdated after rollback) revisions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
329diff
changeset | 377 if (sortedRevisions[sortedRevisions.length - 1] > indexSize) { | 
| 
8da7ade36c57
Add specific IAE subclass to handle wrong (e.g. outdated after rollback) revisions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
329diff
changeset | 378 throw new HgInvalidRevisionException(String.format("Can't iterate [%d, %d] in range [0..%d]", sortedRevisions[0], sortedRevisions[sortedRevisions.length - 1], indexSize), null, sortedRevisions[sortedRevisions.length - 1]); | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 379 } | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 380 | 
| 608 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 381 ReaderN1 r = new ReaderN1(needData, inspector, repo.shallMergePatches()); | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 382 try { | 
| 594 
cc7b0c4dc993
Cache only in-memory revision representations
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
593diff
changeset | 383 r.start(sortedRevisions.length, getLastRevisionRead()); | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 384 for (int i = 0; i < sortedRevisions.length; ) { | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 385 int x = i; | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 386 i++; | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 387 while (i < sortedRevisions.length) { | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 388 if (sortedRevisions[i] == sortedRevisions[i-1] + 1) { | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 389 i++; | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 390 } else { | 
| 217 
e39cf474ef94
Experimental support to mix-in start and end events for inspectors. Additionally, Lifecycle may serve as iteration control
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
202diff
changeset | 391 break; | 
| 
e39cf474ef94
Experimental support to mix-in start and end events for inspectors. Additionally, Lifecycle may serve as iteration control
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
202diff
changeset | 392 } | 
| 
e39cf474ef94
Experimental support to mix-in start and end events for inspectors. Additionally, Lifecycle may serve as iteration control
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
202diff
changeset | 393 } | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 394 // commitRevisions[x..i-1] are sequential | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 395 if (!r.range(sortedRevisions[x], sortedRevisions[i-1])) { | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 396 return; | 
| 51 
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
49diff
changeset | 397 } | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 398 } | 
| 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 399 } catch (IOException ex) { | 
| 366 
189dc6dc1c3e
Use exceptions to expose errors reading mercurial data
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
354diff
changeset | 400 final int c = sortedRevisions.length; | 
| 608 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 401 throw new HgInvalidControlFileException(String.format("Failed reading %d revisions in [%d; %d]", c, sortedRevisions[0], sortedRevisions[c-1]), ex, indexFile); | 
| 3 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 402 } finally { | 
| 593 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 403 CachedRevision cr = r.finish(); | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 404 setLastRevisionRead(cr); | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 405 } | 
| 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 406 } | 
| 607 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 407 | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 408 public void attach(Observer listener) { | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 409 assert listener != null; | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 410 if (observers == null) { | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 411 observers = new ArrayList<Observer>(3); | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 412 } | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 413 observers.add(listener); | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 414 } | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 415 | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 416 public void detach(Observer listener) { | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 417 assert listener != null; | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 418 if (observers != null) { | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 419 observers.remove(listener); | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 420 } | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 421 } | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 422 | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 423 /* | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 424 * Note, this method IS NOT a replacement for Observer. It has to be invoked when the validity of any | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 425 * cache built using revision information is in doubt, but it provides reasonable value only till the | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 426 * first initOutline() to be invoked, i.e. in [change..revlog read operation] time frame. If your code | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 427 * accesses cached information without any prior explicit read operation, you shall consult this method | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 428 * if next read operation would in fact bring changed content. | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 429 * Observer is needed in addition to this method because any revlog read operation (e.g. Revlog#getLastRevision) | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 430 * would clear shallDropDerivedCaches(), and if code relies only on this method to clear its derived caches, | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 431 * it would miss the update. | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 432 */ | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 433 public boolean shallDropDerivedCaches() { | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 434 if (shallDropDerivedCaches) { | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 435 return shallDropDerivedCaches; | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 436 } | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 437 return shallDropDerivedCaches = changeTracker.hasChanged(indexFile); | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 438 } | 
| 198 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 439 | 
| 539 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 440 void revisionAdded(int revisionIndex, Nodeid revision, int baseRevisionIndex, long revisionOffset) throws HgInvalidControlFileException { | 
| 607 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 441 shallDropDerivedCaches = true; | 
| 539 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 442 if (!outlineCached()) { | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 443 return; | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 444 } | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 445 if (baseRevisions.length != revisionIndex) { | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 446 throw new HgInvalidControlFileException(String.format("New entry's index shall be %d, not %d", baseRevisions.length, revisionIndex), null, indexFile); | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 447 } | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 448 if (baseRevisionIndex < 0 || baseRevisionIndex > baseRevisions.length) { | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 449 // baseRevisionIndex MAY be == to baseRevisions.length, it's when new revision is based on itself | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 450 throw new HgInvalidControlFileException(String.format("Base revision index %d doesn't fit [0..%d] range", baseRevisionIndex, baseRevisions.length), null, indexFile); | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 451 } | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 452 assert revision != null; | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 453 assert !revision.isNull(); | 
| 621 
99ad1e3a4e4d
RevlogStream: be aware of existence (not HgDataFile), facilitate use of an added HgDataFile over a commit; Rollback: be more sensitive about file changes (file size is not enough: write/rollback leaves it intact); tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
617diff
changeset | 454 // next effort doesn't seem to be of any value at least in case of regular commit | 
| 
99ad1e3a4e4d
RevlogStream: be aware of existence (not HgDataFile), facilitate use of an added HgDataFile over a commit; Rollback: be more sensitive about file changes (file size is not enough: write/rollback leaves it intact); tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
617diff
changeset | 455 // as the next call to #initOutline would recognize the file change and reload complete revlog anyway | 
| 
99ad1e3a4e4d
RevlogStream: be aware of existence (not HgDataFile), facilitate use of an added HgDataFile over a commit; Rollback: be more sensitive about file changes (file size is not enough: write/rollback leaves it intact); tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
617diff
changeset | 456 // OTOH, there might be transaction strategy that doesn't update the file until its completion, | 
| 
99ad1e3a4e4d
RevlogStream: be aware of existence (not HgDataFile), facilitate use of an added HgDataFile over a commit; Rollback: be more sensitive about file changes (file size is not enough: write/rollback leaves it intact); tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
617diff
changeset | 457 // while it's handy to know new revisions meanwhile. | 
| 539 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 458 int[] baseRevisionsCopy = new int[baseRevisions.length + 1]; | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 459 System.arraycopy(baseRevisions, 0, baseRevisionsCopy, 0, baseRevisions.length); | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 460 baseRevisionsCopy[baseRevisions.length] = baseRevisionIndex; | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 461 baseRevisions = baseRevisionsCopy; | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 462 if (inline && indexRecordOffset != null) { | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 463 assert indexRecordOffset.length == revisionIndex; | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 464 int[] indexRecordOffsetCopy = new int[indexRecordOffset.length + 1]; | 
| 559 
6ca3d0c5b4bc
Commit: tests and fixes for defects discovered
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
539diff
changeset | 465 System.arraycopy(indexRecordOffset, 0, indexRecordOffsetCopy, 0, indexRecordOffset.length); | 
| 539 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 466 indexRecordOffsetCopy[indexRecordOffset.length] = offsetFieldToInlineFileOffset(revisionOffset, revisionIndex); | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 467 indexRecordOffset = indexRecordOffsetCopy; | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 468 } | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 469 } | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 470 | 
| 198 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 471 private int getBaseRevision(int revision) { | 
| 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 472 return baseRevisions[revision]; | 
| 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 473 } | 
| 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 474 | 
| 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 475 /** | 
| 354 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 476 * @param revisionIndex shall be valid index, [0..baseRevisions.length-1]. | 
| 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 477 * It's advised to use {@link #checkRevisionIndex(int)} to ensure argument is correct. | 
| 198 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 478 * @return offset of the revision's record in the index (.i) stream | 
| 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 479 */ | 
| 354 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 480 private int getIndexOffsetInt(int revisionIndex) { | 
| 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 481 return inline ? indexRecordOffset[revisionIndex] : revisionIndex * REVLOGV1_RECORD_SIZE; | 
| 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 482 } | 
| 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 483 | 
| 628 
6526d8adbc0f
Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
621diff
changeset | 484 private int checkRevisionIndex(int revisionIndex) throws HgInvalidControlFileException, HgInvalidRevisionException { | 
| 354 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 485 final int last = revisionCount() - 1; | 
| 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 486 if (revisionIndex == TIP) { | 
| 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 487 revisionIndex = last; | 
| 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 488 } | 
| 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 489 if (revisionIndex < 0 || revisionIndex > last) { | 
| 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 490 throw new HgInvalidRevisionException(revisionIndex).setRevisionIndex(revisionIndex, 0, last); | 
| 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 491 } | 
| 
5f9073eabf06
Propagate errors with exceptions up to a end client
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
347diff
changeset | 492 return revisionIndex; | 
| 198 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 493 } | 
| 539 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 494 | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 495 private boolean outlineCached() { | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 496 return baseRevisions != null && baseRevisions.length > 0; | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 497 } | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 498 | 
| 584 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 499 // translate 6-byte offset field value to physical file offset for inline revlogs | 
| 539 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 500 // DOESN'T MAKE SENSE if revlog with data is separate | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 501 private static int offsetFieldToInlineFileOffset(long offset, int recordIndex) throws HgInvalidStateException { | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 502 int o = Internals.ltoi(offset); | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 503 if (o != offset) { | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 504 // just in case, can't happen, ever, unless HG (or some other bad tool) produces index file | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 505 // with inlined data of size greater than 2 Gb. | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 506 throw new HgInvalidStateException("Data too big, offset didn't fit to sizeof(int)"); | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 507 } | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 508 return o + REVLOGV1_RECORD_SIZE * recordIndex; | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 509 } | 
| 198 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 510 | 
| 607 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 511 // every access to index revlog goes after this method only. | 
| 425 
48f993aa2f41
FIXMEs: exceptions, javadoc
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
423diff
changeset | 512 private void initOutline() throws HgInvalidControlFileException { | 
| 607 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 513 // true to send out 'drop-your-caches' event after outline has been built | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 514 final boolean notifyReload; | 
| 539 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 515 if (outlineCached()) { | 
| 607 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 516 if (!changeTracker.hasChanged(indexFile)) { | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 517 return; | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 518 } | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 519 notifyReload = true; | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 520 } else { | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 521 // no cached outline - inital read, do not send any reload/invalidate notifications | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 522 notifyReload = false; | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 523 } | 
| 607 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 524 changeTracker.touch(indexFile); | 
| 606 
5daa42067e7c
Avoid mmap files when only few bytes are to be read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
594diff
changeset | 525 DataAccess da = getIndexStream(false); | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 526 try { | 
| 202 
706bcc7cfee4
Basic test for HgIncomingCommand. Fix RepositoryComparator for cases when whole repository is unknown. Respect freshly initialized (empty) repositories in general.
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
198diff
changeset | 527 if (da.isEmpty()) { | 
| 
706bcc7cfee4
Basic test for HgIncomingCommand. Fix RepositoryComparator for cases when whole repository is unknown. Respect freshly initialized (empty) repositories in general.
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
198diff
changeset | 528 // do not fail with exception if stream is empty, it's likely intentional | 
| 
706bcc7cfee4
Basic test for HgIncomingCommand. Fix RepositoryComparator for cases when whole repository is unknown. Respect freshly initialized (empty) repositories in general.
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
198diff
changeset | 529 baseRevisions = new int[0]; | 
| 539 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 530 // empty revlog, likely to be populated, indicate we start with a single file | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 531 inline = true; | 
| 202 
706bcc7cfee4
Basic test for HgIncomingCommand. Fix RepositoryComparator for cases when whole repository is unknown. Respect freshly initialized (empty) repositories in general.
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
198diff
changeset | 532 return; | 
| 
706bcc7cfee4
Basic test for HgIncomingCommand. Fix RepositoryComparator for cases when whole repository is unknown. Respect freshly initialized (empty) repositories in general.
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
198diff
changeset | 533 } | 
| 9 
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
6diff
changeset | 534 int versionField = da.readInt(); | 
| 170 
71ddbf8603e8
Initial clone: populate given directory from a bundle. Everything but remote server access is there, albeit prototype code style
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
158diff
changeset | 535 da.readInt(); // just to skip next 4 bytes of offset + flags | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 536 inline = (versionField & INLINEDATA) != 0; | 
| 288 
b11f6a08f748
Avoid boxing int values and list resizes on revlog read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
280diff
changeset | 537 IntVector resBases, resOffsets = null; | 
| 420 
6c22bdc0bdfd
Respect long offsets in revlogs
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
398diff
changeset | 538 int entryCountGuess = Internals.ltoi(da.longLength() / REVLOGV1_RECORD_SIZE); | 
| 288 
b11f6a08f748
Avoid boxing int values and list resizes on revlog read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
280diff
changeset | 539 if (inline) { | 
| 
b11f6a08f748
Avoid boxing int values and list resizes on revlog read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
280diff
changeset | 540 entryCountGuess >>>= 2; // pure guess, assume useful data takes 3/4 of total space | 
| 
b11f6a08f748
Avoid boxing int values and list resizes on revlog read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
280diff
changeset | 541 resOffsets = new IntVector(entryCountGuess, 5000); | 
| 
b11f6a08f748
Avoid boxing int values and list resizes on revlog read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
280diff
changeset | 542 } | 
| 
b11f6a08f748
Avoid boxing int values and list resizes on revlog read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
280diff
changeset | 543 resBases = new IntVector(entryCountGuess, 5000); | 
| 
b11f6a08f748
Avoid boxing int values and list resizes on revlog read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
280diff
changeset | 544 | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 545 long offset = 0; // first offset is always 0, thus Hg uses it for other purposes | 
| 9 
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
6diff
changeset | 546 while(true) { | 
| 
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
6diff
changeset | 547 int compressedLen = da.readInt(); | 
| 5 
fc265ddeab26
File content and non-effective, although working, patch application
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
4diff
changeset | 548 // 8+4 = 12 bytes total read here | 
| 49 
26e3eeaa3962
branch and user filtering for log operation
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
44diff
changeset | 549 @SuppressWarnings("unused") | 
| 9 
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
6diff
changeset | 550 int actualLen = da.readInt(); | 
| 
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
6diff
changeset | 551 int baseRevision = da.readInt(); | 
| 5 
fc265ddeab26
File content and non-effective, although working, patch application
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
4diff
changeset | 552 // 12 + 8 = 20 bytes read here | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 553 // int linkRevision = di.readInt(); | 
| 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 554 // int parent1Revision = di.readInt(); | 
| 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 555 // int parent2Revision = di.readInt(); | 
| 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 556 // byte[] nodeid = new byte[32]; | 
| 198 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 557 resBases.add(baseRevision); | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 558 if (inline) { | 
| 539 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 559 int o = offsetFieldToInlineFileOffset(offset, resOffsets.size()); | 
| 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 560 resOffsets.add(o); | 
| 9 
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
6diff
changeset | 561 da.skip(3*4 + 32 + compressedLen); // Check: 44 (skip) + 20 (read) = 64 (total RevlogNG record size) | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 562 } else { | 
| 9 
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
6diff
changeset | 563 da.skip(3*4 + 32); | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 564 } | 
| 10 
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
9diff
changeset | 565 if (da.isEmpty()) { | 
| 9 
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
6diff
changeset | 566 // fine, done then | 
| 288 
b11f6a08f748
Avoid boxing int values and list resizes on revlog read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
280diff
changeset | 567 baseRevisions = resBases.toArray(true); | 
| 198 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 568 if (inline) { | 
| 288 
b11f6a08f748
Avoid boxing int values and list resizes on revlog read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
280diff
changeset | 569 indexRecordOffset = resOffsets.toArray(true); | 
| 198 
33a7d76f067b
Performance optimization: reduce memory to keep revlog cached info
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
170diff
changeset | 570 } | 
| 9 
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
6diff
changeset | 571 break; | 
| 10 
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
9diff
changeset | 572 } else { | 
| 
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
9diff
changeset | 573 // start reading next record | 
| 
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
9diff
changeset | 574 long l = da.readLong(); | 
| 
382cfe9463db
Dirstate parsing. DataAccess refactored to allow reuse and control over constants
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
9diff
changeset | 575 offset = l >>> 16; | 
| 9 
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
6diff
changeset | 576 } | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 577 } | 
| 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 578 } catch (IOException ex) { | 
| 423 
9c9c442b5f2e
Major refactoring of exception handling. Low-level API uses RuntimeExceptions, while checked are left for higher level
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
420diff
changeset | 579 throw new HgInvalidControlFileException("Failed to analyze revlog index", ex, indexFile); | 
| 9 
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
6diff
changeset | 580 } finally { | 
| 
d6d2a630f4a6
Access to underlaying file data wrapped into own Access object, implemented with FileChannel and ByteBuffer
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
6diff
changeset | 581 da.done(); | 
| 607 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 582 if (notifyReload && observers != null) { | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 583 for (Observer l : observers) { | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 584 l.reloaded(this); | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 585 } | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 586 shallDropDerivedCaches = false; | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 587 } | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
0diff
changeset | 588 } | 
| 3 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 589 } | 
| 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 590 | 
| 593 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 591 private CachedRevision getLastRevisionRead() { | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 592 return lastRevisionRead == null ? null : lastRevisionRead.get(); | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 593 } | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 594 | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 595 private void setLastRevisionRead(CachedRevision cr) { | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 596 // done() for lastRevisionRead.userData has been called by ReaderN1 once | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 597 // it noticed unsuitable DataAccess. | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 598 // Now, done() for any CachedRevision cleared by GC: | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 599 for (Reference<? extends CachedRevision> r; (r = lastRevisionQueue.poll()) != null;) { | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 600 CachedRevision toClean = r.get(); | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 601 if (toClean != null && toClean.userData != null) { | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 602 toClean.userData.done(); | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 603 } | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 604 } | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 605 if (cr != null) { | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 606 lastRevisionRead = new SoftReference<CachedRevision>(cr, lastRevisionQueue); | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 607 } else { | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 608 lastRevisionRead = null; | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 609 } | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 610 } | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 611 | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 612 final static class CachedRevision { | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 613 final int revision; | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 614 final DataAccess userData; | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 615 | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 616 public CachedRevision(int lastRevisionRead, DataAccess lastUserData) { | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 617 revision = lastRevisionRead; | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 618 userData = lastUserData; | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 619 } | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 620 } | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 621 | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 622 /** | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 623 * operation with single file open/close and multiple diverse reads. | 
| 366 
189dc6dc1c3e
Use exceptions to expose errors reading mercurial data
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
354diff
changeset | 624 * XXX initOutline might need similar extraction to keep N1 format knowledge | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 625 */ | 
| 584 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 626 final class ReaderN1 { | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 627 private final Inspector inspector; | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 628 private final boolean needData; | 
| 584 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 629 private final boolean mergePatches; | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 630 private DataAccess daIndex = null, daData = null; | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 631 private Lifecycle.BasicCallback cb = null; | 
| 520 
1ee452f31187
Experimental support for inverse direction history walking. Refactored/streamlined cancellation in HgLogCommand and down the stack
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
440diff
changeset | 632 private Lifecycle lifecycleListener = null; | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 633 private int lastRevisionRead = BAD_REVISION; | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 634 private DataAccess lastUserData; | 
| 584 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 635 // | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 636 // next are transient values, for range() use only | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 637 private final Inflater inflater = new Inflater(); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 638 // can share buffer between instances of InflaterDataAccess as I never read any two of them in parallel | 
| 608 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 639 private final byte[] inflaterBuffer = new byte[10 * 1024]; // TODO [post-1.1] consider using DAP.DEFAULT_FILE_BUFFER | 
| 655 
bcbcc318f250
Performance: reuse unzip output buffer
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
644diff
changeset | 640 private final ByteBuffer inflaterOutBuffer = ByteBuffer.allocate(inflaterBuffer.length * 2); | 
| 584 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 641 private final byte[] nodeidBuf = new byte[20]; | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 642 // revlog record fields | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 643 private long offset; | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 644 @SuppressWarnings("unused") | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 645 private int flags; | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 646 private int compressedLen; | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 647 private int actualLen; | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 648 private int baseRevision; | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 649 private int linkRevision; | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 650 private int parent1Revision; | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 651 private int parent2Revision; | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 652 | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 653 public ReaderN1(boolean dataRequested, Inspector insp, boolean usePatchMerge) { | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 654 assert insp != null; | 
| 584 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 655 needData = dataRequested; | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 656 inspector = insp; | 
| 584 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 657 mergePatches = usePatchMerge; | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 658 } | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 659 | 
| 593 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 660 public void start(int totalWork, CachedRevision cachedRevision) { | 
| 606 
5daa42067e7c
Avoid mmap files when only few bytes are to be read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
594diff
changeset | 661 daIndex = getIndexStream(totalWork <= 10); | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 662 if (needData && !inline) { | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 663 daData = getDataStream(); | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 664 } | 
| 520 
1ee452f31187
Experimental support for inverse direction history walking. Refactored/streamlined cancellation in HgLogCommand and down the stack
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
440diff
changeset | 665 lifecycleListener = Adaptable.Factory.getAdapter(inspector, Lifecycle.class, null); | 
| 
1ee452f31187
Experimental support for inverse direction history walking. Refactored/streamlined cancellation in HgLogCommand and down the stack
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
440diff
changeset | 666 if (lifecycleListener != null) { | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 667 cb = new Lifecycle.BasicCallback(); | 
| 520 
1ee452f31187
Experimental support for inverse direction history walking. Refactored/streamlined cancellation in HgLogCommand and down the stack
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
440diff
changeset | 668 lifecycleListener.start(totalWork, cb, cb); | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 669 } | 
| 593 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 670 if (needData && cachedRevision != null) { | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 671 lastUserData = cachedRevision.userData; | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 672 lastRevisionRead = cachedRevision.revision; | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 673 assert lastUserData != null; | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 674 } | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 675 } | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 676 | 
| 520 
1ee452f31187
Experimental support for inverse direction history walking. Refactored/streamlined cancellation in HgLogCommand and down the stack
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
440diff
changeset | 677 // invoked only once per instance | 
| 593 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 678 public CachedRevision finish() { | 
| 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 679 CachedRevision rv = null; | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 680 if (lastUserData != null) { | 
| 594 
cc7b0c4dc993
Cache only in-memory revision representations
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
593diff
changeset | 681 if (lastUserData instanceof ByteArrayDataAccess) { | 
| 
cc7b0c4dc993
Cache only in-memory revision representations
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
593diff
changeset | 682 // it's safe to cache only in-memory revision texts, | 
| 
cc7b0c4dc993
Cache only in-memory revision representations
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
593diff
changeset | 683 // if lastUserData is merely a filter over file stream, | 
| 
cc7b0c4dc993
Cache only in-memory revision representations
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
593diff
changeset | 684 // we'd need to keep file open, and this is bad. | 
| 
cc7b0c4dc993
Cache only in-memory revision representations
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
593diff
changeset | 685 // XXX perhaps, wrap any DataAccess.byteArray into | 
| 
cc7b0c4dc993
Cache only in-memory revision representations
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
593diff
changeset | 686 // ByteArrayDataAccess? | 
| 
cc7b0c4dc993
Cache only in-memory revision representations
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
593diff
changeset | 687 rv = new CachedRevision(lastRevisionRead, lastUserData); | 
| 
cc7b0c4dc993
Cache only in-memory revision representations
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
593diff
changeset | 688 } else { | 
| 
cc7b0c4dc993
Cache only in-memory revision representations
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
593diff
changeset | 689 lastUserData.done(); | 
| 
cc7b0c4dc993
Cache only in-memory revision representations
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
593diff
changeset | 690 } | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 691 lastUserData = null; | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 692 } | 
| 520 
1ee452f31187
Experimental support for inverse direction history walking. Refactored/streamlined cancellation in HgLogCommand and down the stack
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
440diff
changeset | 693 if (lifecycleListener != null) { | 
| 
1ee452f31187
Experimental support for inverse direction history walking. Refactored/streamlined cancellation in HgLogCommand and down the stack
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
440diff
changeset | 694 lifecycleListener.finish(cb); | 
| 
1ee452f31187
Experimental support for inverse direction history walking. Refactored/streamlined cancellation in HgLogCommand and down the stack
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
440diff
changeset | 695 lifecycleListener = null; | 
| 
1ee452f31187
Experimental support for inverse direction history walking. Refactored/streamlined cancellation in HgLogCommand and down the stack
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
440diff
changeset | 696 cb = null; | 
| 
1ee452f31187
Experimental support for inverse direction history walking. Refactored/streamlined cancellation in HgLogCommand and down the stack
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
440diff
changeset | 697 | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 698 } | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 699 daIndex.done(); | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 700 if (daData != null) { | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 701 daData.done(); | 
| 520 
1ee452f31187
Experimental support for inverse direction history walking. Refactored/streamlined cancellation in HgLogCommand and down the stack
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
440diff
changeset | 702 daData = null; | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 703 } | 
| 593 
9619301a7bb9
Share last revision read between #iterate() invocations, to save revision rebuild efforts when few subsequent revisions are read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
585diff
changeset | 704 return rv; | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 705 } | 
| 584 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 706 | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 707 private void readHeaderRecord(int i) throws IOException { | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 708 if (inline && needData) { | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 709 // inspector reading data (though FilterDataAccess) may have affected index position | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 710 daIndex.seek(getIndexOffsetInt(i)); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 711 } | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 712 long l = daIndex.readLong(); // 0 | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 713 offset = i == 0 ? 0 : (l >>> 16); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 714 flags = (int) (l & 0x0FFFF); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 715 compressedLen = daIndex.readInt(); // +8 | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 716 actualLen = daIndex.readInt(); // +12 | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 717 baseRevision = daIndex.readInt(); // +16 | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 718 linkRevision = daIndex.readInt(); // +20 | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 719 parent1Revision = daIndex.readInt(); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 720 parent2Revision = daIndex.readInt(); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 721 // Hg has 32 bytes here, uses 20 for nodeid, and keeps 12 last bytes empty | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 722 daIndex.readBytes(nodeidBuf, 0, 20); // +32 | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 723 daIndex.skip(12); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 724 } | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 725 | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 726 private boolean isPatch(int i) { | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 727 return baseRevision != i; // the only way I found to tell if it's a patch | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 728 } | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 729 | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 730 private DataAccess getStoredData(int i) throws IOException { | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 731 DataAccess userDataAccess = null; | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 732 DataAccess streamDataAccess; | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 733 long streamOffset; | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 734 if (inline) { | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 735 streamOffset = getIndexOffsetInt(i) + REVLOGV1_RECORD_SIZE; | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 736 streamDataAccess = daIndex; | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 737 // don't need to do seek as it's actual position in the index stream, but it's safe to seek, just in case | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 738 daIndex.longSeek(streamOffset); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 739 } else { | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 740 streamOffset = offset; | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 741 streamDataAccess = daData; | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 742 daData.longSeek(streamOffset); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 743 } | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 744 if (streamDataAccess.isEmpty() || compressedLen == 0) { | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 745 userDataAccess = new DataAccess(); // empty | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 746 } else { | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 747 final byte firstByte = streamDataAccess.readByte(); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 748 if (firstByte == 0x78 /* 'x' */) { | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 749 inflater.reset(); | 
| 655 
bcbcc318f250
Performance: reuse unzip output buffer
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
644diff
changeset | 750 userDataAccess = new InflaterDataAccess(streamDataAccess, streamOffset, compressedLen, isPatch(i) ? -1 : actualLen, inflater, inflaterBuffer, inflaterOutBuffer); | 
| 584 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 751 } else if (firstByte == 0x75 /* 'u' */) { | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 752 userDataAccess = new FilterDataAccess(streamDataAccess, streamOffset+1, compressedLen-1); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 753 } else { | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 754 // XXX Python impl in fact throws exception when there's not 'x', 'u' or '0' but I don't see reason not to return data as is | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 755 // | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 756 // although firstByte is already read from the streamDataAccess, FilterDataAccess#readByte would seek to | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 757 // initial offset before first attempt to read a byte | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 758 userDataAccess = new FilterDataAccess(streamDataAccess, streamOffset, compressedLen); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 759 } | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 760 } | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 761 return userDataAccess; | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 762 } | 
| 263 
31f67be94e71
RevlogStream - reduce number of object instances, reuse when possible
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
258diff
changeset | 763 | 
| 520 
1ee452f31187
Experimental support for inverse direction history walking. Refactored/streamlined cancellation in HgLogCommand and down the stack
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
440diff
changeset | 764 // may be invoked few times per instance life | 
| 628 
6526d8adbc0f
Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
621diff
changeset | 765 public boolean range(int start, int end) throws IOException, HgRuntimeException { | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 766 int i; | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 767 // it (i.e. replace with i >= start) | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 768 if (needData && (i = getBaseRevision(start)) < start) { | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 769 // if lastRevisionRead in [baseRevision(start), start) can reuse lastUserData | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 770 // doesn't make sense to reuse if lastRevisionRead == start (too much to change in the cycle below). | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 771 if (lastRevisionRead != BAD_REVISION && i <= lastRevisionRead && lastRevisionRead < start) { | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 772 i = lastRevisionRead + 1; // start with first not-yet-read revision | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 773 } else { | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 774 if (lastUserData != null) { | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 775 lastUserData.done(); | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 776 lastUserData = null; | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 777 } | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 778 } | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 779 } else { | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 780 // don't need to clean lastUserData as it's always null when !needData | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 781 i = start; | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 782 } | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 783 | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 784 daIndex.seek(getIndexOffsetInt(i)); | 
| 258 
e5776067b3b8
Reduce number of objects instantiated on revlog read
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
243diff
changeset | 785 // | 
| 584 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 786 // reuse instance, do not normalize it as patches from the stream are unlikely to need it | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 787 final Patch patch = new Patch(false); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 788 // | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 789 if (needData && mergePatches && start-i > 2) { | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 790 // i+1 == start just reads lastUserData, i+2 == start applies one patch - not worth dedicated effort | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 791 Patch ultimatePatch = new Patch(true); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 792 for ( ; i < start; i++) { | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 793 readHeaderRecord(i); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 794 DataAccess userDataAccess = getStoredData(i); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 795 if (lastUserData == null) { | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 796 assert !isPatch(i); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 797 lastUserData = userDataAccess; | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 798 } else { | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 799 assert isPatch(i); // i < start and i == getBaseRevision() | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 800 patch.read(userDataAccess); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 801 userDataAccess.done(); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 802 // I assume empty patches are applied ok | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 803 ultimatePatch = ultimatePatch.apply(patch); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 804 patch.clear(); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 805 } | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 806 } | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 807 lastUserData.reset(); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 808 byte[] userData = ultimatePatch.apply(lastUserData, actualLen); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 809 ultimatePatch.clear(); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 810 lastUserData.done(); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 811 lastUserData = new ByteArrayDataAccess(userData); | 
| 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 812 } | 
| 263 
31f67be94e71
RevlogStream - reduce number of object instances, reuse when possible
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
258diff
changeset | 813 // | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 814 | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 815 for (; i <= end; i++ ) { | 
| 584 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 816 readHeaderRecord(i); | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 817 DataAccess userDataAccess = null; | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 818 if (needData) { | 
| 584 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 819 userDataAccess = getStoredData(i); | 
| 397 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 820 // userDataAccess is revision content, either complete revision, patch of a previous content, or an empty patch | 
| 584 
ed243b668502
Conditionally enable effective patch merge alternative for revlog reading
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
580diff
changeset | 821 if (isPatch(i)) { | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 822 // this is a patch | 
| 397 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 823 if (userDataAccess.isEmpty()) { | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 824 // Issue 22, empty patch to an empty base revision | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 825 // Issue 24, empty patch to non-empty base revision | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 826 // empty patch modifies nothing, use content of a previous revision (shall present - it's a patch here) | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 827 // | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 828 assert lastUserData.length() == actualLen; // with no patch, data size shall be the same | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 829 userDataAccess = lastUserData; | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 830 } else { | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 831 patch.read(userDataAccess); | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 832 userDataAccess.done(); | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 833 // | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 834 // it shall be reset at the end of prev iteration, when it got assigned from userDataAccess | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 835 // however, actual userDataAccess and lastUserData may share Inflater object, which needs to be reset | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 836 // Alternatively, userDataAccess.done() above may be responsible to reset Inflater (if it's InflaterDataAccess) | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 837 lastUserData.reset(); | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 838 // final long startMeasuring = System.currentTimeMillis(); // TIMING | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 839 byte[] userData = patch.apply(lastUserData, actualLen); | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 840 // applyTime += (System.currentTimeMillis() - startMeasuring); // TIMING | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 841 patch.clear(); // do not keep any reference, allow byte[] data to be gc'd | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 842 userDataAccess = new ByteArrayDataAccess(userData); | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 843 } | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 844 } | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 845 } else { | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 846 if (inline) { | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 847 daIndex.skip(compressedLen); | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 848 } | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 849 } | 
| 329 
694ebabb5cb3
Refactor revlog patch mechanism, towards patch merging
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 850 if (i >= start) { | 
| 264 
6bb5e7ed051a
Optimize memory usage (reduce number of objects instantiated) when pooling file names and nodeids during manifest parsing
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
263diff
changeset | 851 // final long startMeasuring = System.currentTimeMillis(); // TIMING | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 852 inspector.next(i, actualLen, baseRevision, linkRevision, parent1Revision, parent2Revision, nodeidBuf, userDataAccess); | 
| 264 
6bb5e7ed051a
Optimize memory usage (reduce number of objects instantiated) when pooling file names and nodeids during manifest parsing
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
263diff
changeset | 853 // inspectorTime += (System.currentTimeMillis() - startMeasuring); // TIMING | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 854 } | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 855 if (cb != null) { | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 856 if (cb.isStopped()) { | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 857 return false; | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 858 } | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 859 } | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 860 if (userDataAccess != null) { | 
| 263 
31f67be94e71
RevlogStream - reduce number of object instances, reuse when possible
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
258diff
changeset | 861 userDataAccess.reset(); // not sure this is necessary here, as lastUserData would get reset anyway before next use. | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 862 } | 
| 397 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 863 if (lastUserData != null && lastUserData != userDataAccess /* empty patch case, reuse of recent data in actual revision */) { | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 864 // release lastUserData only if we didn't reuse it in actual revision due to empty patch: | 
| 
5e95b0da26f2
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
377diff
changeset | 865 // empty patch means we have previous revision and didn't alter it with a patch, hence use lastUserData for userDataAccess above | 
| 263 
31f67be94e71
RevlogStream - reduce number of object instances, reuse when possible
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
258diff
changeset | 866 lastUserData.done(); | 
| 
31f67be94e71
RevlogStream - reduce number of object instances, reuse when possible
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
258diff
changeset | 867 } | 
| 
31f67be94e71
RevlogStream - reduce number of object instances, reuse when possible
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
258diff
changeset | 868 lastUserData = userDataAccess; | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 869 } | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 870 lastRevisionRead = end; | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 871 return true; | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 872 } | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 873 } | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 874 | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
223diff
changeset | 875 | 
| 77 
c677e1593919
Moved RevlogStream implementation into .internal
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
74diff
changeset | 876 public interface Inspector { | 
| 608 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 877 /** | 
| 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 878 * XXX boolean retVal to indicate whether to continue? | 
| 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 879 * | 
| 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 880 * Implementers shall not invoke DataAccess.done(), it's accomplished by #iterate at appropriate moment | 
| 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 881 * | 
| 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 882 * @param revisionIndex absolute index of revision in revlog being iterated | 
| 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 883 * @param actualLen length of the user data at this revision | 
| 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 884 * @param baseRevision last revision known to hold complete revision (other hold patches). | 
| 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 885 * if baseRevision != revisionIndex, data for this revision is a result of a sequence of patches | 
| 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 886 * @param linkRevision index of corresponding changeset revision | 
| 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 887 * @param parent1Revision index of first parent revision in this revlog, or {@link HgRepository#NO_REVISION} | 
| 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 888 * @param parent2Revision index of second parent revision in this revlog, or {@link HgRepository#NO_REVISION} | 
| 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 889 * @param nodeid 20-byte buffer, shared between invocations | 
| 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 890 * @param data access to revision content of actualLen size, or <code>null</code> if no data has been requested with | 
| 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 891 * {@link RevlogStream#iterate(int[], boolean, Inspector)} | 
| 
e1b29756f901
Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
607diff
changeset | 892 */ | 
| 628 
6526d8adbc0f
Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
621diff
changeset | 893 void next(int revisionIndex, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[/*20*/] nodeid, DataAccess data) throws HgRuntimeException; | 
| 3 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 894 } | 
| 539 
9edfd5a223b8
Commit: handle empty repository case
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
538diff
changeset | 895 | 
| 607 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 896 public interface Observer { | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 897 // notify observer of invalidate/reload event in the stream | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 898 public void reloaded(RevlogStream src); | 
| 
66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
606diff
changeset | 899 } | 
| 0 
dbd663faec1f
Basic changelog parsing
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 900 } | 
