comparison src/org/tmatesoft/hg/repo/HgDataFile.java @ 233:1d389c0cb0a5

Optimize file history walk not to iterat over whole changelog for sparse and distant revisions
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Fri, 03 Jun 2011 04:50:09 +0200
parents 41a778e3fd31
children 6e1373b54e9b
comparison
equal deleted inserted replaced
232:b7347daa50e3 233:1d389c0cb0a5
174 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) { 174 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) {
175 commitRevisions[count++] = linkRevision; 175 commitRevisions[count++] = linkRevision;
176 } 176 }
177 }; 177 };
178 content.iterate(start, end, false, insp); 178 content.iterate(start, end, false, insp);
179 getRepo().getChangelog().range(inspector, commitRevisions); 179 final HgChangelog changelog = getRepo().getChangelog();
180 // changelog.range(inspector, commitRevisions); not effective when changes are sparse and far from each other
181 //
182 final int HistoricallyCloseCommits = 50; // XXX perhaps, shall increase/decrease based on changelog.revisionCount()
183 // (huge changelog => memory mapped files, each file re-read is more expensive than iterating over records in one read?
184 //
185 // try short sequences on neighboring revisions.
186 for (int i = 0; i < commitRevisions.length; ) {
187 int x = i;
188 i++;
189 boolean sequential = true;
190 while (i < commitRevisions.length) {
191 if (commitRevisions[i] == commitRevisions[i-1] + 1) {
192 i++;
193 } else if (commitRevisions[i] - commitRevisions[i-1] < HistoricallyCloseCommits) {
194 // close enough, but not sequential
195 sequential = false;
196 i++;
197 } else {
198 break;
199 }
200 }
201 if (sequential) {
202 // commitRevisions[x..i-1] are sequential
203 changelog.range(commitRevisions[x], commitRevisions[i-1], inspector);
204 } else {
205 int[] revs = new int[i-x];
206 System.arraycopy(commitRevisions, x, revs, 0, i-x);
207 changelog.range(inspector, revs);
208 }
209 }
180 } 210 }
181 211
182 // for a given local revision of the file, find out local revision in the changelog 212 // for a given local revision of the file, find out local revision in the changelog
183 public int getChangesetLocalRevision(int revision) { 213 public int getChangesetLocalRevision(int revision) {
184 return content.linkRevision(revision); 214 return content.linkRevision(revision);