Skip to content

Commit 677d2fd

Browse files
committed
PARQUET-2493. Reflection based use of hadoop WrappedIO class
in sync with ongoing hadoop pr, commit 3d7dc340c9a1 Change-Id: I868df6afb373d57179c9cb9d90164e71b0571faf
1 parent 8fb5421 commit 677d2fd

File tree

4 files changed

+503
-3
lines changed

4 files changed

+503
-3
lines changed

parquet-hadoop/src/main/java/org/apache/parquet/hadoop/util/HadoopInputFile.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.apache.hadoop.fs.FileStatus;
2525
import org.apache.hadoop.fs.FileSystem;
2626
import org.apache.hadoop.fs.Path;
27+
import org.apache.parquet.hadoop.util.wrapped.io.DynamicWrappedIO;
2728
import org.apache.parquet.io.InputFile;
2829
import org.apache.parquet.io.SeekableInputStream;
2930

@@ -72,7 +73,7 @@ public long getLength() {
7273

7374
@Override
7475
public SeekableInputStream newStream() throws IOException {
75-
return HadoopStreams.wrap(fs.open(stat.getPath()));
76+
return HadoopStreams.wrap(DynamicWrappedIO.openFile(fs, stat));
7677
}
7778

7879
@Override

parquet-hadoop/src/main/java/org/apache/parquet/hadoop/util/wrapped/io/BindingUtils.java

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818

1919
package org.apache.parquet.hadoop.util.wrapped.io;
2020

21+
import static org.apache.parquet.Preconditions.checkState;
22+
23+
import java.io.IOException;
24+
import java.io.UncheckedIOException;
25+
import java.util.function.Supplier;
2126
import org.apache.parquet.util.DynMethods;
2227
import org.slf4j.Logger;
2328
import org.slf4j.LoggerFactory;
@@ -31,6 +36,35 @@ final class BindingUtils {
3136

3237
private BindingUtils() {}
3338

39+
/**
40+
* Load a class by name.
41+
* @param cl classloader to use.
42+
* @param className classname
43+
* @return the class or null if it could not be loaded.
44+
*/
45+
public static Class<?> loadClass(ClassLoader cl, String className) {
46+
try {
47+
return cl.loadClass(className);
48+
} catch (ClassNotFoundException e) {
49+
LOG.debug("No class {}", className, e);
50+
return null;
51+
}
52+
}
53+
54+
/**
55+
* Load a class by name.
56+
* @param className classname
57+
* @return the class or null if it could not be loaded.
58+
*/
59+
public static Class<?> loadClass(String className) {
60+
try {
61+
return Class.forName(className);
62+
} catch (ClassNotFoundException e) {
63+
LOG.debug("No class {}", className, e);
64+
return null;
65+
}
66+
}
67+
3468
/**
3569
* Get an invocation from the source class, which will be unavailable() if
3670
* the class is null or the method isn't found.
@@ -65,6 +99,30 @@ static <T> DynMethods.UnboundMethod loadInvocation(
6599
}
66100
}
67101

102+
/**
103+
* Load a static method from the source class, which will be a noop() if
104+
* the class is null or the method isn't found.
105+
* If the class and method are not found, then an {@code IllegalStateException}
106+
* is raised on the basis that this means that the binding class is broken,
107+
* rather than missing/out of date.
108+
*
109+
* @param <T> return type
110+
* @param source source. If null, the method is a no-op.
111+
* @param returnType return type class (unused)
112+
* @param name method name
113+
* @param parameterTypes parameters
114+
*
115+
* @return the method or a no-op.
116+
* @throws IllegalStateException if the method is not static.
117+
*/
118+
public static <T> DynMethods.UnboundMethod loadStaticMethod(
119+
Class<?> source, Class<? extends T> returnType, String name, Class<?>... parameterTypes) {
120+
121+
final DynMethods.UnboundMethod method = loadInvocation(source, returnType, name, parameterTypes);
122+
checkState(method.isStatic(), "Method is not static %s", method);
123+
return method;
124+
}
125+
68126
/**
69127
* Create a no-op method.
70128
*
@@ -91,4 +149,40 @@ static boolean implemented(DynMethods.UnboundMethod... methods) {
91149
}
92150
return true;
93151
}
152+
153+
/**
154+
* Require a method to be available.
155+
* @param method method to probe
156+
* @throws UnsupportedOperationException if the method was not found.
157+
*/
158+
static void checkAvailable(DynMethods.UnboundMethod method) throws UnsupportedOperationException {
159+
if (method.isNoop()) {
160+
throw new UnsupportedOperationException("Unbound " + method);
161+
}
162+
}
163+
164+
/**
165+
* Is a method available?
166+
* @param method method to probe
167+
* @return true iff the method is found and loaded.
168+
*/
169+
static boolean available(DynMethods.UnboundMethod method) {
170+
return !method.isNoop();
171+
}
172+
173+
/**
174+
* Invoke the supplier, catching any {@code UncheckedIOException} raised,
175+
* extracting the inner IOException and rethrowing it.
176+
* @param call call to invoke
177+
* @return result
178+
* @param <T> type of result
179+
* @throws IOException if the call raised an IOException wrapped by an UncheckedIOException.
180+
*/
181+
static <T> T extractIOEs(Supplier<T> call) throws IOException {
182+
try {
183+
return call.get();
184+
} catch (UncheckedIOException e) {
185+
throw e.getCause();
186+
}
187+
}
94188
}

0 commit comments

Comments
 (0)