Class PhiloxSupport


  • final class PhiloxSupport
    extends java.lang.Object
    Utility support for the Philox family of generators.

    Contains methods that use the java.lang.invoke package to call java.lang.Math functions for computing the high part of the 128-bit result of a multiply of two 64-bit longs. These methods may be supported by intrinsic calls to native operations if supported on the platform for a significant performance gain.

    Note

    This class is used specifically in the Philox4x64 generator which has a state update cycle which is performance dependent on the multiply of two unsigned long values. Other classes which use unsigned multiply and are not performance dependent on the method do not use this implementation (for example the LXM family of generators). This allows the multiply method to be adapted to the usage of Philox4x64 which always has the first argument as a negative constant.

    Since:
    1.7
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private static java.util.function.LongBinaryOperator UNSIGNED_MULTIPLY_HIGH
      Method to compute unsigned multiply high.
    • Constructor Summary

      Constructors 
      Modifier Constructor Description
      private PhiloxSupport()
      No instances.
    • Method Summary

      All Methods Static Methods Concrete Methods 
      Modifier and Type Method Description
      (package private) static java.lang.invoke.MethodHandle getMathMethod​(java.lang.String methodName)
      Gets the named method from the Math class.
      private static java.util.function.LongBinaryOperator getMathMultiplyHigh()
      Gets a method to compute the high 64-bits of an unsigned 64-bit multiplication using the Math multiplyHigh method from JDK 9.
      private static java.util.function.LongBinaryOperator getMathUnsignedMultiplyHigh()
      Gets a method to compute the high 64-bits of an unsigned 64-bit multiplication using the Math unsignedMultiplyHigh method from JDK 18.
      (package private) static boolean testUnsignedMultiplyHigh​(java.util.function.LongBinaryOperator op)
      Test the implementation of unsigned multiply high.
      (package private) static long unsignedMultiplyHigh​(long value1, long value2)
      Multiply the two values as if unsigned 64-bit longs to produce the high 64-bits of the 128-bit unsigned result.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • UNSIGNED_MULTIPLY_HIGH

        private static final java.util.function.LongBinaryOperator UNSIGNED_MULTIPLY_HIGH
        Method to compute unsigned multiply high. Uses:
        • java.lang.Math.unsignedMultiplyHigh if Java 18
        • java.lang.Math.multiplyHigh if Java 9
        • otherwise a default implementation.
    • Constructor Detail

      • PhiloxSupport

        private PhiloxSupport()
        No instances.
    • Method Detail

      • getMathUnsignedMultiplyHigh

        private static java.util.function.LongBinaryOperator getMathUnsignedMultiplyHigh()
        Gets a method to compute the high 64-bits of an unsigned 64-bit multiplication using the Math unsignedMultiplyHigh method from JDK 18.
        Returns:
        the method, or null
      • getMathMultiplyHigh

        private static java.util.function.LongBinaryOperator getMathMultiplyHigh()
        Gets a method to compute the high 64-bits of an unsigned 64-bit multiplication using the Math multiplyHigh method from JDK 9.
        Returns:
        the method, or null
      • getMathMethod

        static java.lang.invoke.MethodHandle getMathMethod​(java.lang.String methodName)
                                                    throws java.lang.NoSuchMethodException,
                                                           java.lang.IllegalAccessException
        Gets the named method from the Math class.

        The look-up assumes the named method accepts two long arguments and returns a long.

        Parameters:
        methodName - Method name.
        Returns:
        the method
        Throws:
        java.lang.NoSuchMethodException - if the method does not exist
        java.lang.IllegalAccessException - if the method cannot be accessed
      • testUnsignedMultiplyHigh

        static boolean testUnsignedMultiplyHigh​(java.util.function.LongBinaryOperator op)
        Test the implementation of unsigned multiply high. It is assumed the invocation of the method may raise an IllegalStateException if it cannot be invoked.
        Parameters:
        op - Method implementation.
        Returns:
        True if the method can be called to generate the expected result
      • unsignedMultiplyHigh

        static long unsignedMultiplyHigh​(long value1,
                                         long value2)
        Multiply the two values as if unsigned 64-bit longs to produce the high 64-bits of the 128-bit unsigned result. The first argument is assumed to be negative.

        This method uses a MethodHandle to call Java functions added since Java 8 to the Math class:

        • java.lang.Math.unsignedMultiplyHigh if Java 18
        • java.lang.Math.multiplyHigh if Java 9
        • otherwise a default implementation.

        Warning

        For performance reasons this method assumes the first argument is negative. This allows some operations to be dropped if running on Java 9 to 17.

        Parameters:
        value1 - the first value (must be negative)
        value2 - the second value
        Returns:
        the high 64-bits of the 128-bit result