Put filter spec information in a dedicated object

This increases type-safety and is ground work for support of the
"tree:<depth>" filter.

Change-Id: Id19eacdcdaddb9132064c642f6d554b1060efe9f
Signed-off-by: Matthew DeVore <matvore@gmail.com>
This commit is contained in:
Matthew DeVore 2019-03-15 18:57:04 -07:00
parent cc714d3bbb
commit cc9ca71a16
9 changed files with 89 additions and 43 deletions

View File

@ -193,7 +193,7 @@ public void testRecvWantsFilter()
assertThat(request.getWantIds(), assertThat(request.getWantIds(),
hasOnlyObjectIds("4624442d68ee402a94364191085b77137618633e", hasOnlyObjectIds("4624442d68ee402a94364191085b77137618633e",
"f900c8326a43303685c46b279b9f70411bff1a4b")); "f900c8326a43303685c46b279b9f70411bff1a4b"));
assertEquals(13000, request.getFilterBlobLimit()); assertEquals(13000, request.getFilterSpec().getBlobLimit());
} }
} }

View File

@ -232,7 +232,7 @@ public void testFetchWithNoneFilter() throws IOException {
ProtocolV2Parser parser = new ProtocolV2Parser( ProtocolV2Parser parser = new ProtocolV2Parser(
ConfigBuilder.start().allowFilter().done()); ConfigBuilder.start().allowFilter().done());
FetchV2Request request = parser.parseFetchRequest(pckIn); FetchV2Request request = parser.parseFetchRequest(pckIn);
assertEquals(0, request.getFilterBlobLimit()); assertEquals(0, request.getFilterSpec().getBlobLimit());
} }
@Test @Test
@ -243,7 +243,7 @@ public void testFetchWithBlobSizeFilter() throws IOException {
ProtocolV2Parser parser = new ProtocolV2Parser( ProtocolV2Parser parser = new ProtocolV2Parser(
ConfigBuilder.start().allowFilter().done()); ConfigBuilder.start().allowFilter().done());
FetchV2Request request = parser.parseFetchRequest(pckIn); FetchV2Request request = parser.parseFetchRequest(pckIn);
assertEquals(15, request.getFilterBlobLimit()); assertEquals(15, request.getFilterSpec().getBlobLimit());
} }
@Test @Test

View File

@ -62,7 +62,7 @@ abstract class FetchRequest {
final Set<ObjectId> clientShallowCommits; final Set<ObjectId> clientShallowCommits;
final long filterBlobLimit; final FilterSpec filterSpec;
final Set<String> clientCapabilities; final Set<String> clientCapabilities;
@ -82,8 +82,8 @@ abstract class FetchRequest {
* how deep to go in the tree * how deep to go in the tree
* @param clientShallowCommits * @param clientShallowCommits
* commits the client has without history * commits the client has without history
* @param filterBlobLimit * @param filterSpec
* to exclude blobs on certain conditions * the filter spec
* @param clientCapabilities * @param clientCapabilities
* capabilities sent in the request * capabilities sent in the request
* @param deepenNotRefs * @param deepenNotRefs
@ -96,13 +96,14 @@ abstract class FetchRequest {
* agent as reported by the client in the request body * agent as reported by the client in the request body
*/ */
FetchRequest(@NonNull Set<ObjectId> wantIds, int depth, FetchRequest(@NonNull Set<ObjectId> wantIds, int depth,
@NonNull Set<ObjectId> clientShallowCommits, long filterBlobLimit, @NonNull Set<ObjectId> clientShallowCommits,
@NonNull FilterSpec filterSpec,
@NonNull Set<String> clientCapabilities, int deepenSince, @NonNull Set<String> clientCapabilities, int deepenSince,
@NonNull List<String> deepenNotRefs, @Nullable String agent) { @NonNull List<String> deepenNotRefs, @Nullable String agent) {
this.wantIds = requireNonNull(wantIds); this.wantIds = requireNonNull(wantIds);
this.depth = depth; this.depth = depth;
this.clientShallowCommits = requireNonNull(clientShallowCommits); this.clientShallowCommits = requireNonNull(clientShallowCommits);
this.filterBlobLimit = filterBlobLimit; this.filterSpec = requireNonNull(filterSpec);
this.clientCapabilities = requireNonNull(clientCapabilities); this.clientCapabilities = requireNonNull(clientCapabilities);
this.deepenSince = deepenSince; this.deepenSince = deepenSince;
this.deepenNotRefs = requireNonNull(deepenNotRefs); this.deepenNotRefs = requireNonNull(deepenNotRefs);
@ -137,10 +138,11 @@ Set<ObjectId> getClientShallowCommits() {
} }
/** /**
* @return the blob limit set in a "filter" line (-1 if not set) * @return the filter spec given in a "filter" line
*/ */
long getFilterBlobLimit() { @NonNull
return filterBlobLimit; FilterSpec getFilterSpec() {
return filterSpec;
} }
/** /**

View File

@ -42,6 +42,8 @@
*/ */
package org.eclipse.jgit.transport; package org.eclipse.jgit.transport;
import static java.util.Objects.requireNonNull;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
@ -57,9 +59,10 @@
final class FetchV0Request extends FetchRequest { final class FetchV0Request extends FetchRequest {
FetchV0Request(@NonNull Set<ObjectId> wantIds, int depth, FetchV0Request(@NonNull Set<ObjectId> wantIds, int depth,
@NonNull Set<ObjectId> clientShallowCommits, long filterBlobLimit, @NonNull Set<ObjectId> clientShallowCommits,
@NonNull FilterSpec filterSpec,
@NonNull Set<String> clientCapabilities, @Nullable String agent) { @NonNull Set<String> clientCapabilities, @Nullable String agent) {
super(wantIds, depth, clientShallowCommits, filterBlobLimit, super(wantIds, depth, clientShallowCommits, filterSpec,
clientCapabilities, 0, Collections.emptyList(), agent); clientCapabilities, 0, Collections.emptyList(), agent);
} }
@ -71,7 +74,7 @@ static final class Builder {
final Set<ObjectId> clientShallowCommits = new HashSet<>(); final Set<ObjectId> clientShallowCommits = new HashSet<>();
long filterBlobLimit = -1; FilterSpec filterSpec = FilterSpec.NO_FILTER;
final Set<String> clientCaps = new HashSet<>(); final Set<String> clientCaps = new HashSet<>();
@ -129,18 +132,18 @@ Builder setAgent(String clientAgent) {
} }
/** /**
* @param filterBlobLim * @param filter
* blob limit set in a "filter" line * the filter set in a filter line
* @return this builder * @return this builder
*/ */
Builder setFilterBlobLimit(long filterBlobLim) { Builder setFilterSpec(@NonNull FilterSpec filter) {
filterBlobLimit = filterBlobLim; filterSpec = requireNonNull(filter);
return this; return this;
} }
FetchV0Request build() { FetchV0Request build() {
return new FetchV0Request(wantIds, depth, clientShallowCommits, return new FetchV0Request(wantIds, depth, clientShallowCommits,
filterBlobLimit, clientCaps, agent); filterSpec, clientCaps, agent);
} }
} }

View File

@ -77,11 +77,12 @@ public final class FetchV2Request extends FetchRequest {
@NonNull Set<ObjectId> wantIds, @NonNull Set<ObjectId> wantIds,
@NonNull Set<ObjectId> clientShallowCommits, int deepenSince, @NonNull Set<ObjectId> clientShallowCommits, int deepenSince,
@NonNull List<String> deepenNotRefs, int depth, @NonNull List<String> deepenNotRefs, int depth,
long filterBlobLimit, @NonNull FilterSpec filterSpec,
boolean doneReceived, @NonNull Set<String> clientCapabilities, boolean doneReceived, @NonNull Set<String> clientCapabilities,
@Nullable String agent, @NonNull List<String> serverOptions) { @Nullable String agent, @NonNull List<String> serverOptions) {
super(wantIds, depth, clientShallowCommits, filterBlobLimit, super(wantIds, depth, clientShallowCommits, filterSpec,
clientCapabilities, deepenSince, deepenNotRefs, agent); clientCapabilities, deepenSince,
deepenNotRefs, agent);
this.peerHas = requireNonNull(peerHas); this.peerHas = requireNonNull(peerHas);
this.wantedRefs = requireNonNull(wantedRefs); this.wantedRefs = requireNonNull(wantedRefs);
this.doneReceived = doneReceived; this.doneReceived = doneReceived;
@ -149,7 +150,7 @@ static final class Builder {
int deepenSince; int deepenSince;
long filterBlobLimit = -1; FilterSpec filterSpec = FilterSpec.NO_FILTER;
boolean doneReceived; boolean doneReceived;
@ -268,12 +269,12 @@ int getDeepenSince() {
} }
/** /**
* @param filterBlobLim * @param filter
* set in a "filter" line * spec set in a "filter" line
* @return this builder * @return this builder
*/ */
Builder setFilterBlobLimit(long filterBlobLim) { Builder setFilterSpec(@NonNull FilterSpec filter) {
filterBlobLimit = filterBlobLim; filterSpec = requireNonNull(filter);
return this; return this;
} }
@ -322,7 +323,7 @@ Builder addServerOption(@NonNull String value) {
FetchV2Request build() { FetchV2Request build() {
return new FetchV2Request(peerHas, wantedRefs, wantIds, return new FetchV2Request(peerHas, wantedRefs, wantIds,
clientShallowCommits, deepenSince, deepenNotRefs, clientShallowCommits, deepenSince, deepenNotRefs,
depth, filterBlobLimit, doneReceived, clientCapabilities, depth, filterSpec, doneReceived, clientCapabilities,
agent, Collections.unmodifiableList(serverOptions)); agent, Collections.unmodifiableList(serverOptions));
} }
} }

View File

@ -49,24 +49,31 @@
import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.JGitText;
/** /**
* Utility code for dealing with filter lines. * Represents either a filter specified in a protocol "filter" line, or a
* placeholder to indicate no filtering.
*
* @since 5.4
*/ */
final class FilterSpec { public final class FilterSpec {
private FilterSpec() {} private final long blobLimit;
/* private FilterSpec(long blobLimit) {
this.blobLimit = blobLimit;
}
/**
* Process the content of "filter" line from the protocol. It has a shape * Process the content of "filter" line from the protocol. It has a shape
* like "blob:none" or "blob:limit=N", with limit a positive number. * like "blob:none" or "blob:limit=N", with limit a positive number.
* *
* @param filterLine * @param filterLine
* the content of the "filter" line in the protocol * the content of the "filter" line in the protocol
* @return N, the limit, defaulting to 0 if "none" * @return a FilterSpec representing the given filter
* @throws PackProtocolException * @throws PackProtocolException
* invalid filter because due to unrecognized format or * invalid filter because due to unrecognized format or
* negative/non-numeric filter. * negative/non-numeric filter.
*/ */
static long parseFilterLine(String filterLine) public static FilterSpec fromFilterLine(String filterLine)
throws PackProtocolException { throws PackProtocolException {
long blobLimit = -1; long blobLimit = -1;
@ -92,7 +99,40 @@ static long parseFilterLine(String filterLine)
JGitText.get().invalidFilter, filterLine)); JGitText.get().invalidFilter, filterLine));
} }
return new FilterSpec(blobLimit);
}
/**
* @param blobLimit
* the blob limit in a "blob:[limit]" or "blob:none" filter line
* @return a filter spec which filters blobs above a certain size
*/
static FilterSpec withBlobLimit(long blobLimit) {
if (blobLimit < 0) {
throw new IllegalArgumentException(
"blobLimit cannot be negative: " + blobLimit); //$NON-NLS-1$
}
return new FilterSpec(blobLimit);
}
/**
* A placeholder that indicates no filtering.
*/
public static final FilterSpec NO_FILTER = new FilterSpec(-1);
/**
* @return -1 if this filter does not filter blobs based on size, or a
* non-negative integer representing the max size of blobs to allow
*/
public long getBlobLimit() {
return blobLimit; return blobLimit;
} }
/**
* @return true if this filter doesn't filter out anything
*/
public boolean isNoOp() {
return blobLimit == -1;
}
} }

View File

@ -130,7 +130,7 @@ FetchV0Request recvWants(PacketLineIn pckIn)
} }
filterReceived = true; filterReceived = true;
reqBuilder.setFilterBlobLimit(FilterSpec.parseFilterLine(arg)); reqBuilder.setFilterSpec(FilterSpec.fromFilterLine(arg));
continue; continue;
} }

View File

@ -207,7 +207,7 @@ FetchV2Request parseFetchRequest(PacketLineIn pckIn)
JGitText.get().tooManyFilters); JGitText.get().tooManyFilters);
} }
filterReceived = true; filterReceived = true;
reqBuilder.setFilterBlobLimit(FilterSpec.parseFilterLine( reqBuilder.setFilterSpec(FilterSpec.fromFilterLine(
line.substring(OPTION_FILTER.length() + 1))); line.substring(OPTION_FILTER.length() + 1)));
} else { } else {
throw new PackProtocolException(MessageFormat throw new PackProtocolException(MessageFormat

View File

@ -1536,7 +1536,7 @@ public long getFilterBlobLimit() {
if (currentRequest == null) { if (currentRequest == null) {
throw new RequestNotYetReadException(); throw new RequestNotYetReadException();
} }
return currentRequest.getFilterBlobLimit(); return currentRequest.getFilterSpec().getBlobLimit();
} }
/** /**
@ -2098,11 +2098,11 @@ private void sendPack(final boolean sideband,
accumulator); accumulator);
try { try {
pw.setIndexDisabled(true); pw.setIndexDisabled(true);
if (req.getFilterBlobLimit() >= 0) { if (req.getFilterSpec().isNoOp()) {
pw.setFilterBlobLimit(req.getFilterBlobLimit());
pw.setUseCachedPacks(false);
} else {
pw.setUseCachedPacks(true); pw.setUseCachedPacks(true);
} else {
pw.setFilterBlobLimit(req.getFilterSpec().getBlobLimit());
pw.setUseCachedPacks(false);
} }
pw.setUseBitmaps( pw.setUseBitmaps(
req.getDepth() == 0 req.getDepth() == 0