List of usage examples for java.lang.invoke MethodHandle bindTo
public MethodHandle bindTo(Object x)
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; }