Mercurial > hg4j
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. |