Mercurial > jhg
comparison src/org/tmatesoft/hg/repo/HgManifest.java @ 598:d29d9dc6c128
Utilize the fact nodeids are very different and are read anyway to speed up reverse lookup
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Fri, 03 May 2013 15:19:18 +0200 |
| parents | c895b5556937 |
| children | 46f29b73e51e |
comparison
equal
deleted
inserted
replaced
| 597:c895b5556937 | 598:d29d9dc6c128 |
|---|---|
| 575 private static class RevisionMapper implements RevlogStream.Inspector, Lifecycle { | 575 private static class RevisionMapper implements RevlogStream.Inspector, Lifecycle { |
| 576 | 576 |
| 577 private final int changelogRevisionCount; | 577 private final int changelogRevisionCount; |
| 578 private int[] changelog2manifest; | 578 private int[] changelog2manifest; |
| 579 private final HgRepository repo; | 579 private final HgRepository repo; |
| 580 private int[] manifestNodeidHashes; // first 4 bytes of manifest nodeid at corresponding index | |
| 580 | 581 |
| 581 public RevisionMapper(HgRepository hgRepo) { | 582 public RevisionMapper(HgRepository hgRepo) { |
| 582 repo = hgRepo; | 583 repo = hgRepo; |
| 583 changelogRevisionCount = repo.getChangelog().getRevisionCount(); | 584 changelogRevisionCount = repo.getChangelog().getRevisionCount(); |
| 584 } | 585 } |
| 617 for (int i = 0; i < revisionNumber; changelog2manifest[i] = i, i++) | 618 for (int i = 0; i < revisionNumber; changelog2manifest[i] = i, i++) |
| 618 ; | 619 ; |
| 619 changelog2manifest[linkRevision] = revisionNumber; | 620 changelog2manifest[linkRevision] = revisionNumber; |
| 620 } | 621 } |
| 621 } | 622 } |
| 623 manifestNodeidHashes[revisionNumber] = Nodeid.hashCode(nodeid); | |
| 622 } | 624 } |
| 623 | 625 |
| 624 public void start(int count, Callback callback, Object token) { | 626 public void start(int count, Callback callback, Object token) { |
| 625 if (count != changelogRevisionCount) { | 627 if (count != changelogRevisionCount) { |
| 626 assert count < changelogRevisionCount; // no idea what to do if manifest has more revisions than changelog | 628 assert count < changelogRevisionCount; // no idea what to do if manifest has more revisions than changelog |
| 629 // Note, it's pure guess, I didn't see such repository yet (although the way manifest revisions | 631 // Note, it's pure guess, I didn't see such repository yet (although the way manifest revisions |
| 630 // in cpython repo are numbered makes me think aforementioned way) | 632 // in cpython repo are numbered makes me think aforementioned way) |
| 631 changelog2manifest = new int[changelogRevisionCount]; | 633 changelog2manifest = new int[changelogRevisionCount]; |
| 632 Arrays.fill(changelog2manifest, BAD_REVISION); | 634 Arrays.fill(changelog2manifest, BAD_REVISION); |
| 633 } | 635 } |
| 636 manifestNodeidHashes = new int[count]; | |
| 634 } | 637 } |
| 635 | 638 |
| 636 public void finish(Object token) { | 639 public void finish(Object token) { |
| 637 if (changelog2manifest == null) { | 640 if (changelog2manifest == null) { |
| 638 return; | 641 return; |
| 643 if (changelog2manifest[i] == BAD_REVISION) { | 646 if (changelog2manifest[i] == BAD_REVISION) { |
| 644 undefinedChangelogRevision.add(i); | 647 undefinedChangelogRevision.add(i); |
| 645 } | 648 } |
| 646 } | 649 } |
| 647 if (undefinedChangelogRevision.size() > 0) { | 650 if (undefinedChangelogRevision.size() > 0) { |
| 651 final long t1 = System.nanoTime(); | |
| 648 final IntMap<Nodeid> missingCsetToManifest = new IntMap<Nodeid>(undefinedChangelogRevision.size()); | 652 final IntMap<Nodeid> missingCsetToManifest = new IntMap<Nodeid>(undefinedChangelogRevision.size()); |
| 649 int[] undefinedClogRevs = undefinedChangelogRevision.toArray(); | 653 int[] undefinedClogRevs = undefinedChangelogRevision.toArray(); |
| 650 // undefinedChangelogRevision is sorted by the nature it's created | 654 // undefinedChangelogRevision is sorted by the nature it's created |
| 651 repo.getChangelog().rangeInternal(new HgChangelog.Inspector() { | 655 repo.getChangelog().rangeInternal(new HgChangelog.Inspector() { |
| 652 | 656 |
| 653 public void next(int revisionIndex, Nodeid nodeid, RawChangeset cset) { | 657 public void next(int revisionIndex, Nodeid nodeid, RawChangeset cset) { |
| 654 missingCsetToManifest.put(revisionIndex, cset.manifest()); | 658 missingCsetToManifest.put(revisionIndex, cset.manifest()); |
| 655 } | 659 } |
| 656 }, undefinedClogRevs); | 660 }, undefinedClogRevs); |
| 657 assert missingCsetToManifest.size() == undefinedChangelogRevision.size(); | 661 assert missingCsetToManifest.size() == undefinedChangelogRevision.size(); |
| 662 final long t2 = System.nanoTime(); | |
| 658 for (int u : undefinedClogRevs) { | 663 for (int u : undefinedClogRevs) { |
| 659 Nodeid manifest = missingCsetToManifest.get(u); | 664 Nodeid manifest = missingCsetToManifest.get(u); |
| 660 // TODO calculate those missing effectively (e.g. cache and sort nodeids to speed lookup | |
| 661 // right away in the #next (may refactor ParentWalker's sequential and sorted into dedicated helper and reuse here) | |
| 662 if (manifest == null || manifest.isNull()) { | 665 if (manifest == null || manifest.isNull()) { |
| 663 repo.getSessionContext().getLog().dump(getClass(), Severity.Warn, "Changeset %d has no associated manifest entry", u); | 666 repo.getSessionContext().getLog().dump(getClass(), Severity.Warn, "Changeset %d has no associated manifest entry", u); |
| 664 // keep -1 in the changelog2manifest map. | 667 // keep -1 in the changelog2manifest map. |
| 665 } else { | 668 continue; |
| 666 changelog2manifest[u] = repo.getManifest().getRevisionIndex(manifest); | |
| 667 } | 669 } |
| 668 } | 670 int hash = manifest.hashCode(); |
| 669 } | 671 for (int i = 0; i < manifestNodeidHashes.length; i++) { |
| 672 if (manifestNodeidHashes[i] == hash) { | |
| 673 if (manifest.equals(repo.getManifest().getRevision(i))) { | |
| 674 changelog2manifest[u] = i; | |
| 675 break; | |
| 676 } | |
| 677 // else false match (only 4 head bytes matched, continue loop | |
| 678 } | |
| 679 } | |
| 680 } | |
| 681 final long t3 = System.nanoTime(); | |
| 682 System.out.printf("\tRevisionMapper#finish(), %d missing revs: %d + %d us\n", undefinedChangelogRevision.size(), (t2-t1) / 1000, (t3-t2) / 1000); | |
| 683 } | |
| 684 manifestNodeidHashes = null; | |
| 670 } | 685 } |
| 671 } | 686 } |
| 672 | 687 |
| 673 /** | 688 /** |
| 674 * Look up specified file in possibly multiple manifest revisions, collect file revision and flags. | 689 * Look up specified file in possibly multiple manifest revisions, collect file revision and flags. |
