aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java405
1 files changed, 329 insertions, 76 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
index 4c9af85fa8..b916d1e8e9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
@@ -1,70 +1,58 @@
/*
- * Copyright (C) 2010, Google Inc.
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2010, Google Inc. and others
*
- * 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
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://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.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.lib;
+import static org.eclipse.jgit.lib.Constants.OBJECT_ID_ABBREV_STRING_LENGTH;
+
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import java.util.Optional;
import java.util.Set;
+import org.eclipse.jgit.annotations.NonNull;
+import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
-import org.eclipse.jgit.internal.storage.pack.ObjectReuseAsIs;
+import org.eclipse.jgit.internal.revwalk.BitmappedObjectReachabilityChecker;
+import org.eclipse.jgit.internal.revwalk.BitmappedReachabilityChecker;
+import org.eclipse.jgit.internal.revwalk.PedestrianObjectReachabilityChecker;
+import org.eclipse.jgit.internal.revwalk.PedestrianReachabilityChecker;
+import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph;
+import org.eclipse.jgit.revwalk.ObjectReachabilityChecker;
+import org.eclipse.jgit.revwalk.ObjectWalk;
+import org.eclipse.jgit.revwalk.ReachabilityChecker;
+import org.eclipse.jgit.revwalk.RevWalk;
/**
- * Reads an {@link ObjectDatabase} for a single thread.
+ * Reads an {@link org.eclipse.jgit.lib.ObjectDatabase} for a single thread.
* <p>
* Readers that can support efficient reuse of pack encoded objects should also
- * implement the companion interface {@link ObjectReuseAsIs}.
+ * implement the companion interface
+ * {@link org.eclipse.jgit.internal.storage.pack.ObjectReuseAsIs}.
*/
public abstract class ObjectReader implements AutoCloseable {
/** Type hint indicating the caller doesn't know the type. */
public static final int OBJ_ANY = -1;
/**
+ * The threshold at which a file will be streamed rather than loaded
+ * entirely into memory.
+ * @since 4.6
+ */
+ protected int streamFileThreshold;
+
+ /**
* Construct a new reader from the same data.
* <p>
* Applications can use this method to build a new reader from the same data
@@ -87,12 +75,12 @@ public abstract class ObjectReader implements AutoCloseable {
* @param objectId
* object identity that needs to be abbreviated.
* @return SHA-1 abbreviation.
- * @throws IOException
+ * @throws java.io.IOException
* the object store cannot be read.
*/
public AbbreviatedObjectId abbreviate(AnyObjectId objectId)
throws IOException {
- return abbreviate(objectId, 7);
+ return abbreviate(objectId, OBJECT_ID_ABBREV_STRING_LENGTH);
}
/**
@@ -114,7 +102,7 @@ public abstract class ObjectReader implements AutoCloseable {
* [2, {@value Constants#OBJECT_ID_STRING_LENGTH}].
* @return SHA-1 abbreviation. If no matching objects exist in the
* repository, the abbreviation will match the minimum length.
- * @throws IOException
+ * @throws java.io.IOException
* the object store cannot be read.
*/
public AbbreviatedObjectId abbreviate(AnyObjectId objectId, int len)
@@ -126,7 +114,7 @@ public abstract class ObjectReader implements AutoCloseable {
Collection<ObjectId> matches = resolve(abbrev);
while (1 < matches.size() && len < Constants.OBJECT_ID_STRING_LENGTH) {
abbrev = objectId.abbreviate(++len);
- List<ObjectId> n = new ArrayList<ObjectId>(8);
+ List<ObjectId> n = new ArrayList<>(8);
for (ObjectId candidate : matches) {
if (abbrev.prefixCompare(candidate) == 0)
n.add(candidate);
@@ -166,7 +154,7 @@ public abstract class ObjectReader implements AutoCloseable {
* abbreviated id to resolve to a complete identity. The
* abbreviation must have a length of at least 2.
* @return candidates that begin with the abbreviated identity.
- * @throws IOException
+ * @throws java.io.IOException
* the object store cannot be read.
*/
public abstract Collection<ObjectId> resolve(AbbreviatedObjectId id)
@@ -178,7 +166,7 @@ public abstract class ObjectReader implements AutoCloseable {
* @param objectId
* identity of the object to test for existence of.
* @return true if the specified object is stored in this database.
- * @throws IOException
+ * @throws java.io.IOException
* the object store cannot be accessed.
*/
public boolean has(AnyObjectId objectId) throws IOException {
@@ -192,13 +180,14 @@ public abstract class ObjectReader implements AutoCloseable {
* identity of the object to test for existence of.
* @param typeHint
* hint about the type of object being requested, e.g.
- * {@link Constants#OBJ_BLOB}; {@link #OBJ_ANY} if the object
- * type is not known, or does not matter to the caller.
+ * {@link org.eclipse.jgit.lib.Constants#OBJ_BLOB};
+ * {@link #OBJ_ANY} if the object type is not known, or does not
+ * matter to the caller.
* @return true if the specified object is stored in this database.
* @throws IncorrectObjectTypeException
* typeHint was not OBJ_ANY, and the object's actual type does
* not match typeHint.
- * @throws IOException
+ * @throws java.io.IOException
* the object store cannot be accessed.
*/
public boolean has(AnyObjectId objectId, int typeHint) throws IOException {
@@ -215,10 +204,11 @@ public abstract class ObjectReader implements AutoCloseable {
*
* @param objectId
* identity of the object to open.
- * @return a {@link ObjectLoader} for accessing the object.
- * @throws MissingObjectException
+ * @return a {@link org.eclipse.jgit.lib.ObjectLoader} for accessing the
+ * object.
+ * @throws org.eclipse.jgit.errors.MissingObjectException
* the object does not exist.
- * @throws IOException
+ * @throws java.io.IOException
* the object store cannot be accessed.
*/
public ObjectLoader open(AnyObjectId objectId)
@@ -233,15 +223,17 @@ public abstract class ObjectReader implements AutoCloseable {
* identity of the object to open.
* @param typeHint
* hint about the type of object being requested, e.g.
- * {@link Constants#OBJ_BLOB}; {@link #OBJ_ANY} if the object
- * type is not known, or does not matter to the caller.
- * @return a {@link ObjectLoader} for accessing the object.
- * @throws MissingObjectException
+ * {@link org.eclipse.jgit.lib.Constants#OBJ_BLOB};
+ * {@link #OBJ_ANY} if the object type is not known, or does not
+ * matter to the caller.
+ * @return a {@link org.eclipse.jgit.lib.ObjectLoader} for accessing the
+ * object.
+ * @throws org.eclipse.jgit.errors.MissingObjectException
* the object does not exist.
- * @throws IncorrectObjectTypeException
+ * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException
* typeHint was not OBJ_ANY, and the object's actual type does
* not match typeHint.
- * @throws IOException
+ * @throws java.io.IOException
* the object store cannot be accessed.
*/
public abstract ObjectLoader open(AnyObjectId objectId, int typeHint)
@@ -252,7 +244,8 @@ public abstract class ObjectReader implements AutoCloseable {
* Returns IDs for those commits which should be considered as shallow.
*
* @return IDs of shallow commits
- * @throws IOException
+ * @throws java.io.IOException
+ * if an error occurred
*/
public abstract Set<ObjectId> getShallowCommits() throws IOException;
@@ -260,7 +253,7 @@ public abstract class ObjectReader implements AutoCloseable {
* Asynchronous object opening.
*
* @param <T>
- * type of identifier being supplied.
+ * type of {@code ObjectId}
* @param objectIds
* objects to open from the object store. The supplied collection
* must not be modified until the queue has finished.
@@ -275,34 +268,39 @@ public abstract class ObjectReader implements AutoCloseable {
public <T extends ObjectId> AsyncObjectLoaderQueue<T> open(
Iterable<T> objectIds, final boolean reportMissing) {
final Iterator<T> idItr = objectIds.iterator();
- return new AsyncObjectLoaderQueue<T>() {
+ return new AsyncObjectLoaderQueue<>() {
private T cur;
+ @Override
public boolean next() throws MissingObjectException, IOException {
if (idItr.hasNext()) {
cur = idItr.next();
return true;
- } else {
- return false;
}
+ return false;
}
+ @Override
public T getCurrent() {
return cur;
}
+ @Override
public ObjectId getObjectId() {
return cur;
}
+ @Override
public ObjectLoader open() throws IOException {
return ObjectReader.this.open(cur, OBJ_ANY);
}
+ @Override
public boolean cancel(boolean mayInterruptIfRunning) {
return true;
}
+ @Override
public void release() {
// Since we are sequential by default, we don't
// have any state to clean up if we terminate early.
@@ -321,15 +319,16 @@ public abstract class ObjectReader implements AutoCloseable {
* identity of the object to open.
* @param typeHint
* hint about the type of object being requested, e.g.
- * {@link Constants#OBJ_BLOB}; {@link #OBJ_ANY} if the object
- * type is not known, or does not matter to the caller.
+ * {@link org.eclipse.jgit.lib.Constants#OBJ_BLOB};
+ * {@link #OBJ_ANY} if the object type is not known, or does not
+ * matter to the caller.
* @return size of object in bytes.
- * @throws MissingObjectException
+ * @throws org.eclipse.jgit.errors.MissingObjectException
* the object does not exist.
- * @throws IncorrectObjectTypeException
+ * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException
* typeHint was not OBJ_ANY, and the object's actual type does
* not match typeHint.
- * @throws IOException
+ * @throws java.io.IOException
* the object store cannot be accessed.
*/
public long getObjectSize(AnyObjectId objectId, int typeHint)
@@ -339,10 +338,43 @@ public abstract class ObjectReader implements AutoCloseable {
}
/**
+ * Check if the object size is less or equal than certain value
+ *
+ * By default, it reads the object from storage to get the size. Subclasses
+ * can implement more efficient lookups.
+ *
+ * @param objectId
+ * identity of the object to open.
+ * @param typeHint
+ * hint about the type of object being requested, e.g.
+ * {@link org.eclipse.jgit.lib.Constants#OBJ_BLOB};
+ * {@link #OBJ_ANY} if the object type is not known, or does not
+ * matter to the caller.
+ * @param size
+ * threshold value for the size of the object in bytes.
+ * @return true if the object size is equal or smaller than the threshold
+ * value
+ * @throws org.eclipse.jgit.errors.MissingObjectException
+ * the object does not exist.
+ * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException
+ * typeHint was not OBJ_ANY, and the object's actual type does
+ * not match typeHint.
+ * @throws java.io.IOException
+ * the object store cannot be accessed.
+ *
+ * @since 6.4
+ */
+ public boolean isNotLargerThan(AnyObjectId objectId, int typeHint, long size)
+ throws MissingObjectException, IncorrectObjectTypeException,
+ IOException {
+ return open(objectId, typeHint).getSize() <= size;
+ }
+
+ /**
* Asynchronous object size lookup.
*
* @param <T>
- * type of identifier being supplied.
+ * type of {@code ObjectId}
* @param objectIds
* objects to get the size of from the object store. The supplied
* collection must not be modified until the queue has finished.
@@ -357,37 +389,42 @@ public abstract class ObjectReader implements AutoCloseable {
public <T extends ObjectId> AsyncObjectSizeQueue<T> getObjectSize(
Iterable<T> objectIds, final boolean reportMissing) {
final Iterator<T> idItr = objectIds.iterator();
- return new AsyncObjectSizeQueue<T>() {
+ return new AsyncObjectSizeQueue<>() {
private T cur;
private long sz;
+ @Override
public boolean next() throws MissingObjectException, IOException {
if (idItr.hasNext()) {
cur = idItr.next();
sz = getObjectSize(cur, OBJ_ANY);
return true;
- } else {
- return false;
}
+ return false;
}
+ @Override
public T getCurrent() {
return cur;
}
+ @Override
public ObjectId getObjectId() {
return cur;
}
+ @Override
public long getSize() {
return sz;
}
+ @Override
public boolean cancel(boolean mayInterruptIfRunning) {
return true;
}
+ @Override
public void release() {
// Since we are sequential by default, we don't
// have any state to clean up if we terminate early.
@@ -413,7 +450,7 @@ public abstract class ObjectReader implements AutoCloseable {
* An index that can be used to speed up ObjectWalks.
*
* @return the index or null if one does not exist.
- * @throws IOException
+ * @throws java.io.IOException
* when the index fails to load
* @since 3.0
*/
@@ -422,6 +459,90 @@ public abstract class ObjectReader implements AutoCloseable {
}
/**
+ * Create a reachability checker that will use bitmaps if possible.
+ *
+ * @param rw
+ * revwalk for use by the reachability checker
+ * @return the most efficient reachability checker for this repository.
+ * @throws IOException
+ * if it cannot open any of the underlying indices.
+ *
+ * @since 5.11
+ */
+ @NonNull
+ public ReachabilityChecker createReachabilityChecker(RevWalk rw)
+ throws IOException {
+ if (getBitmapIndex() != null) {
+ return new BitmappedReachabilityChecker(rw);
+ }
+
+ return new PedestrianReachabilityChecker(true, rw);
+ }
+
+ /**
+ * Create an object reachability checker that will use bitmaps if possible.
+ *
+ * This reachability checker accepts any object as target. For checks
+ * exclusively between commits, use
+ * {@link #createReachabilityChecker(RevWalk)}.
+ *
+ * @param ow
+ * objectwalk for use by the reachability checker
+ * @return the most efficient object reachability checker for this
+ * repository.
+ *
+ * @throws IOException
+ * if it cannot open any of the underlying indices.
+ *
+ * @since 5.11
+ */
+ @NonNull
+ public ObjectReachabilityChecker createObjectReachabilityChecker(
+ ObjectWalk ow) throws IOException {
+ if (getBitmapIndex() != null) {
+ return new BitmappedObjectReachabilityChecker(ow);
+ }
+
+ return new PedestrianObjectReachabilityChecker(ow);
+ }
+
+ /**
+ * Get the commit-graph for this repository if available.
+ * <p>
+ * The commit graph can be created/modified/deleted while the repository is
+ * open and specific implementations decide when to refresh it.
+ *
+ * @return the commit-graph or empty if the commit-graph does not exist or
+ * is invalid; always returns empty when core.commitGraph is false
+ * (default is
+ * {@value org.eclipse.jgit.lib.CoreConfig#DEFAULT_COMMIT_GRAPH_ENABLE}).
+ *
+ * @throws IOException
+ * if it cannot open any of the underlying commit graph.
+ *
+ * @since 6.5
+ */
+ public Optional<CommitGraph> getCommitGraph() throws IOException {
+ return Optional.empty();
+ }
+
+ /**
+ * Get the {@link org.eclipse.jgit.lib.ObjectInserter} from which this
+ * reader was created using {@code inserter.newReader()}
+ *
+ * @return the {@link org.eclipse.jgit.lib.ObjectInserter} from which this
+ * reader was created using {@code inserter.newReader()}, or null if
+ * this reader was not created from an inserter.
+ * @since 4.4
+ */
+ @Nullable
+ public ObjectInserter getCreatedFromInserter() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
* Release any resources used by this reader.
* <p>
* A reader that has been released can be used again, but may need to be
@@ -430,7 +551,139 @@ public abstract class ObjectReader implements AutoCloseable {
* @since 4.0
*/
@Override
- public void close() {
- // Do nothing.
+ public abstract void close();
+
+ /**
+ * Sets the threshold at which a file will be streamed rather than loaded
+ * entirely into memory
+ *
+ * @param threshold
+ * the new threshold
+ * @since 4.6
+ */
+ public void setStreamFileThreshold(int threshold) {
+ streamFileThreshold = threshold;
+ }
+
+ /**
+ * Returns the threshold at which a file will be streamed rather than loaded
+ * entirely into memory
+ *
+ * @return the threshold in bytes
+ * @since 4.6
+ */
+ public int getStreamFileThreshold() {
+ return streamFileThreshold;
+ }
+
+ /**
+ * Wraps a delegate ObjectReader.
+ *
+ * @since 4.4
+ */
+ public abstract static class Filter extends ObjectReader {
+ /**
+ * Get delegate ObjectReader to handle all processing
+ *
+ * @return delegate ObjectReader to handle all processing.
+ * @since 4.4
+ */
+ protected abstract ObjectReader delegate();
+
+ @Override
+ public ObjectReader newReader() {
+ return delegate().newReader();
+ }
+
+ @Override
+ public AbbreviatedObjectId abbreviate(AnyObjectId objectId)
+ throws IOException {
+ return delegate().abbreviate(objectId);
+ }
+
+ @Override
+ public AbbreviatedObjectId abbreviate(AnyObjectId objectId, int len)
+ throws IOException {
+ return delegate().abbreviate(objectId, len);
+ }
+
+ @Override
+ public Collection<ObjectId> resolve(AbbreviatedObjectId id)
+ throws IOException {
+ return delegate().resolve(id);
+ }
+
+ @Override
+ public boolean has(AnyObjectId objectId) throws IOException {
+ return delegate().has(objectId);
+ }
+
+ @Override
+ public boolean has(AnyObjectId objectId, int typeHint) throws IOException {
+ return delegate().has(objectId, typeHint);
+ }
+
+ @Override
+ public ObjectLoader open(AnyObjectId objectId)
+ throws MissingObjectException, IOException {
+ return delegate().open(objectId);
+ }
+
+ @Override
+ public ObjectLoader open(AnyObjectId objectId, int typeHint)
+ throws MissingObjectException, IncorrectObjectTypeException,
+ IOException {
+ return delegate().open(objectId, typeHint);
+ }
+
+ @Override
+ public Set<ObjectId> getShallowCommits() throws IOException {
+ return delegate().getShallowCommits();
+ }
+
+ @Override
+ public <T extends ObjectId> AsyncObjectLoaderQueue<T> open(
+ Iterable<T> objectIds, boolean reportMissing) {
+ return delegate().open(objectIds, reportMissing);
+ }
+
+ @Override
+ public long getObjectSize(AnyObjectId objectId, int typeHint)
+ throws MissingObjectException, IncorrectObjectTypeException,
+ IOException {
+ return delegate().getObjectSize(objectId, typeHint);
+ }
+
+ @Override
+ public <T extends ObjectId> AsyncObjectSizeQueue<T> getObjectSize(
+ Iterable<T> objectIds, boolean reportMissing) {
+ return delegate().getObjectSize(objectIds, reportMissing);
+ }
+
+ @Override
+ public void setAvoidUnreachableObjects(boolean avoid) {
+ delegate().setAvoidUnreachableObjects(avoid);
+ }
+
+ @Override
+ public BitmapIndex getBitmapIndex() throws IOException {
+ return delegate().getBitmapIndex();
+ }
+
+ @Override
+ public Optional<CommitGraph> getCommitGraph() throws IOException{
+ return delegate().getCommitGraph();
+ }
+
+ @Override
+ @Nullable
+ public ObjectInserter getCreatedFromInserter() {
+ return delegate().getCreatedFromInserter();
+ }
+
+ @Override
+ public void close() {
+ delegate().close();
+ }
}
}