All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.jgit.revwalk.RevCommitList Maven / Gradle / Ivy

/*
 * Copyright (C) 2008, Shawn O. Pearce 
 * and other copyright owners as documented in the project's IP log.
 *
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Distribution License v1.0 which
 * accompanies this distribution, is reproduced below, and is
 * available at http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the
 *   names of its contributors may be used to endorse or promote
 *   products derived from this software without specific prior
 *   written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.eclipse.jgit.revwalk;

import java.io.IOException;

import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.revwalk.filter.RevFilter;

/**
 * An ordered list of {@link RevCommit} subclasses.
 *
 * @param 
 *            type of subclass of RevCommit the list is storing.
 */
public class RevCommitList extends RevObjectList {
	private RevWalk walker;

	@Override
	public void clear() {
		super.clear();
		walker = null;
	}

	/**
	 * Apply a flag to all commits matching the specified filter.
	 * 

* Same as applyFlag(matching, flag, 0, size()), but without * the incremental behavior. * * @param matching * the filter to test commits with. If the filter includes a * commit it will have the flag set; if the filter does not * include the commit the flag will be unset. * @param flag * the flag to apply (or remove). Applications are responsible * for allocating this flag from the source RevWalk. * @throws IOException * revision filter needed to read additional objects, but an * error occurred while reading the pack files or loose objects * of the repository. * @throws IncorrectObjectTypeException * revision filter needed to read additional objects, but an * object was not of the correct type. Repository corruption may * have occurred. * @throws MissingObjectException * revision filter needed to read additional objects, but an * object that should be present was not found. Repository * corruption may have occurred. */ public void applyFlag(final RevFilter matching, final RevFlag flag) throws MissingObjectException, IncorrectObjectTypeException, IOException { applyFlag(matching, flag, 0, size()); } /** * Apply a flag to all commits matching the specified filter. *

* This version allows incremental testing and application, such as from a * background thread that needs to periodically halt processing and send * updates to the UI. * * @param matching * the filter to test commits with. If the filter includes a * commit it will have the flag set; if the filter does not * include the commit the flag will be unset. * @param flag * the flag to apply (or remove). Applications are responsible * for allocating this flag from the source RevWalk. * @param rangeBegin * first commit within the list to begin testing at, inclusive. * Must not be negative, but may be beyond the end of the list. * @param rangeEnd * last commit within the list to end testing at, exclusive. If * smaller than or equal to rangeBegin then no * commits will be tested. * @throws IOException * revision filter needed to read additional objects, but an * error occurred while reading the pack files or loose objects * of the repository. * @throws IncorrectObjectTypeException * revision filter needed to read additional objects, but an * object was not of the correct type. Repository corruption may * have occurred. * @throws MissingObjectException * revision filter needed to read additional objects, but an * object that should be present was not found. Repository * corruption may have occurred. */ public void applyFlag(final RevFilter matching, final RevFlag flag, int rangeBegin, int rangeEnd) throws MissingObjectException, IncorrectObjectTypeException, IOException { final RevWalk w = flag.getRevWalk(); rangeEnd = Math.min(rangeEnd, size()); while (rangeBegin < rangeEnd) { int index = rangeBegin; Block s = contents; while (s.shift > 0) { final int i = index >> s.shift; index -= i << s.shift; s = (Block) s.contents[i]; } while (rangeBegin++ < rangeEnd && index < BLOCK_SIZE) { final RevCommit c = (RevCommit) s.contents[index++]; if (matching.include(w, c)) c.add(flag); else c.remove(flag); } } } /** * Remove the given flag from all commits. *

* Same as clearFlag(flag, 0, size()), but without the * incremental behavior. * * @param flag * the flag to remove. Applications are responsible for * allocating this flag from the source RevWalk. */ public void clearFlag(final RevFlag flag) { clearFlag(flag, 0, size()); } /** * Remove the given flag from all commits. *

* This method is actually implemented in terms of: * applyFlag(RevFilter.NONE, flag, rangeBegin, rangeEnd). * * @param flag * the flag to remove. Applications are responsible for * allocating this flag from the source RevWalk. * @param rangeBegin * first commit within the list to begin testing at, inclusive. * Must not be negative, but may be beyond the end of the list. * @param rangeEnd * last commit within the list to end testing at, exclusive. If * smaller than or equal to rangeBegin then no * commits will be tested. */ public void clearFlag(final RevFlag flag, final int rangeBegin, final int rangeEnd) { try { applyFlag(RevFilter.NONE, flag, rangeBegin, rangeEnd); } catch (IOException e) { // Never happen. The filter we use does not throw any // exceptions, for any reason. } } /** * Find the next commit that has the given flag set. * * @param flag * the flag to test commits against. * @param begin * first commit index to test at. Applications may wish to begin * at 0, to test the first commit in the list. * @return index of the first commit at or after index begin * that has the specified flag set on it; -1 if no match is found. */ public int indexOf(final RevFlag flag, int begin) { while (begin < size()) { int index = begin; Block s = contents; while (s.shift > 0) { final int i = index >> s.shift; index -= i << s.shift; s = (Block) s.contents[i]; } while (begin++ < size() && index < BLOCK_SIZE) { final RevCommit c = (RevCommit) s.contents[index++]; if (c.has(flag)) return begin; } } return -1; } /** * Find the next commit that has the given flag set. * * @param flag * the flag to test commits against. * @param begin * first commit index to test at. Applications may wish to begin * at size()-1, to test the last commit in the * list. * @return index of the first commit at or before index begin * that has the specified flag set on it; -1 if no match is found. */ public int lastIndexOf(final RevFlag flag, int begin) { begin = Math.min(begin, size() - 1); while (begin >= 0) { int index = begin; Block s = contents; while (s.shift > 0) { final int i = index >> s.shift; index -= i << s.shift; s = (Block) s.contents[i]; } while (begin-- >= 0 && index >= 0) { final RevCommit c = (RevCommit) s.contents[index--]; if (c.has(flag)) return begin; } } return -1; } /** * Set the revision walker this list populates itself from. * * @param w * the walker to populate from. * @see #fillTo(int) */ public void source(final RevWalk w) { walker = w; } /** * Is this list still pending more items? * * @return true if {@link #fillTo(int)} might be able to extend the list * size when called. */ public boolean isPending() { return walker != null; } /** * Ensure this list contains at least a specified number of commits. *

* The revision walker specified by {@link #source(RevWalk)} is pumped until * the given number of commits are contained in this list. If there are * fewer total commits available from the walk then the method will return * early. Callers can test the final size of the list by {@link #size()} to * determine if the high water mark specified was met. * * @param highMark * number of commits the caller wants this list to contain when * the fill operation is complete. * @throws IOException * see {@link RevWalk#next()} * @throws IncorrectObjectTypeException * see {@link RevWalk#next()} * @throws MissingObjectException * see {@link RevWalk#next()} */ public void fillTo(final int highMark) throws MissingObjectException, IncorrectObjectTypeException, IOException { if (walker == null || size > highMark) return; RevCommit c = walker.next(); if (c == null) { walker = null; return; } enter(size, (E) c); add((E) c); while (size <= highMark) { int index = size; Block s = contents; while (index >> s.shift >= BLOCK_SIZE) { s = new Block(s.shift + BLOCK_SHIFT); s.contents[0] = contents; contents = s; } while (s.shift > 0) { final int i = index >> s.shift; index -= i << s.shift; if (s.contents[i] == null) s.contents[i] = new Block(s.shift - BLOCK_SHIFT); s = (Block) s.contents[i]; } final Object[] dst = s.contents; while (size <= highMark && index < BLOCK_SIZE) { c = walker.next(); if (c == null) { walker = null; return; } enter(size++, (E) c); dst[index++] = c; } } } /** * Ensures all commits until the given commit are loaded. The revision * walker specified by {@link #source(RevWalk)} is pumped until the * specified commit is loaded. Callers can test the final size of the list * by {@link #size()} to determine if the high water mark specified was met. *

* @param commitToLoad * commit the caller wants this list to contain when the fill * operation is complete. * @param highMark * maximum number of commits the caller wants this list to * contain when the fill operation is complete. If highMark is 0 * the walk is pumped until the specified commit or the end of * the walk is reached. * @throws IOException * see {@link RevWalk#next()} * @throws IncorrectObjectTypeException * see {@link RevWalk#next()} * @throws MissingObjectException * see {@link RevWalk#next()} */ public void fillTo(final RevCommit commitToLoad, int highMark) throws MissingObjectException, IncorrectObjectTypeException, IOException { if (walker == null || commitToLoad == null || (highMark > 0 && size > highMark)) return; RevCommit c = walker.next(); if (c == null) { walker = null; return; } enter(size, (E) c); add((E) c); while ((highMark == 0 || size <= highMark) && !c.equals(commitToLoad)) { int index = size; Block s = contents; while (index >> s.shift >= BLOCK_SIZE) { s = new Block(s.shift + BLOCK_SHIFT); s.contents[0] = contents; contents = s; } while (s.shift > 0) { final int i = index >> s.shift; index -= i << s.shift; if (s.contents[i] == null) s.contents[i] = new Block(s.shift - BLOCK_SHIFT); s = (Block) s.contents[i]; } final Object[] dst = s.contents; while ((highMark == 0 || size <= highMark) && index < BLOCK_SIZE && !c.equals(commitToLoad)) { c = walker.next(); if (c == null) { walker = null; return; } enter(size++, (E) c); dst[index++] = c; } } } /** * Optional callback invoked when commits enter the list by fillTo. *

* This method is only called during {@link #fillTo(int)}. * * @param index * the list position this object will appear at. * @param e * the object being added (or set) into the list. */ protected void enter(final int index, final E e) { // Do nothing by default. } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy