Mercurial > jhg
comparison src/org/tmatesoft/hg/repo/HgDataFile.java @ 242:ad6a046943be
Improved reading of sparse revisions from a revlog
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Thu, 23 Jun 2011 15:19:07 +0200 |
| parents | 29231022fec8 |
| children | 2fb439375ddc |
comparison
equal
deleted
inserted
replaced
| 241:d3ab16739736 | 242:ad6a046943be |
|---|---|
| 222 end = last; | 222 end = last; |
| 223 } else if (end < start || end > last) { | 223 } else if (end < start || end > last) { |
| 224 throw new IllegalArgumentException(); | 224 throw new IllegalArgumentException(); |
| 225 } | 225 } |
| 226 final int[] commitRevisions = new int[end - start + 1]; | 226 final int[] commitRevisions = new int[end - start + 1]; |
| 227 final boolean[] needsSorting = { false }; | |
| 227 RevlogStream.Inspector insp = new RevlogStream.Inspector() { | 228 RevlogStream.Inspector insp = new RevlogStream.Inspector() { |
| 228 int count = 0; | 229 int count = 0; |
| 229 | |
| 230 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) { | 230 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) { |
| 231 if (count > 0) { | |
| 232 if (commitRevisions[count -1] > linkRevision) { | |
| 233 needsSorting[0] = true; | |
| 234 } | |
| 235 } | |
| 231 commitRevisions[count++] = linkRevision; | 236 commitRevisions[count++] = linkRevision; |
| 232 } | 237 } |
| 233 }; | 238 }; |
| 234 content.iterate(start, end, false, insp); | 239 content.iterate(start, end, false, insp); |
| 235 final HgChangelog changelog = getRepo().getChangelog(); | 240 final HgChangelog changelog = getRepo().getChangelog(); |
| 236 /* | 241 if (needsSorting[0]) { |
| 237 * changelog.range(inspector, commitRevisions); | 242 // automatic tools (svnmerge?) produce unnatural file history |
| 238 * Not effective when changes are sparse and far from each other. | 243 // (e.g. cpython/Lib/doctest.py, revision 164 points to cset 63509, 165 - to 38453) |
| 239 * However, it's only single file read, unlike code below (few reads of sequential blocks) | 244 Arrays.sort(commitRevisions); |
| 240 * Need to weight tradeoffs of file read and iteration of sparse files. | 245 } |
| 241 */ | 246 changelog.range(inspector, commitRevisions); |
| 242 | |
| 243 // | |
| 244 final int HistoricallyCloseCommits = 50; // XXX perhaps, shall increase/decrease based on changelog.revisionCount() | |
| 245 // (huge changelog => memory mapped files, each file re-read is more expensive than iterating over records in one read? | |
| 246 // | |
| 247 // try short sequences on neighboring revisions. | |
| 248 Arrays.sort(commitRevisions); // automatic tools (svnmerge?) produce unnatural file history | |
| 249 // (e.g. cpython/Lib/doctest.py, revision 164 points to 63509, 165 - to 38453) | |
| 250 for (int i = 0; i < commitRevisions.length; ) { | |
| 251 int x = i; | |
| 252 i++; | |
| 253 boolean sequential = true; | |
| 254 while (i < commitRevisions.length) { | |
| 255 if (commitRevisions[i] == commitRevisions[i-1] + 1) { | |
| 256 i++; | |
| 257 } else if (commitRevisions[i] - commitRevisions[i-1] < HistoricallyCloseCommits) { | |
| 258 // close enough, but not sequential | |
| 259 sequential = false; | |
| 260 i++; | |
| 261 } else { | |
| 262 break; | |
| 263 } | |
| 264 } | |
| 265 if (sequential) { | |
| 266 // commitRevisions[x..i-1] are sequential | |
| 267 changelog.range(commitRevisions[x], commitRevisions[i-1], inspector); | |
| 268 } else { | |
| 269 int[] revs = new int[i-x]; | |
| 270 System.arraycopy(commitRevisions, x, revs, 0, i-x); | |
| 271 changelog.range(inspector, revs); | |
| 272 } | |
| 273 } | |
| 274 } | 247 } |
| 275 | 248 |
| 276 // for a given local revision of the file, find out local revision in the changelog | 249 // for a given local revision of the file, find out local revision in the changelog |
| 277 public int getChangesetLocalRevision(int revision) { | 250 public int getChangesetLocalRevision(int revision) { |
| 278 return content.linkRevision(revision); | 251 return content.linkRevision(revision); |
