Mercurial > hg4j
comparison src/org/tmatesoft/hg/repo/Revlog.java @ 171:2c3e96674e2a
Towards outgoing changes - initial detection logic, get connected with remote repo stub
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 25 Mar 2011 00:05:52 +0100 |
parents | d5268ca7715b |
children | 9807bf8f3a9c |
comparison
equal
deleted
inserted
replaced
170:71ddbf8603e8 | 171:2c3e96674e2a |
---|---|
23 import java.nio.ByteBuffer; | 23 import java.nio.ByteBuffer; |
24 import java.util.Arrays; | 24 import java.util.Arrays; |
25 import java.util.Collection; | 25 import java.util.Collection; |
26 import java.util.Collections; | 26 import java.util.Collections; |
27 import java.util.HashMap; | 27 import java.util.HashMap; |
28 import java.util.HashSet; | |
28 import java.util.LinkedHashSet; | 29 import java.util.LinkedHashSet; |
30 import java.util.LinkedList; | |
31 import java.util.List; | |
29 import java.util.Map; | 32 import java.util.Map; |
30 import java.util.Set; | 33 import java.util.Set; |
31 | 34 |
32 import org.tmatesoft.hg.core.HgBadStateException; | 35 import org.tmatesoft.hg.core.HgBadStateException; |
33 import org.tmatesoft.hg.core.HgException; | 36 import org.tmatesoft.hg.core.HgException; |
197 * and yes, walker is not a proper name | 200 * and yes, walker is not a proper name |
198 */ | 201 */ |
199 public final class ParentWalker { | 202 public final class ParentWalker { |
200 private Map<Nodeid, Nodeid> firstParent; | 203 private Map<Nodeid, Nodeid> firstParent; |
201 private Map<Nodeid, Nodeid> secondParent; | 204 private Map<Nodeid, Nodeid> secondParent; |
202 private Set<Nodeid> allNodes; | 205 private final LinkedHashSet<Nodeid> allNodes = new LinkedHashSet<Nodeid>(); // childrenOf rely on ordering |
203 | 206 |
204 public ParentWalker() { | 207 public ParentWalker() { |
205 firstParent = secondParent = Collections.emptyMap(); | 208 firstParent = secondParent = Collections.emptyMap(); |
206 allNodes = Collections.emptySet(); | |
207 } | 209 } |
208 | 210 |
209 public void init() { | 211 public void init() { |
210 final RevlogStream stream = Revlog.this.content; | 212 final RevlogStream stream = Revlog.this.content; |
211 final int revisionCount = stream.revisionCount(); | 213 final int revisionCount = stream.revisionCount(); |
212 firstParent = new HashMap<Nodeid, Nodeid>(revisionCount); | 214 firstParent = new HashMap<Nodeid, Nodeid>(revisionCount); |
213 secondParent = new HashMap<Nodeid, Nodeid>(firstParent.size() >> 1); // assume branches/merges are less frequent | 215 secondParent = new HashMap<Nodeid, Nodeid>(firstParent.size() >> 1); // assume branches/merges are less frequent |
214 allNodes = new LinkedHashSet<Nodeid>(); | |
215 | 216 |
216 RevlogStream.Inspector insp = new RevlogStream.Inspector() { | 217 RevlogStream.Inspector insp = new RevlogStream.Inspector() { |
217 final Nodeid[] sequentialRevisionNodeids = new Nodeid[revisionCount]; | 218 final Nodeid[] sequentialRevisionNodeids = new Nodeid[revisionCount]; |
218 int ix = 0; | 219 int ix = 0; |
219 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess da) { | 220 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess da) { |
276 if (p2 != null) { | 277 if (p2 != null) { |
277 modified = c.add(p2) || modified; | 278 modified = c.add(p2) || modified; |
278 } | 279 } |
279 } | 280 } |
280 return modified; | 281 return modified; |
282 } | |
283 | |
284 // XXX alternative (and perhaps more reliable) approach would be to make a copy of allNodes and remove | |
285 // nodes, their parents and so on. | |
286 | |
287 // @return ordered collection of all children rooted at supplied nodes. Nodes shall not be descendants of each other! | |
288 public List<Nodeid> childrenOf(List<Nodeid> nodes) { | |
289 HashSet<Nodeid> parents = new HashSet<Nodeid>(); | |
290 LinkedHashSet<Nodeid> result = new LinkedHashSet<Nodeid>(); | |
291 LinkedList<Nodeid> orderedResult = new LinkedList<Nodeid>(); | |
292 for(Nodeid next : allNodes) { | |
293 // i assume allNodes is sorted, hence do not check any parents unless we hit any common known node first | |
294 if (nodes.contains(next)) { | |
295 parents.add(next); | |
296 } else { | |
297 if (parents.isEmpty()) { | |
298 // didn't scroll up to any known yet | |
299 continue; | |
300 } | |
301 // record each and every node reported after first common known node hit | |
302 orderedResult.addLast(next); | |
303 if (parents.contains(firstParent(next)) || parents.contains(secondParent(next))) { | |
304 result.add(next); | |
305 parents.add(next); // to find next's children | |
306 } | |
307 } | |
308 } | |
309 // leave only those of interest in ordered sequence | |
310 orderedResult.retainAll(result); | |
311 return orderedResult; | |
281 } | 312 } |
282 } | 313 } |
283 | 314 |
284 protected static class ContentPipe implements RevlogStream.Inspector, CancelSupport { | 315 protected static class ContentPipe implements RevlogStream.Inspector, CancelSupport { |
285 private final ByteChannel sink; | 316 private final ByteChannel sink; |