annotate src/org/tmatesoft/hg/repo/HgManifest.java @ 324:283b294d1079

Explore alternatives to access file-changelog combined history
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Mon, 03 Oct 2011 06:47:20 +0200
parents ac38e75c9e8e
children d42a45a2c9d6
rev   line source
13
df8c67f3006a Basic manifest parsing to analyze what's in there
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
1 /*
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 28
diff changeset
2 * Copyright (c) 2010-2011 TMate Software Ltd
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 28
diff changeset
3 *
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 28
diff 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: 28
diff 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: 28
diff changeset
6 * the Free Software Foundation; version 2 of the License.
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 28
diff changeset
7 *
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 28
diff 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: 28
diff 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: 28
diff changeset
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 28
diff changeset
11 * GNU General Public License for more details.
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 28
diff changeset
12 *
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 28
diff changeset
13 * For information on how to redistribute this software under
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 28
diff 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: 77
diff changeset
15 * contact TMate Software at support@hg4j.com
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
16 */
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 28
diff changeset
17 package org.tmatesoft.hg.repo;
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 28
diff changeset
18
218
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
19 import static org.tmatesoft.hg.repo.HgRepository.TIP;
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
20
232
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
21 import java.io.ByteArrayOutputStream;
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 102
diff changeset
22 import java.io.IOException;
218
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
23 import java.util.ArrayList;
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
24 import java.util.Arrays;
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 102
diff changeset
25
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 102
diff changeset
26 import org.tmatesoft.hg.core.HgBadStateException;
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 28
diff changeset
27 import org.tmatesoft.hg.core.Nodeid;
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 102
diff changeset
28 import org.tmatesoft.hg.internal.DataAccess;
266
0a2f445de774 Improve manifest parsing: reduce number of arrays instantiated for Nodeid
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 264
diff changeset
29 import org.tmatesoft.hg.internal.DigestHelper;
320
678e326fd27c Issue 15: Exception accessing oddly named file from history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 313
diff changeset
30 import org.tmatesoft.hg.internal.EncodingHelper;
232
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
31 import org.tmatesoft.hg.internal.Experimental;
312
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
32 import org.tmatesoft.hg.internal.IterateControlMediator;
218
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
33 import org.tmatesoft.hg.internal.Lifecycle;
304
85b8efde5586 Use memory-friendly set implementation to canonicalize filenames and nodeids
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
34 import org.tmatesoft.hg.internal.Pool2;
77
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
35 import org.tmatesoft.hg.internal.RevlogStream;
312
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
36 import org.tmatesoft.hg.util.CancelSupport;
232
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
37 import org.tmatesoft.hg.util.Path;
312
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
38 import org.tmatesoft.hg.util.ProgressSupport;
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 28
diff changeset
39
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
40
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
41 /**
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
42 *
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 28
diff changeset
43 * @author Artem Tikhomirov
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 28
diff changeset
44 * @author TMate Software Ltd.
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
45 */
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
46 public class HgManifest extends Revlog {
218
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
47 private RevisionMapper revisionMap;
285
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
48
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
49 public enum Flags {
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
50 Exec, Link;
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
51
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
52 static Flags parse(String flags) {
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
53 if ("x".equalsIgnoreCase(flags)) {
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
54 return Exec;
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
55 }
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
56 if ("l".equalsIgnoreCase(flags)) {
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
57 return Link;
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
58 }
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
59 if (flags == null) {
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
60 return null;
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
61 }
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
62 throw new IllegalStateException(flags);
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
63 }
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
64
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
65 static Flags parse(byte[] data, int start, int length) {
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
66 if (length == 0) {
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
67 return null;
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
68 }
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
69 if (length == 1) {
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
70 if (data[start] == 'x') {
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
71 return Exec;
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
72 }
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
73 if (data[start] == 'l') {
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
74 return Link;
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
75 }
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
76 // FALL THROUGH
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
77 }
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
78 throw new IllegalStateException(new String(data, start, length));
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
79 }
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
80
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
81 String nativeString() {
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
82 if (this == Exec) {
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
83 return "x";
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
84 }
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
85 if (this == Link) {
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
86 return "l";
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
87 }
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
88 throw new IllegalStateException(toString());
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
89 }
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
90 }
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
91
13
df8c67f3006a Basic manifest parsing to analyze what's in there
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
92 /*package-local*/ HgManifest(HgRepository hgRepo, RevlogStream content) {
21
e929cecae4e1 Refactor to move revlog content to base class
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 20
diff changeset
93 super(hgRepo, content);
13
df8c67f3006a Basic manifest parsing to analyze what's in there
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
94 }
df8c67f3006a Basic manifest parsing to analyze what's in there
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
95
218
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
96 /**
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
97 *
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
98 * @param start changelog (not manifest!) revision to begin with
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
99 * @param end changelog (not manifest!) revision to stop, inclusive.
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
100 * @param inspector can't be <code>null</code>
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
101 */
19
40532cdc92fc Inspector (visitor) for manifest
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 16
diff changeset
102 public void walk(int start, int end, final Inspector inspector) {
196
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
103 if (inspector == null) {
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
104 throw new IllegalArgumentException();
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
105 }
218
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
106 int start0 = fromChangelog(start);
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
107 int end0 = fromChangelog(end);
300
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 285
diff changeset
108 if (end0 < start0) {
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 285
diff changeset
109 // there are tool-constructed repositories that got order of changeset revisions completely different from that of manifest
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 285
diff changeset
110 int x = end0;
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 285
diff changeset
111 end0 = start0;
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 285
diff changeset
112 start0 = x;
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 285
diff changeset
113 }
218
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
114 content.iterate(start0, end0, true, new ManifestParser(inspector));
19
40532cdc92fc Inspector (visitor) for manifest
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 16
diff changeset
115 }
218
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
116
254
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
117 /**
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
118 * "Sparse" iteration of the manifest
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
119 *
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
120 * @param inspector
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
121 * @param localRevisions local changeset revisions to visit
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
122 */
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
123 public void walk(final Inspector inspector, int... localRevisions) {
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
124 if (inspector == null || localRevisions == null) {
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
125 throw new IllegalArgumentException();
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
126 }
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
127 int[] manifestLocalRevs = new int[localRevisions.length];
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
128 boolean needsSort = false;
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
129 for (int i = 0; i < localRevisions.length; i++) {
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
130 final int manifestLocalRev = fromChangelog(localRevisions[i]);
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
131 manifestLocalRevs[i] = manifestLocalRev;
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
132 if (i > 0 && manifestLocalRevs[i-1] > manifestLocalRev) {
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
133 needsSort = true;
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
134 }
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
135 }
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
136 if (needsSort) {
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
137 Arrays.sort(manifestLocalRevs);
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
138 }
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
139 content.iterate(manifestLocalRevs, true, new ManifestParser(inspector));
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
140 }
a620f0663a37 Collect tags for a file - improve performance of 'sparse' manifest reads
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 232
diff changeset
141
232
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
142 // manifest revision number that corresponds to the given changeset
218
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
143 /*package-local*/ int fromChangelog(int revisionNumber) {
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
144 if (HgInternals.wrongLocalRevision(revisionNumber)) {
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
145 throw new IllegalArgumentException(String.valueOf(revisionNumber));
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
146 }
257
f39fb6b3cc76 Handle revision constants correctly
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 254
diff changeset
147 if (revisionNumber == HgRepository.WORKING_COPY || revisionNumber == HgRepository.BAD_REVISION) {
f39fb6b3cc76 Handle revision constants correctly
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 254
diff changeset
148 throw new IllegalArgumentException("Can't use constants like WORKING_COPY or BAD_REVISION");
f39fb6b3cc76 Handle revision constants correctly
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 254
diff changeset
149 }
f39fb6b3cc76 Handle revision constants correctly
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 254
diff changeset
150 // revisionNumber == TIP is processed by RevisionMapper
218
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
151 if (revisionMap == null) {
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
152 revisionMap = new RevisionMapper(getRepo());
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
153 content.iterate(0, TIP, false, revisionMap);
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
154 }
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
155 return revisionMap.at(revisionNumber);
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
156 }
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
157
232
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
158 /**
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
159 * Extracts file revision as it was known at the time of given changeset.
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
160 *
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
161 * @param revisionNumber local changeset index
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
162 * @param file path to file in question
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
163 * @return file revision or <code>null</code> if manifest at specified revision doesn't list such file
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
164 */
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
165 @Experimental(reason="Perhaps, HgDataFile shall own this method")
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
166 public Nodeid getFileRevision(int revisionNumber, final Path file) {
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
167 int rev = fromChangelog(revisionNumber);
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
168 final Nodeid[] rv = new Nodeid[] { null };
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
169 content.iterate(rev, rev, true, new RevlogStream.Inspector() {
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
170
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
171 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) {
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
172 ByteArrayOutputStream bos = new ByteArrayOutputStream();
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
173 try {
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
174 byte b;
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
175 while (!data.isEmpty() && (b = data.readByte()) != '\n') {
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
176 if (b != 0) {
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
177 bos.write(b);
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
178 } else {
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
179 String fname = new String(bos.toByteArray());
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
180 bos.reset();
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
181 if (file.toString().equals(fname)) {
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
182 byte[] nid = new byte[40];
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
183 data.readBytes(nid, 0, 40);
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
184 rv[0] = Nodeid.fromAscii(nid, 0, 40);
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
185 break;
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
186 }
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
187 // else skip to the end of line
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
188 while (!data.isEmpty() && (b = data.readByte()) != '\n')
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
189 ;
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
190 }
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
191 }
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
192 } catch (IOException ex) {
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
193 throw new HgBadStateException(ex);
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
194 }
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
195 }
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
196 });
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
197 return rv[0];
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
198 }
b7347daa50e3 Allow to cat a file with changeset revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 222
diff changeset
199
19
40532cdc92fc Inspector (visitor) for manifest
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 16
diff changeset
200 public interface Inspector {
222
373e07cd3991 Due to discrepancy in manifest and changelor indexes, wrong manifest revisions got cached and compared
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 220
diff changeset
201 boolean begin(int mainfestRevision, Nodeid nid, int changelogRevision);
285
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
202 /**
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
203 * @deprecated switch to {@link Inspector2#next(Nodeid, Path, Flags)}
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
204 */
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
205 @Deprecated
19
40532cdc92fc Inspector (visitor) for manifest
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 16
diff changeset
206 boolean next(Nodeid nid, String fname, String flags);
222
373e07cd3991 Due to discrepancy in manifest and changelor indexes, wrong manifest revisions got cached and compared
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 220
diff changeset
207 boolean end(int manifestRevision);
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
208 }
267
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
209
285
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
210 @Experimental(reason="Explore Path alternative for filenames and enum for flags")
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
211 public interface Inspector2 extends Inspector {
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
212 boolean next(Nodeid nid, Path fname, Flags flags);
267
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
213 }
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
214
268
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
215 /**
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
216 * When Pool uses Strings directly,
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
217 * ManifestParser creates new String instance with new char[] value, and does byte->char conversion.
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
218 * For cpython repo, walk(0..10k), there are over 16 million filenames, of them only 3020 unique.
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
219 * This means there are 15.9 million useless char[] instances and byte->char conversions
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
220 *
285
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
221 * When String (Path) is wrapped into {@link PathProxy}, there's extra overhead of byte[] representation
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
222 * of the String, but these are only for unique Strings (Paths) (3020 in the example above). Besides, I save
268
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
223 * useless char[] and byte->char conversions.
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
224 */
285
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
225 private static class PathProxy {
267
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
226 private byte[] data;
268
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
227 private int start;
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
228 private final int hash, length;
285
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
229 private Path result;
267
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
230
285
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
231 public PathProxy(byte[] data, int start, int length) {
267
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
232 this.data = data;
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
233 this.start = start;
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
234 this.length = length;
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
235
268
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
236 // copy from String.hashCode(). In fact, not necessarily match result of String(data).hashCode
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
237 // just need some nice algorithm here
267
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
238 int h = 0;
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
239 byte[] d = data;
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
240 for (int i = 0, off = start, len = length; i < len; i++) {
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
241 h = 31 * h + d[off++];
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
242 }
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
243 hash = h;
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
244 }
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
245
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
246 @Override
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
247 public boolean equals(Object obj) {
285
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
248 if (false == obj instanceof PathProxy) {
267
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
249 return false;
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
250 }
285
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
251 PathProxy o = (PathProxy) obj;
267
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
252 if (o.result != null && result != null) {
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
253 return result.equals(o.result);
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
254 }
268
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
255 if (o.length != length || o.hash != hash) {
267
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
256 return false;
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
257 }
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
258 for (int i = 0, x = o.start, y = start; i < length; i++) {
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
259 if (o.data[x++] != data[y++]) {
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
260 return false;
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
261 }
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
262 }
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
263 return true;
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
264 }
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
265 @Override
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
266 public int hashCode() {
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
267 return hash;
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
268 }
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
269
285
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
270 public Path freeze() {
267
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
271 if (result == null) {
320
678e326fd27c Issue 15: Exception accessing oddly named file from history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 313
diff changeset
272 result = Path.create(EncodingHelper.fromManifest(data, start, length));
268
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
273 // release reference to bigger data array, make a copy of relevant part only
285
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
274 // use original bytes, not those from String above to avoid cache misses due to different encodings
268
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
275 byte[] d = new byte[length];
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
276 System.arraycopy(data, start, d, 0, length);
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
277 data = d;
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
278 start = 0;
267
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
279 }
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
280 return result;
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
281 }
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
282 }
196
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
283
312
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
284 private static class ManifestParser implements RevlogStream.Inspector, Lifecycle {
196
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
285 private final Inspector inspector;
285
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
286 private final Inspector2 inspector2;
304
85b8efde5586 Use memory-friendly set implementation to canonicalize filenames and nodeids
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
287 private Pool2<Nodeid> nodeidPool, thisRevPool;
85b8efde5586 Use memory-friendly set implementation to canonicalize filenames and nodeids
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
288 private final Pool2<PathProxy> fnamePool;
266
0a2f445de774 Improve manifest parsing: reduce number of arrays instantiated for Nodeid
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 264
diff changeset
289 private byte[] nodeidLookupBuffer = new byte[20]; // get reassigned each time new Nodeid is added to pool
312
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
290 private final ProgressSupport progressHelper;
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
291 private IterateControlMediator iterateControl;
262
3dcd3dd90c77 Improve manifest parsing: decode bytes to chars once, minimize arraycopy on String instantiation, keep set of file revisions from previous manifest only
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 257
diff changeset
292
196
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
293 public ManifestParser(Inspector delegate) {
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
294 assert delegate != null;
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
295 inspector = delegate;
285
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
296 inspector2 = delegate instanceof Inspector2 ? (Inspector2) delegate : null;
304
85b8efde5586 Use memory-friendly set implementation to canonicalize filenames and nodeids
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
297 nodeidPool = new Pool2<Nodeid>();
85b8efde5586 Use memory-friendly set implementation to canonicalize filenames and nodeids
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
298 fnamePool = new Pool2<PathProxy>();
85b8efde5586 Use memory-friendly set implementation to canonicalize filenames and nodeids
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
299 thisRevPool = new Pool2<Nodeid>();
312
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
300 progressHelper = ProgressSupport.Factory.get(delegate);
196
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
301 }
268
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
302
196
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
303 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess da) {
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
304 try {
312
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
305 if (!inspector.begin(revisionNumber, new Nodeid(nodeid, true), linkRevision)) {
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
306 iterateControl.stop();
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
307 return;
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
308 }
285
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
309 Path fname = null;
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
310 Flags flags = null;
196
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
311 Nodeid nid = null;
267
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
312 int i;
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
313 byte[] data = da.byteArray();
312
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
314 for (i = 0; i < actualLen; i++) {
267
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
315 int x = i;
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
316 for( ; data[i] != '\n' && i < actualLen; i++) {
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
317 if (fname == null && data[i] == 0) {
285
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
318 PathProxy px = fnamePool.unify(new PathProxy(data, x, i - x));
268
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
319 // if (cached = fnamePool.unify(px))== px then cacheMiss, else cacheHit
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
320 // cpython 0..10k: hits: 15 989 152, misses: 3020
c5980f287cc4 Use StringProxy when parsing manifest to minimize number of useless conversions and array instances
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 267
diff changeset
321 fname = px.freeze();
267
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
322 x = i+1;
196
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
323 }
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
324 }
267
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
325 if (i < actualLen) {
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
326 assert data[i] == '\n';
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
327 int nodeidLen = i - x < 40 ? i-x : 40; // if > 40, there are flags
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
328 DigestHelper.ascii2bin(data, x, nodeidLen, nodeidLookupBuffer); // ignore return value as it's unlikely to have NULL in manifest
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
329 nid = new Nodeid(nodeidLookupBuffer, false); // this Nodeid is for pool lookup only, mock object
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
330 Nodeid cached = nodeidPool.unify(nid);
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
331 if (cached == nid) {
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
332 // buffer now belongs to the cached nodeid
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
333 nodeidLookupBuffer = new byte[20];
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
334 } else {
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
335 nid = cached; // use existing version, discard the lookup object
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
336 } // for cpython 0..10k, cache hits are 15 973 301, vs 18871 misses.
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
337 thisRevPool.record(nid); // memorize revision for the next iteration.
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
338 if (nodeidLen + x < i) {
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
339 // 'x' and 'l' for executable bits and symlinks?
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
340 // hg --debug manifest shows 644 for each regular file in my repo
285
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
341 // for cpython 0..10k, there are 4361062 flag checks, and there's only 1 unique flag
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
342 flags = Flags.parse(data, x + nodeidLen, i-x-nodeidLen);
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
343 } else {
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
344 flags = null;
267
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
345 }
312
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
346 boolean good2go;
285
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
347 if (inspector2 == null) {
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
348 String flagString = flags == null ? null : flags.nativeString();
312
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
349 good2go = inspector.next(nid, fname.toString(), flagString);
285
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
350 } else {
312
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
351 good2go = inspector2.next(nid, fname, flags);
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
352 }
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
353 if (!good2go) {
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
354 iterateControl.stop();
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
355 return;
285
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
356 }
267
ec921ef0628e Revert manifest parser changes - no single string and back to HashMap Pool
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 266
diff changeset
357 }
196
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
358 nid = null;
285
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
359 fname = null;
6dbbc53fc46d Use Path instead of plain String for manifest file names
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 268
diff changeset
360 flags = null;
196
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
361 }
312
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
362 if (!inspector.end(revisionNumber)) {
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
363 iterateControl.stop();
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
364 return;
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
365 }
262
3dcd3dd90c77 Improve manifest parsing: decode bytes to chars once, minimize arraycopy on String instantiation, keep set of file revisions from previous manifest only
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 257
diff changeset
366 //
3dcd3dd90c77 Improve manifest parsing: decode bytes to chars once, minimize arraycopy on String instantiation, keep set of file revisions from previous manifest only
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 257
diff changeset
367 // keep only actual file revisions, found at this version
3dcd3dd90c77 Improve manifest parsing: decode bytes to chars once, minimize arraycopy on String instantiation, keep set of file revisions from previous manifest only
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 257
diff changeset
368 // (next manifest is likely to refer to most of them, although in specific cases
3dcd3dd90c77 Improve manifest parsing: decode bytes to chars once, minimize arraycopy on String instantiation, keep set of file revisions from previous manifest only
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 257
diff changeset
369 // like commit in another branch a lot may be useless)
3dcd3dd90c77 Improve manifest parsing: decode bytes to chars once, minimize arraycopy on String instantiation, keep set of file revisions from previous manifest only
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 257
diff changeset
370 nodeidPool.clear();
304
85b8efde5586 Use memory-friendly set implementation to canonicalize filenames and nodeids
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
371 Pool2<Nodeid> t = nodeidPool;
262
3dcd3dd90c77 Improve manifest parsing: decode bytes to chars once, minimize arraycopy on String instantiation, keep set of file revisions from previous manifest only
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 257
diff changeset
372 nodeidPool = thisRevPool;
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: 262
diff changeset
373 thisRevPool = t;
313
c1e3c18fd2f2 Test manifest cancellation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 312
diff changeset
374 iterateControl.checkCancelled();
312
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
375 progressHelper.worked(1);
196
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
376 } catch (IOException ex) {
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
377 throw new HgBadStateException(ex);
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
378 }
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
379 }
312
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
380
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
381 public void start(int count, Callback callback, Object token) {
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
382 CancelSupport cs = CancelSupport.Factory.get(inspector, null);
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
383 iterateControl = new IterateControlMediator(cs, callback);
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
384 progressHelper.start(count);
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
385 }
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
386
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
387 public void finish(Object token) {
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
388 progressHelper.done();
f9f3e9b67ccc Facilitate cancellation and progress reporting in changelog and manifest iterations
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 304
diff changeset
389 }
196
e2115da4cf6a Pool objects to avoid memory polution with duplicates
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 157
diff changeset
390 }
218
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
391
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
392 private static class RevisionMapper implements RevlogStream.Inspector, Lifecycle {
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
393
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
394 private final int changelogRevisions;
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
395 private int[] changelog2manifest;
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
396 private final HgRepository repo;
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
397
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
398 public RevisionMapper(HgRepository hgRepo) {
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
399 repo = hgRepo;
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
400 changelogRevisions = repo.getChangelog().getRevisionCount();
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
401 }
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
402
257
f39fb6b3cc76 Handle revision constants correctly
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 254
diff changeset
403 // respects TIP
218
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
404 public int at(int revisionNumber) {
257
f39fb6b3cc76 Handle revision constants correctly
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 254
diff changeset
405 if (revisionNumber == TIP) {
f39fb6b3cc76 Handle revision constants correctly
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 254
diff changeset
406 revisionNumber = changelogRevisions - 1;
f39fb6b3cc76 Handle revision constants correctly
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 254
diff changeset
407 }
218
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
408 if (changelog2manifest != null) {
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
409 return changelog2manifest[revisionNumber];
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
410 }
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
411 return revisionNumber;
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
412 }
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
413
324
283b294d1079 Explore alternatives to access file-changelog combined history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 321
diff changeset
414 // XXX likely can be replaced with Revlog.RevisionInspector
218
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
415 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) {
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
416 if (changelog2manifest != null) {
220
8de327242aa0 Basic information about branches
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 218
diff changeset
417 // next assertion is not an error, rather assumption check, which is too development-related to be explicit exception -
8de327242aa0 Basic information about branches
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 218
diff changeset
418 // I just wonder if there are manifests that have two entries pointing to single changeset. It seems unrealistic, though -
8de327242aa0 Basic information about branches
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 218
diff changeset
419 // changeset records one and only one manifest nodeid
8de327242aa0 Basic information about branches
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 218
diff changeset
420 assert changelog2manifest[linkRevision] == -1 : String.format("revision:%d, link:%d, already linked to revision:%d", revisionNumber, linkRevision, changelog2manifest[linkRevision]);
218
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
421 changelog2manifest[linkRevision] = revisionNumber;
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
422 } else {
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
423 if (revisionNumber != linkRevision) {
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
424 changelog2manifest = new int[changelogRevisions];
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
425 Arrays.fill(changelog2manifest, -1);
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
426 for (int i = 0; i < revisionNumber; changelog2manifest[i] = i, i++)
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
427 ;
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
428 changelog2manifest[linkRevision] = revisionNumber;
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
429 }
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
430 }
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
431 }
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
432
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
433 public void start(int count, Callback callback, Object token) {
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
434 if (count != changelogRevisions) {
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
435 assert count < changelogRevisions; // no idea what to do if manifest has more revisions than changelog
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
436 // the way how manifest may contain more revisions than changelog, as I can imagine, is a result of
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
437 // some kind of an import tool (e.g. from SVN or CVS), that creates manifest and changelog independently.
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
438 // Note, it's pure guess, I didn't see such repository yet (although the way manifest revisions
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
439 // in cpython repo are numbered makes me think aforementioned way)
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
440 changelog2manifest = new int[changelogRevisions];
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
441 Arrays.fill(changelog2manifest, -1);
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
442 }
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
443 }
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
444
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
445 public void finish(Object token) {
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
446 if (changelog2manifest == null) {
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
447 return;
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
448 }
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
449 // I assume there'd be not too many revisions we don't know manifest of
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
450 ArrayList<Integer> undefinedChangelogRevision = new ArrayList<Integer>();
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
451 for (int i = 0; i < changelog2manifest.length; i++) {
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
452 if (changelog2manifest[i] == -1) {
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
453 undefinedChangelogRevision.add(i);
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
454 }
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
455 }
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
456 for (int u : undefinedChangelogRevision) {
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
457 Nodeid manifest = repo.getChangelog().range(u, u).get(0).manifest();
220
8de327242aa0 Basic information about branches
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 218
diff changeset
458 // FIXME calculate those missing effectively (e.g. cache and sort nodeids to speed lookup
218
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
459 // right away in the #next (may refactor ParentWalker's sequential and sorted into dedicated helper and reuse here)
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
460 changelog2manifest[u] = repo.getManifest().getLocalRevision(manifest);
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
461 }
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
462 }
047b1dec7a04 Issue 7: Correctly handle manifest and changelog with different number of (or non-matching) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 196
diff changeset
463 }
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
464 }