-
Notifications
You must be signed in to change notification settings - Fork 9.1k
HADOOP-13230. S3A to optionally retain directory markers #2149
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
66cac81
93be7b6
f21b787
4ec17cd
c0320ef
cf86899
0eb7a65
62dfba3
5e2d025
85c92c1
52f7483
c3e2a6b
5273e87
6a246ea
2ed6e13
c9f12eb
54b85e9
11d9d68
bbeed7e
e24d42b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one | ||
| * or more contributor license agreements. See the NOTICE file | ||
| * distributed with this work for additional information | ||
| * regarding copyright ownership. The ASF licenses this file | ||
| * to you under the Apache License, Version 2.0 (the | ||
| * "License"); you may not use this file except in compliance | ||
| * with the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| package org.apache.hadoop.test; | ||
|
|
||
| import java.util.concurrent.Callable; | ||
|
|
||
| import org.assertj.core.description.Description; | ||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
|
|
||
| /** | ||
| * Extra classes to work with AssertJ. | ||
| * These are kept separate from {@link LambdaTestUtils} so there's | ||
| * no requirement for AssertJ to be on the classpath in that broadly | ||
| * used class. | ||
| */ | ||
| public final class AssertExtensions { | ||
|
|
||
| private static final Logger LOG = | ||
| LoggerFactory.getLogger(AssertExtensions.class); | ||
|
|
||
| private AssertExtensions() { | ||
| } | ||
|
|
||
| /** | ||
| * A description for AssertJ "describedAs" clauses which evaluates the | ||
| * lambda-expression only on failure. That must return a string | ||
| * or null/"" to be skipped. | ||
| * @param eval lambda expression to invoke | ||
| * @return a description for AssertJ | ||
| */ | ||
| public static Description dynamicDescription(Callable<String> eval) { | ||
| return new DynamicDescription(eval); | ||
| } | ||
|
|
||
| private static final class DynamicDescription extends Description { | ||
| private final Callable<String> eval; | ||
|
|
||
| private DynamicDescription(final Callable<String> eval) { | ||
| this.eval = eval; | ||
| } | ||
|
|
||
| @Override | ||
| public String value() { | ||
| try { | ||
| return eval.call(); | ||
| } catch (Exception e) { | ||
| LOG.warn("Failed to evaluate description: " + e); | ||
| LOG.debug("Evaluation failure", e); | ||
| // return null so that the description evaluation chain | ||
| // will skip this one | ||
| return null; | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -142,12 +142,27 @@ public FileStatusListingIterator createFileStatusListingIterator( | |
| Listing.FileStatusAcceptor acceptor, | ||
| RemoteIterator<S3AFileStatus> providedStatus) throws IOException { | ||
| return new FileStatusListingIterator( | ||
| new ObjectListingIterator(listPath, request), | ||
| createObjectListingIterator(listPath, request), | ||
| filter, | ||
| acceptor, | ||
| providedStatus); | ||
| } | ||
|
|
||
| /** | ||
| * Create an object listing iterator against a path, with a given | ||
| * list object request. | ||
| * @param listPath path of the listing | ||
| * @param request initial request to make | ||
| * @return the iterator | ||
| * @throws IOException IO Problems | ||
| */ | ||
| @Retries.RetryRaw | ||
| public ObjectListingIterator createObjectListingIterator( | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is this required, will there be some logic in the future other than creating the new object? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mukund is doing a lot of work on listing performance; I'm just trying to keep up with the changes with this and the io statistics patches. |
||
| final Path listPath, | ||
| final S3ListRequest request) throws IOException { | ||
| return new ObjectListingIterator(listPath, request); | ||
| } | ||
|
|
||
| /** | ||
| * Create a located status iterator over a file status iterator. | ||
| * @param statusIterator an iterator over the remote status entries | ||
|
|
@@ -194,8 +209,12 @@ public RemoteIterator<S3ALocatedFileStatus> getListFilesAssumingDir( | |
|
|
||
| String key = maybeAddTrailingSlash(pathToKey(path)); | ||
| String delimiter = recursive ? null : "/"; | ||
| LOG.debug("Requesting all entries under {} with delimiter '{}'", | ||
| key, delimiter); | ||
| if (recursive) { | ||
| LOG.debug("Recursive list of all entries under {}", key); | ||
| } else { | ||
| LOG.debug("Requesting all entries under {} with delimiter '{}'", | ||
| key, delimiter); | ||
| } | ||
| final RemoteIterator<S3AFileStatus> cachedFilesIterator; | ||
| final Set<Path> tombstones; | ||
| boolean allowAuthoritative = listingOperationCallbacks | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to have a
booleanvar here and return the value - I prefer that for the sake of readability but this will do as wellThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, the code already did that direct return