comparison src/com/tmate/hgkit/ll/StatusCollector.java @ 64:19e9e220bf68

Convenient commands constitute hi-level API. org.tmatesoft namespace, GPL2 statement
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Fri, 21 Jan 2011 05:56:43 +0100
parents b771e94a4f7c
children 0e499fed9b3d
comparison
equal deleted inserted replaced
63:a47530a2ea12 64:19e9e220bf68
28 emptyFakeState.begin(-1, null); 28 emptyFakeState.begin(-1, null);
29 emptyFakeState.end(-1); 29 emptyFakeState.end(-1);
30 cache.put(-1, emptyFakeState); 30 cache.put(-1, emptyFakeState);
31 } 31 }
32 32
33 public HgRepository getRepo() {
34 return repo;
35 }
36
33 private ManifestRevisionInspector get(int rev) { 37 private ManifestRevisionInspector get(int rev) {
34 ManifestRevisionInspector i = cache.get(rev); 38 ManifestRevisionInspector i = cache.get(rev);
35 if (i == null) { 39 if (i == null) {
36 i = new ManifestRevisionInspector(rev, rev); 40 i = new ManifestRevisionInspector(rev, rev);
37 cache.put(rev, i); 41 cache.put(rev, i);
56 // if this assumption is wrong, fix this (lookup manifest revisions from changeset). 60 // if this assumption is wrong, fix this (lookup manifest revisions from changeset).
57 public void walk(int rev1, int rev2, Inspector inspector) { 61 public void walk(int rev1, int rev2, Inspector inspector) {
58 if (rev1 == rev2) { 62 if (rev1 == rev2) {
59 throw new IllegalArgumentException(); 63 throw new IllegalArgumentException();
60 } 64 }
65 if (inspector == null) {
66 throw new IllegalArgumentException();
67 }
68 if (inspector instanceof Record) {
69 ((Record) inspector).init(rev1, rev2, this);
70 }
61 // in fact, rev1 and rev2 are often next (or close) to each other, 71 // in fact, rev1 and rev2 are often next (or close) to each other,
62 // thus, we can optimize Manifest reads here (manifest.walk(rev1, rev2)) 72 // thus, we can optimize Manifest reads here (manifest.walk(rev1, rev2))
63
64 ManifestRevisionInspector r1, r2; 73 ManifestRevisionInspector r1, r2;
65 if (!cache.containsKey(rev1) && !cache.containsKey(rev2) && Math.abs(rev1 - rev2) < 5 /*subjective equivalent of 'close enough'*/) { 74 if (!cache.containsKey(rev1) && !cache.containsKey(rev2) && Math.abs(rev1 - rev2) < 5 /*subjective equivalent of 'close enough'*/) {
66 int minRev = rev1 < rev2 ? rev1 : rev2; 75 int minRev = rev1 < rev2 ? rev1 : rev2;
67 int maxRev = minRev == rev1 ? rev2 : rev1; 76 int maxRev = minRev == rev1 ? rev2 : rev1;
68 r1 = r2 = new ManifestRevisionInspector(minRev, maxRev); 77 r1 = r2 = new ManifestRevisionInspector(minRev, maxRev);
117 // XXX for r1..r2 status, only modified, added, removed (and perhaps, clean) make sense 126 // XXX for r1..r2 status, only modified, added, removed (and perhaps, clean) make sense
118 public static class Record implements Inspector { 127 public static class Record implements Inspector {
119 private List<String> modified, added, removed, clean, missing, unknown, ignored; 128 private List<String> modified, added, removed, clean, missing, unknown, ignored;
120 private Map<String, String> copied; 129 private Map<String, String> copied;
121 130
131 private int startRev, endRev;
132 private StatusCollector statusHelper;
133
134 // XXX StatusCollector may additionally initialize Record instance to speed lookup of changed file revisions
135 // here I need access to ManifestRevisionInspector via #raw(). Perhaps, non-static class (to get
136 // implicit reference to StatusCollector) may be better?
137 // Since users may want to reuse Record instance we've once created (and initialized), we need to
138 // ensure functionality is correct for each/any call (#walk checks instanceof Record and fixes it up)
139 // Perhaps, distinct helper (sc.getRevisionHelper().nodeid(fname)) would be better, just not clear
140 // how to supply [start..end] values there easily
141 /*package-local*/void init(int startRevision, int endRevision, StatusCollector self) {
142 startRev = startRevision;
143 endRev = endRevision;
144 statusHelper = self;
145 }
146
147 public Nodeid nodeidBeforeChange(String fname) {
148 if ((modified == null || !modified.contains(fname)) && (removed == null || !removed.contains(fname))) {
149 return null;
150 }
151 return statusHelper.raw(startRev).nodeid(startRev, fname);
152 }
153 public Nodeid nodeidAfterChange(String fname) {
154 if ((modified == null || !modified.contains(fname)) && (added == null || !added.contains(fname))) {
155 return null;
156 }
157 return statusHelper.raw(endRev).nodeid(endRev, fname);
158 }
159
122 public List<String> getModified() { 160 public List<String> getModified() {
123 return proper(modified); 161 return proper(modified);
124 } 162 }
125 163
126 public List<String> getAdded() { 164 public List<String> getAdded() {
206 l.add(s); 244 l.add(s);
207 return l; 245 return l;
208 } 246 }
209 } 247 }
210 248
249 // XXX in fact, indexed access brings more trouble than benefits, get rid of it? Distinct instance per revision is good enough
211 public /*XXX private, actually. Made public unless repo.statusLocal finds better place*/ static final class ManifestRevisionInspector implements HgManifest.Inspector { 250 public /*XXX private, actually. Made public unless repo.statusLocal finds better place*/ static final class ManifestRevisionInspector implements HgManifest.Inspector {
212 private final HashMap<String, Nodeid>[] idsMap; 251 private final HashMap<String, Nodeid>[] idsMap;
213 private final HashMap<String, String>[] flagsMap; 252 private final HashMap<String, String>[] flagsMap;
214 private final int baseRevision; 253 private final int baseRevision;
215 private int r = -1; // cursor 254 private int r = -1; // cursor