On 09/16/2013 01:32 PM, Doug Lea wrote:
On 09/16/2013 05:35 AM, Alan Bateman wrote:
On 15/09/2013 17:32, Paul Sandoz wrote:
Hi,

http://cr.openjdk.java.net/~psandoz/tl/JDK-8024253-tlr-seed/webrev/

Now that the hash seed functionality, which utilized ThreadLocalRandom, has been removed from Hashtable and WeakHashMap we can update TLR to use the same seed initialization functionality as SplittableRandom, which includes using SecureRandom if the system property "java.util.secureRandomSeed" is set to true.


Thanks. This just re-instates a change we had to hold off on
in last TLR updates because of the hash seed dependency.

Looks okay to me although it might be better to catch UHE rather than Exception.

The intent is to ignore any problem in getting hashed host name
short of a VM error. On the other hand, it is not nice to consume
any unexpected mysterious RunTimeException. A coin flip...

-Doug

Hi,

The InetAddress.getLocalHost() might throw SecurityException in some configurations (SecurityManager.checkConnect(localHostName, -1)). So perhaps, the call should be wrapped by AccessController.doPrivileged(...). But that's not so important. What worries me is that InetAddress.getLocalHost() involves name service look-up. It depends on configuration, but on my computer, it takes about 5s to evaluate the hostname -> IP mapping the first time the program is run. The OS seems to cache this for a minute or so, because when I re-run the test program, it only takes 10ms. After a minute, the OS cache seems to expire and it again takes 5s to evaluate.

It may be that I have a strange unusual configuration (the name -> IP mapping is performed by DNS service even for local host name), but I have no other obvious problems using my machine.

I tried the following alternative:

    private static long interfacesHash() {
        long hash = 0L;
        try {
Enumeration<NetworkInterface> ifcs = NetworkInterface.getNetworkInterfaces();
            while (ifcs.hasMoreElements()) {
                hash ^= interfaceHash(ifcs.nextElement());
            }
        } catch (Exception e) {
            // ignore
        }
        return hash;
    }

    private static long interfaceHash(NetworkInterface ni) {
        long hash = 0L;
        Enumeration<InetAddress> ipAddresses = ni.getInetAddresses();
        while (ipAddresses.hasMoreElements()) {
            hash ^= mix64(ipAddresses.nextElement().hashCode());
        }
        Enumeration<NetworkInterface> subNis = ni.getSubInterfaces();
        while (subNis.hasMoreElements()) {
            hash ^= interfaceHash(subNis.nextElement());
        }
        return hash;
    }


This iterates all interfaces (with sub-interfaces) on the machine and XORs together the mix64-ed hashes of their IP addresses. It does't do any name service look-up and on my machine (with one ethernet and a loopback interface) it runs about 6-10x faster than InetAddress.getLocalHost() (that's when InetAddress.getLocalHost() runs fast - the OS caches the mapping):

InetAddress.getLocalHost() ~ 7-10 ms
interfacesHash() ~ 0.5-1.2ms

Note that in order to gain as much seed as possible from interfacesHash(), it should also be wrapped by AccessController.doPrivileged(...)

NetworkInterface also has one method called getHardwareAddress(). This might me interesting too...


Regards, Peter

Reply via email to