comparison src/org/tmatesoft/hg/repo/HgBranches.java @ 340:a54bfe0db959

IAE using stale data from branchheads file (invalid due to repository rollback)
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Thu, 17 Nov 2011 06:16:20 +0100
parents 8952f89be195
children a0864b2892cd
comparison
equal deleted inserted replaced
339:863356c2847e 340:a54bfe0db959
52 52
53 HgBranches(HgRepository hgRepo) { 53 HgBranches(HgRepository hgRepo) {
54 repo = hgRepo; 54 repo = hgRepo;
55 } 55 }
56 56
57 private int readCache() { 57 private int readCache() /*XXX throws parse errors, e.g. may fail with NumberFormatException */{
58 File branchheadsCache = getCacheFile(); 58 File branchheadsCache = getCacheFile();
59 int lastInCache = -1; 59 int lastInCache = -1;
60 if (!branchheadsCache.canRead()) { 60 if (!branchheadsCache.canRead()) {
61 return lastInCache; 61 return lastInCache;
62 } 62 }
69 if (line == null || line.trim().length() == 0) { 69 if (line == null || line.trim().length() == 0) {
70 return lastInCache; 70 return lastInCache;
71 } 71 }
72 String[] cacheIdentity = spacePattern.split(line.trim()); 72 String[] cacheIdentity = spacePattern.split(line.trim());
73 lastInCache = Integer.parseInt(cacheIdentity[1]); 73 lastInCache = Integer.parseInt(cacheIdentity[1]);
74 // XXX may want to check if nodeid of cset from repo.getChangelog() of lastInCache index match cacheIdentity[0] 74 final int lastKnownRepoRevIndex = repo.getChangelog().getLastRevision();
75 // 75 if (lastInCache > lastKnownRepoRevIndex || !repo.getChangelog().getRevision(lastKnownRepoRevIndex).equals(Nodeid.fromAscii(cacheIdentity[0]))) {
76 // there are chances cache file got invalid entries due to e.g. rollback operation
77 return -1;
78 }
76 while ((line = br.readLine()) != null) { 79 while ((line = br.readLine()) != null) {
77 String[] elements = spacePattern.split(line.trim()); 80 String[] elements = spacePattern.split(line.trim());
78 if (elements.length != 2) { 81 if (elements.length != 2) {
79 // bad entry 82 // bad entry
80 continue; 83 continue;
110 void collect(final ProgressSupport ps) { 113 void collect(final ProgressSupport ps) {
111 branches.clear(); 114 branches.clear();
112 ps.start(1 + repo.getChangelog().getRevisionCount() * 2); 115 ps.start(1 + repo.getChangelog().getRevisionCount() * 2);
113 // 116 //
114 int lastCached = readCache(); 117 int lastCached = readCache();
115 /*
116 * Next code was supposed to fill missing aspects of the BranchInfo, but is too slow
117 *
118 if (lastCached != -1 && lastCached <= repo.getChangelog().getLastRevision()) {
119 LinkedList<BranchInfo> incompleteBranches = new LinkedList<HgBranches.BranchInfo>(branches.values());
120 for (BranchInfo bi : incompleteBranches) {
121 LinkedList<Nodeid> closedHeads = new LinkedList<Nodeid>();
122 for (Nodeid h : bi.getHeads()) {
123 if ("1".equals(repo.getChangelog().changeset(h).extras().get("close"))) {
124 closedHeads.add(h);
125 }
126 }
127 HashSet<Nodeid> earliest = new HashSet<Nodeid>(bi.getHeads());
128 HashSet<Nodeid> visited = new HashSet<Nodeid>();
129 ArrayList<Nodeid> parents = new ArrayList<Nodeid>(2);
130 HashSet<Nodeid> candidate = new HashSet<Nodeid>();
131 do {
132 candidate.clear();
133 for (Nodeid e : earliest) {
134 parents.clear();
135 if (pw.appendParentsOf(e, parents)) {
136 // at least one parent
137 Nodeid p1 = parents.get(0);
138 if (p1 != null && !visited.contains(p1) && bi.getName().equals(repo.getChangelog().changeset(p1).branch())) {
139 visited.add(p1);
140 candidate.add(p1);
141 }
142 Nodeid p2 = parents.size() > 1 ? parents.get(1) : null;
143 if (p2 != null && !visited.contains(p2) && bi.getName().equals(repo.getChangelog().changeset(p2).branch())) {
144 visited.add(p2);
145 candidate.add(p2);
146 }
147 }
148 }
149 if (!candidate.isEmpty()) {
150 earliest.clear();
151 earliest.addAll(candidate);
152 }
153 } while (!candidate.isEmpty());
154 // earliest can't be empty, we've started with non-empty heads.
155 Nodeid first = null;
156 if (earliest.size() == 1) {
157 first = earliest.iterator().next();
158 } else {
159 int earliestRevNum = Integer.MAX_VALUE;
160 for (Nodeid e : earliest) {
161 int x = repo.getChangelog().getLocalRevision(e);
162 if (x < earliestRevNum) {
163 earliestRevNum = x;
164 first = e;
165 }
166 }
167 }
168 assert first != null;
169 System.out.println("Updated branch " + bi.getName());
170 branches.put(bi.getName(), new BranchInfo(bi.getName(), first, bi.getHeads().toArray(new Nodeid[0]), closedHeads.size() == bi.getHeads().size()));
171 }
172 }
173 */
174 isCacheActual = lastCached == repo.getChangelog().getLastRevision(); 118 isCacheActual = lastCached == repo.getChangelog().getLastRevision();
175 if (!isCacheActual) { 119 if (!isCacheActual) {
176 final HgChangelog.ParentWalker pw = repo.getChangelog().new ParentWalker(); 120 final HgChangelog.ParentWalker pw = repo.getChangelog().new ParentWalker();
177 pw.init(); 121 pw.init();
178 ps.worked(repo.getChangelog().getRevisionCount()); 122 ps.worked(repo.getChangelog().getRevisionCount());