ReverseWalk.java

  1. /*
  2.  * Copyright (C) 2011, Google Inc. and others
  3.  *
  4.  * This program and the accompanying materials are made available under the
  5.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  6.  * https://www.eclipse.org/org/documents/edl-v10.php.
  7.  *
  8.  * SPDX-License-Identifier: BSD-3-Clause
  9.  */

  10. package org.eclipse.jgit.blame;

  11. import java.io.IOException;

  12. import org.eclipse.jgit.errors.IncorrectObjectTypeException;
  13. import org.eclipse.jgit.errors.MissingObjectException;
  14. import org.eclipse.jgit.lib.AnyObjectId;
  15. import org.eclipse.jgit.lib.Repository;
  16. import org.eclipse.jgit.revwalk.RevCommit;
  17. import org.eclipse.jgit.revwalk.RevWalk;

  18. final class ReverseWalk extends RevWalk {
  19.     ReverseWalk(Repository repo) {
  20.         super(repo);
  21.     }

  22.     /** {@inheritDoc} */
  23.     @Override
  24.     public ReverseCommit next() throws MissingObjectException,
  25.             IncorrectObjectTypeException, IOException {
  26.         ReverseCommit c = (ReverseCommit) super.next();
  27.         if (c == null)
  28.             return null;
  29.         for (int pIdx = 0; pIdx < c.getParentCount(); pIdx++)
  30.             ((ReverseCommit) c.getParent(pIdx)).addChild(c);
  31.         return c;
  32.     }

  33.     /** {@inheritDoc} */
  34.     @Override
  35.     protected RevCommit createCommit(AnyObjectId id) {
  36.         return new ReverseCommit(id);
  37.     }

  38.     static final class ReverseCommit extends RevCommit {
  39.         private static final ReverseCommit[] NO_CHILDREN = {};

  40.         private ReverseCommit[] children = NO_CHILDREN;

  41.         ReverseCommit(AnyObjectId id) {
  42.             super(id);
  43.         }

  44.         void addChild(ReverseCommit c) {
  45.             // Always put the most recent child onto the front of the list.
  46.             // This works correctly because our ReverseWalk parent (above)
  47.             // runs in COMMIT_TIME_DESC order. Older commits will be popped
  48.             // later and should go in front of the children list so they are
  49.             // visited first by BlameGenerator when considering candidates.

  50.             int cnt = children.length;
  51.             switch (cnt) {
  52.             case 0:
  53.                 children = new ReverseCommit[] { c };
  54.                 break;
  55.             case 1:
  56.                 children = new ReverseCommit[] { c, children[0] };
  57.                 break;
  58.             default:
  59.                 ReverseCommit[] n = new ReverseCommit[1 + cnt];
  60.                 n[0] = c;
  61.                 System.arraycopy(children, 0, n, 1, cnt);
  62.                 children = n;
  63.                 break;
  64.             }
  65.         }

  66.         int getChildCount() {
  67.             return children.length;
  68.         }

  69.         ReverseCommit getChild(int nth) {
  70.             return children[nth];
  71.         }
  72.     }
  73. }