This is an automated email from the ASF dual-hosted git repository.

stevel pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hadoop-api-shim.git

commit fc3b60ee4479e812ead37a47f8f4837307db802e
Author: Steve Loughran <ste...@cloudera.com>
AuthorDate: Fri Jul 28 17:29:50 2023 +0100

    PARQUET-2171. Vector IO through self-contained shim classes.
    
    Takes the vector IO shim code from the hadoop-shim library and
    reimplements in through the DynMethods class.
    
    Needs
    * lower level tests of behaviour
    * review of exception handling/unwrapping.
---
 .../fs/shim/impl/FSDataInputStreamShimImpl.java    | 10 ++-
 .../hadoop/fs/shim/impl/FileRangeBridge.java       | 81 ++++++++++++++--------
 .../hadoop/fs/shim/impl/FileSystemShimImpl.java    |  5 +-
 .../hadoop/fs/shim/impl/ShimReflectionSupport.java | 10 +--
 4 files changed, 64 insertions(+), 42 deletions(-)

diff --git 
a/hadoop-api-shim/src/main/java/org/apache/hadoop/fs/shim/impl/FSDataInputStreamShimImpl.java
 
b/hadoop-api-shim/src/main/java/org/apache/hadoop/fs/shim/impl/FSDataInputStreamShimImpl.java
index f1b535e..45df066 100644
--- 
a/hadoop-api-shim/src/main/java/org/apache/hadoop/fs/shim/impl/FSDataInputStreamShimImpl.java
+++ 
b/hadoop-api-shim/src/main/java/org/apache/hadoop/fs/shim/impl/FSDataInputStreamShimImpl.java
@@ -25,7 +25,6 @@ import java.nio.ByteBuffer;
 import java.util.List;
 import java.util.Locale;
 import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.Function;
 import java.util.function.IntFunction;
 import java.util.stream.Collectors;
 
@@ -103,15 +102,14 @@ public class FSDataInputStreamShimImpl
   public FSDataInputStreamShimImpl(
       final FSDataInputStream instance) {
     super(FSDataInputStream.class, instance);
-    byteBufferPositionedRead = loadInvocation(getClazz(), READ,
-        Integer.class,
+    byteBufferPositionedRead = loadInvocation(getClazz(), Integer.class, READ,
         Long.class, ByteBuffer.class);
 
     boolean bbrb = instance.hasCapability(PREADBYTEBUFFER)
         && byteBufferPositionedRead.available();
     if (bbrb) {
       byteBufferPositionedReadFully = loadInvocation(getClazz(),
-          READ_FULLY, Void.class, Long.class, ByteBuffer.class);
+          Void.class, READ_FULLY, Long.class, ByteBuffer.class);
       isByteBufferPositionedReadAvailable = new AtomicBoolean(true);
     } else {
       byteBufferPositionedReadFully = unavailable(READ_FULLY);
@@ -122,8 +120,8 @@ public class FSDataInputStreamShimImpl
     isByteBufferReadableAvailable = new AtomicBoolean(
         instance.getWrappedStream() instanceof ByteBufferReadable);
     if (FILE_RANGE_BRIDGE.bridgeAvailable()) {
-      readVectored = loadInvocation(getClazz(), READ_VECTORED,
-          Void.class, List.class, Function.class);
+      readVectored = loadInvocation(getClazz(), Void.class, READ_VECTORED,
+          List.class, IntFunction.class);
     } else {
       readVectored = unavailable(READ_VECTORED);
     }
diff --git 
a/hadoop-api-shim/src/main/java/org/apache/hadoop/fs/shim/impl/FileRangeBridge.java
 
b/hadoop-api-shim/src/main/java/org/apache/hadoop/fs/shim/impl/FileRangeBridge.java
index 1cc7afd..04c118b 100644
--- 
a/hadoop-api-shim/src/main/java/org/apache/hadoop/fs/shim/impl/FileRangeBridge.java
+++ 
b/hadoop-api-shim/src/main/java/org/apache/hadoop/fs/shim/impl/FileRangeBridge.java
@@ -18,8 +18,6 @@
 
 package org.apache.hadoop.fs.shim.impl;
 
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
 import java.nio.ByteBuffer;
 import java.util.concurrent.CompletableFuture;
 
@@ -29,7 +27,6 @@ import org.slf4j.LoggerFactory;
 import org.apache.hadoop.fs.shim.api.VectorFileRange;
 
 import static java.util.Objects.requireNonNull;
-import static org.apache.hadoop.fs.shim.impl.ShimReflectionSupport.ctor;
 import static 
org.apache.hadoop.fs.shim.impl.ShimReflectionSupport.loadInvocation;
 
 /**
@@ -38,15 +35,27 @@ import static 
org.apache.hadoop.fs.shim.impl.ShimReflectionSupport.loadInvocatio
 public final class FileRangeBridge {
   private static final Logger LOG = 
LoggerFactory.getLogger(FileRangeBridge.class);
 
-  public static final String CLASSNAME = 
"org.apache.hadoop.fs.impl.FileRangeImpl";
+  /**
+   * Name of the {@code FileRange} interface.
+   */
+  public static final String CLASSNAME = "org.apache.hadoop.fs.FileRange";
 
-  private final Class<?> fileRangeClass;
+  /**
+   * Class of the interface {@link #CLASSNAME}, if loaded.
+   * This can resolve all methods in this interface and super-interfaces,
+   * including static ones.
+   */
+  private final Class<?> fileRangeInterface;
   private final Invocation<Long> _getOffset;
   private final Invocation<Integer> _getLength;
   private final Invocation<CompletableFuture<ByteBuffer>> _getData;
   private final Invocation<Void> _setData;
   private final Invocation<Object> _getReference;
-  private final Constructor<?> newFileRange;
+
+  /**
+   * new FileRange(long, long, Object)
+   */
+  private final Invocation<Object> createFileRange;
 
   /**
    * Constructor.
@@ -61,59 +70,67 @@ public final class FileRangeBridge {
       LOG.debug("No {}", CLASSNAME);
       cl = null;
     }
-    fileRangeClass = cl;
+    fileRangeInterface = cl;
     // class found, so load the methods
-    _getOffset = loadInvocation(fileRangeClass, "getOffset", Long.class);
-    _getLength= loadInvocation(fileRangeClass, "getLength", Integer.class);
-    _getData = loadInvocation(fileRangeClass, "getData", null);
-    _setData = loadInvocation(fileRangeClass, "setData", Void.class, 
CompletableFuture.class);
-    _getReference = loadInvocation(fileRangeClass, "getReference", 
Object.class);
+    _getOffset = loadInvocation(fileRangeInterface, Long.class, "getOffset");
+    _getLength = loadInvocation(fileRangeInterface, Integer.class, 
"getLength");
+    _getData = loadInvocation(fileRangeInterface, null, "getData");
+    _setData = loadInvocation(fileRangeInterface, Void.class, "setData", 
CompletableFuture.class);
+    _getReference = loadInvocation(fileRangeInterface, Object.class, 
"getReference");
+
+    // static interface method to create an instance.
+    createFileRange = loadInvocation(fileRangeInterface, Object.class, 
"createFileRange", Long.class,
+        Integer.class, Object.class);
 
-    newFileRange = ctor(fileRangeClass, Long.class, Integer.class, 
Object.class);
   }
 
   /**
    * Is the bridge available.
+   *
    * @return true iff the bridge is present.
    */
   public boolean bridgeAvailable() {
-    return fileRangeClass != null;
+    return fileRangeInterface != null;
   }
 
   /**
    * Get the file range class.
+   *
    * @return the file range implementation class, if present.
    */
-  public Class<?> getFileRangeClass() {
-    return fileRangeClass;
+  public Class<?> getFileRangeInterface() {
+    return fileRangeInterface;
   }
 
   /**
    * Instantiate.
+   *
+   * @param offset offset in file
+   * @param length length of data to read.
+   * @param reference nullable reference to store in the range.
    * @return a VectorFileRange wrapping a FileRange
+   *
    * @throws RuntimeException if the range cannot be instantiated
    * @throws IllegalStateException if the API is not available.
    */
-  public WrappedFileRange newWrappedFileRange(long offset, int length) {
+  public VectorFileRange createFileRange(long offset, int length, final Object 
reference) {
     Preconditions.checkState(bridgeAvailable(), "FileRange not available");
-    try {
-      return new WrappedFileRange(newFileRange.newInstance(offset, length));
-    } catch (InstantiationException | IllegalAccessException | 
InvocationTargetException e) {
-      throw new RuntimeException("failed to instantiate a FileRange object: " 
+ e,
-          e);
-    }
+    return new WrappedFileRange(createFileRange.invokeUnchecked(null, offset, 
length, reference));
   }
 
   /**
-   * Convert a range to an instance of FileRange
-   * @param in input
+   * Convert a range to an instance of FileRange.
+   * The offset, length and reference of the input range
+   * all passed into the createFileRange() method.
+   * @param range input range
+   *
    * @return a converted instance
    */
-  public Object toFileRange(VectorFileRange in) {
+  public Object toFileRange(VectorFileRange range) {
     // create a new wrapped file range, fill in and then
     // get the instance
-    final WrappedFileRange wfr = newWrappedFileRange(in.getOffset(), 
in.getLength());
-    wfr.setData(in.getData());
+    final WrappedFileRange wfr = createFileRange(
+        range.getOffset(), range.getLength(), range.getReference());
     return wfr.getInstance();
   }
 
@@ -124,10 +141,15 @@ public final class FileRangeBridge {
    * API to interact with these.
    */
   private class WrappedFileRange implements VectorFileRange {
-    final Object instance;
+
+    /**
+     * The wrapped range.
+     */
+    private final Object instance;
 
     /**
      * Instantiate.
+     *
      * @param instance non null instance.
      */
     private WrappedFileRange(final Object instance) {
@@ -162,6 +184,7 @@ public final class FileRangeBridge {
 
     /**
      * Get the instance.
+     *
      * @return the instance.
      */
     public Object getInstance() {
diff --git 
a/hadoop-api-shim/src/main/java/org/apache/hadoop/fs/shim/impl/FileSystemShimImpl.java
 
b/hadoop-api-shim/src/main/java/org/apache/hadoop/fs/shim/impl/FileSystemShimImpl.java
index f00b40d..cab57f4 100644
--- 
a/hadoop-api-shim/src/main/java/org/apache/hadoop/fs/shim/impl/FileSystemShimImpl.java
+++ 
b/hadoop-api-shim/src/main/java/org/apache/hadoop/fs/shim/impl/FileSystemShimImpl.java
@@ -118,11 +118,10 @@ public class FileSystemShimImpl extends 
AbstractAPIShim<FileSystem>
     // the simpler methods.
     Class<FileSystem> clazz = getClazz();
 
-    hasPathCapabilityMethod = loadInvocation(clazz, "hasPathCapability",
-        Boolean.class,
+    hasPathCapabilityMethod = loadInvocation(clazz, Boolean.class, 
"hasPathCapability",
         Path.class, String.class);
 
-    msyncMethod = loadInvocation(clazz, "msync", Void.class);
+    msyncMethod = loadInvocation(clazz, Void.class, "msync");
 
     executeOpenFile = new OpenFileThroughAvailableOperation();
   }
diff --git 
a/hadoop-api-shim/src/main/java/org/apache/hadoop/fs/shim/impl/ShimReflectionSupport.java
 
b/hadoop-api-shim/src/main/java/org/apache/hadoop/fs/shim/impl/ShimReflectionSupport.java
index 1c4a196..804dfa6 100644
--- 
a/hadoop-api-shim/src/main/java/org/apache/hadoop/fs/shim/impl/ShimReflectionSupport.java
+++ 
b/hadoop-api-shim/src/main/java/org/apache/hadoop/fs/shim/impl/ShimReflectionSupport.java
@@ -121,21 +121,23 @@ public final class ShimReflectionSupport {
    */
   public static <T> Invocation<T> getInvocation(
       Class<?> source, String name, Class<?>... parameterTypes) {
-    return (Invocation<T>) loadInvocation(source, name, null, parameterTypes);
+    return (Invocation<T>) loadInvocation(source, null, name, parameterTypes);
   }
 
   /**
    * Get an invocation from the source class, which will be unavailable() if
    * the class is null or the method isn't found.
-   * @param source source
-   * @param name method name
+   *
    * @param <T> return type
+   * @param source source
    * @param returnType return type class for the compiler to be happy
+   * @param name method name
    * @param parameterTypes parameters
+   *
    * @return the method or "unavailable"
    */
   public static <T> Invocation<T> loadInvocation(
-      Class<?> source, String name, Class<? extends T> returnType, Class<?>... 
parameterTypes) {
+      Class<?> source, Class<? extends T> returnType, String name, Class<?>... 
parameterTypes) {
     if (source == null) {
       return unavailable(name);
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscr...@hadoop.apache.org
For additional commands, e-mail: common-commits-h...@hadoop.apache.org

Reply via email to