View Javadoc
1   /*
2    * Copyright (C) 2017, 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  
11  package org.eclipse.jgit.internal.revwalk;
12  
13  import org.eclipse.jgit.lib.BitmapIndex.Bitmap;
14  import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder;
15  import org.eclipse.jgit.lib.Constants;
16  import org.eclipse.jgit.revwalk.filter.RevFilter;
17  import org.eclipse.jgit.revwalk.RevWalk;
18  import org.eclipse.jgit.revwalk.RevCommit;
19  import org.eclipse.jgit.revwalk.RevFlag;
20  
21  /**
22   * A RevFilter that adds the visited commits to {@code bitmap} as a side
23   * effect.
24   * <p>
25   * When the walk hits a commit that is part of {@code bitmap}'s
26   * BitmapIndex, that entire bitmap is ORed into {@code bitmap} and the
27   * commit and its parents are marked as SEEN so that the walk does not
28   * have to visit its ancestors.  This ensures the walk is very short if
29   * there is good bitmap coverage.
30   * <p>
31   * Commits named in {@code seen} are considered already seen.  If one is
32   * encountered, that commit and its parents will be marked with the SEEN
33   * flag to prevent the walk from visiting its ancestors.
34   */
35  public class AddUnseenToBitmapFilter extends RevFilter {
36  	private final BitmapBuilder seen;
37  	private final BitmapBuilder bitmap;
38  
39  	/**
40  	 * Create a filter that adds visited commits to the given bitmap, but does not walk
41  	 * through the objects in {@code seen}.
42  	 *
43  	 * @param seen objects that are already seen
44  	 * @param bitmap bitmap to write visited commits to
45  	 */
46  	public AddUnseenToBitmapFilter(BitmapBuilder seen, BitmapBuilder bitmap) {
47  		this.seen = seen;
48  		this.bitmap = bitmap;
49  	}
50  
51  	/** {@inheritDoc} */
52  	@Override
53  	public final boolean include(RevWalk walker, RevCommit cmit) {
54  		Bitmap visitedBitmap;
55  
56  		if (seen.contains(cmit) || bitmap.contains(cmit)) {
57  			// already seen or included
58  		} else if ((visitedBitmap = bitmap.getBitmapIndex()
59  				.getBitmap(cmit)) != null) {
60  			bitmap.or(visitedBitmap);
61  		} else {
62  			bitmap.addObject(cmit, Constants.OBJ_COMMIT);
63  			return true;
64  		}
65  
66  		for (RevCommit p : cmit.getParents()) {
67  			p.add(RevFlag.SEEN);
68  		}
69  		return false;
70  	}
71  
72  	/** {@inheritDoc} */
73  	@Override
74  	public final RevFilter clone() {
75  		throw new UnsupportedOperationException();
76  	}
77  
78  	/** {@inheritDoc} */
79  	@Override
80  	public final boolean requiresCommitBody() {
81  		return false;
82  	}
83  }