comparison src/org/tmatesoft/hg/core/HgChangeset.java @ 195:c9b305df0b89

Optimization: use ParentWalker to get changeset's parents, if possible. Do not keep duplicating nodeids and strings in manifest revisions
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Fri, 15 Apr 2011 05:17:44 +0200
parents ba2bf656f00f
children e2115da4cf6a
comparison
equal deleted inserted replaced
194:344e8d7e4d6e 195:c9b305df0b89
14 * the terms of a license other than GNU General Public License 14 * the terms of a license other than GNU General Public License
15 * contact TMate Software at support@hg4j.com 15 * contact TMate Software at support@hg4j.com
16 */ 16 */
17 package org.tmatesoft.hg.core; 17 package org.tmatesoft.hg.core;
18 18
19 import static org.tmatesoft.hg.core.Nodeid.NULL;
20
19 import java.util.ArrayList; 21 import java.util.ArrayList;
20 import java.util.Collections; 22 import java.util.Collections;
21 import java.util.List; 23 import java.util.List;
22 24
23 import org.tmatesoft.hg.core.HgLogCommand.FileRevision; 25 import org.tmatesoft.hg.core.HgLogCommand.FileRevision;
24 import org.tmatesoft.hg.repo.HgChangelog.RawChangeset; 26 import org.tmatesoft.hg.repo.HgChangelog.RawChangeset;
27 import org.tmatesoft.hg.repo.HgChangelog;
25 import org.tmatesoft.hg.repo.HgRepository; 28 import org.tmatesoft.hg.repo.HgRepository;
26 import org.tmatesoft.hg.repo.HgStatusCollector; 29 import org.tmatesoft.hg.repo.HgStatusCollector;
27 import org.tmatesoft.hg.util.Path; 30 import org.tmatesoft.hg.util.Path;
28 31
29 32
37 */ 40 */
38 public class HgChangeset implements Cloneable { 41 public class HgChangeset implements Cloneable {
39 private final HgStatusCollector statusHelper; 42 private final HgStatusCollector statusHelper;
40 private final Path.Source pathHelper; 43 private final Path.Source pathHelper;
41 44
45 private HgChangelog.ParentWalker parentHelper;
46
42 // 47 //
43 private RawChangeset changeset; 48 private RawChangeset changeset;
44 private Nodeid nodeid; 49 private Nodeid nodeid;
45 50
46 // 51 //
47 private List<FileRevision> modifiedFiles, addedFiles; 52 private List<FileRevision> modifiedFiles, addedFiles;
48 private List<Path> deletedFiles; 53 private List<Path> deletedFiles;
49 private int revNumber; 54 private int revNumber;
55 private byte[] parent1, parent2;
50 56
51 // XXX consider CommandContext with StatusCollector, PathPool etc. Commands optionally get CC through a cons or create new 57 // XXX consider CommandContext with StatusCollector, PathPool etc. Commands optionally get CC through a cons or create new
52 // and pass it around 58 // and pass it around
53 /*package-local*/HgChangeset(HgStatusCollector statusCollector, Path.Source pathFactory) { 59 /*package-local*/HgChangeset(HgStatusCollector statusCollector, Path.Source pathFactory) {
54 statusHelper = statusCollector; 60 statusHelper = statusCollector;
55 pathHelper = pathFactory; 61 pathHelper = pathFactory;
56 } 62 }
57 63
58 /*package-local*/ 64 /*package-local*/ void init(int localRevNumber, Nodeid nid, RawChangeset rawChangeset) {
59 void init(int localRevNumber, Nodeid nid, RawChangeset rawChangeset) {
60 revNumber = localRevNumber; 65 revNumber = localRevNumber;
61 nodeid = nid; 66 nodeid = nid;
62 changeset = rawChangeset; 67 changeset = rawChangeset;
63 modifiedFiles = addedFiles = null; 68 modifiedFiles = addedFiles = null;
64 deletedFiles = null; 69 deletedFiles = null;
65 } 70 parent1 = parent2 = null;
71 // keep references to parentHelper, statusHelper and pathHelper
72 }
73
74 /*package-local*/ void setParentHelper(HgChangelog.ParentWalker pw) {
75 parentHelper = pw;
76 if (parentHelper != null) {
77 if (parentHelper.getRepo() != statusHelper.getRepo()) {
78 throw new IllegalArgumentException();
79 }
80 }
81 }
82
66 public int getRevision() { 83 public int getRevision() {
67 return revNumber; 84 return revNumber;
68 } 85 }
69 public Nodeid getNodeid() { 86 public Nodeid getNodeid() {
70 return nodeid; 87 return nodeid;
117 } 134 }
118 return deletedFiles; 135 return deletedFiles;
119 } 136 }
120 137
121 public boolean isMerge() { 138 public boolean isMerge() {
122 return !Nodeid.NULL.equals(getSecondParentRevision()); 139 // p1 == -1 and p2 != -1 is legitimate case
140 return !NULL.equals(getFirstParentRevision()) && !NULL.equals(getSecondParentRevision());
123 } 141 }
124 142
125 public Nodeid getFirstParentRevision() { 143 public Nodeid getFirstParentRevision() {
126 // XXX may read once for both p1 and p2 144 if (parentHelper != null) {
127 // or use ParentWalker to minimize reads even more. 145 return parentHelper.safeFirstParent(nodeid);
128 byte[] p1 = new byte[20]; 146 }
129 statusHelper.getRepo().getChangelog().parents(revNumber, new int[2], p1, null); 147 // read once for both p1 and p2
130 return Nodeid.fromBinary(p1, 0); 148 if (parent1 == null) {
149 parent1 = new byte[20];
150 parent2 = new byte[20];
151 statusHelper.getRepo().getChangelog().parents(revNumber, new int[2], parent1, parent2);
152 }
153 return Nodeid.fromBinary(parent1, 0);
131 } 154 }
132 155
133 public Nodeid getSecondParentRevision() { 156 public Nodeid getSecondParentRevision() {
134 byte[] p2 = new byte[20]; 157 if (parentHelper != null) {
135 statusHelper.getRepo().getChangelog().parents(revNumber, new int[2], null, p2); 158 return parentHelper.safeSecondParent(nodeid);
136 return Nodeid.fromBinary(p2, 0); 159 }
160 if (parent2 == null) {
161 parent1 = new byte[20];
162 parent2 = new byte[20];
163 statusHelper.getRepo().getChangelog().parents(revNumber, new int[2], parent1, parent2);
164 }
165 return Nodeid.fromBinary(parent2, 0);
137 } 166 }
138 167
139 @Override 168 @Override
140 public HgChangeset clone() { 169 public HgChangeset clone() {
141 try { 170 try {