Example usage for java.lang.invoke MethodHandle bindTo

List of usage examples for java.lang.invoke MethodHandle bindTo

Introduction

In this page you can find the example usage for java.lang.invoke MethodHandle bindTo.

Prototype

public MethodHandle bindTo(Object x) 

Source Link

Document

Binds a value x to the first argument of a method handle, without invoking it.

Usage

From source file:de.zib.sfs.WrappedFSDataInputStream.java

/**
 * Gets the datanode that was last read from as a string. Should be called
 * after the first read operation has been performed.
 * //w  w w .ja  va 2 s.c om
 * @return "->" + hostname of the datanode, or empty string if the
 *         information is not available
 */
private String getDatanodeHostNameString() {
    if (this.datanodeHostnameSupplier == null) {
        if (this.in instanceof HdfsDataInputStream) {
            // call Hadoop's method directly
            final HdfsDataInputStream hdfsIn = (HdfsDataInputStream) this.in;
            if (hdfsIn.getCurrentDatanode() != null) {
                this.datanodeHostnameSupplier = () -> hdfsIn.getCurrentDatanode().getHostName();
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Using datanodeHostNameSupplier from Hadoop.");
                }
            } else {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("datanodeHostNameSupplier from Hadoop has no DataNode information.");
                }
                this.datanodeHostnameSupplier = () -> "";
            }
        } else {
            try {
                // Check if there's an appropriately named method available
                // that returns the hostname of the current node that is
                // being read from. Using the lambda factory provides almost
                // direct invocation performance.
                MethodHandles.Lookup methodHandlesLookup = MethodHandles.lookup();

                // try this stream or the one it wraps
                Method getCurrentDatanodeHostNameMethod = null;
                InputStream bindToStream = null;
                try {
                    getCurrentDatanodeHostNameMethod = this.in.getClass()
                            .getDeclaredMethod("getCurrentDatanodeHostName");
                    bindToStream = this.in;
                } catch (NoSuchMethodException e) {
                    getCurrentDatanodeHostNameMethod = this.in.getWrappedStream().getClass()
                            .getDeclaredMethod("getCurrentDatanodeHostName");
                    bindToStream = this.in.getWrappedStream();
                }

                MethodHandle datanodeHostNameSupplierTarget = LambdaMetafactory.metafactory(methodHandlesLookup,
                        "get", MethodType.methodType(Supplier.class, bindToStream.getClass()),
                        MethodType.methodType(Object.class),
                        methodHandlesLookup.unreflect(getCurrentDatanodeHostNameMethod),
                        MethodType.methodType(Object.class)).getTarget();
                this.datanodeHostnameSupplier = (Supplier<String>) datanodeHostNameSupplierTarget
                        .bindTo(bindToStream).invoke();

                if (LOG.isDebugEnabled()) {
                    LOG.debug("Using 'getCurrentDatanodeHostName' as datanodeHostNameSupplier.");
                }
            } catch (Throwable t) {
                this.datanodeHostnameSupplier = () -> "";
                if (LOG.isDebugEnabled()) {
                    LOG.debug("No datanodeHostNameSupplier available.", t);
                }
            }
        }
    }

    // handle cases where we have to perform a reverse lookup if
    // hostname is an IP
    String dnHostname = this.datanodeHostnameSupplier.get();
    String cachedHostname = HOSTNAME_CACHE.get(dnHostname);
    if (cachedHostname == null) {
        try {
            // strip port if necessary
            int portIndex = dnHostname.indexOf(":");
            cachedHostname = InetAddress
                    .getByName(portIndex == -1 ? dnHostname : dnHostname.substring(0, portIndex)).getHostName();
        } catch (UnknownHostException e) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Could not determine hostname for " + dnHostname, e);
            }
            cachedHostname = "";
        }
        HOSTNAME_CACHE.put(dnHostname, cachedHostname);
    }
    return cachedHostname;
}