UIDGenerator: better support for 32-bit machines
authorTim Starling <tstarling@wikimedia.org>
Thu, 18 Apr 2013 22:34:20 +0000 (08:34 +1000)
committerTim Starling <tstarling@wikimedia.org>
Thu, 18 Apr 2013 22:34:20 +0000 (08:34 +1000)
Replace one exception with another that is less likely. Integer
multiplication is exact up to the limit of the double precision
mantissa size, and wfBaseConvert() will work up to any size of string.
So it's not necessary to require bcmath/gmp to be installed. The modulo
operation is equivalent to truncation of the binary form.

Perhaps mantissa sizes will be extended before the year 144680, made
possible by improved computing hardware. The exception message should be
altered when such hardware becomes available.

Change-Id: I8116dac1958b5dbef977d3900973bf13be3d9d17

includes/UIDGenerator.php

index 6219b3d..20ec302 100644 (file)
@@ -315,25 +315,12 @@ class UIDGenerator {
         */
        protected function millisecondsSinceEpochBinary( array $time ) {
                list( $sec, $msec ) = $time;
-               if ( PHP_INT_SIZE >= 8 ) { // 64 bit integers
-                       $ts = ( 1000 * $sec + $msec );
-                       $id_bin = str_pad( decbin( $ts % pow( 2, 46 ) ), 46, '0', STR_PAD_LEFT );
-               } elseif ( extension_loaded( 'gmp' ) ) {
-                       $ts = gmp_mod( // wrap around
-                               gmp_add( gmp_mul( (string) $sec, (string) 1000 ), (string) $msec ),
-                               gmp_pow( '2', '46' )
-                       );
-                       $id_bin = str_pad( gmp_strval( $ts, 2 ), 46, '0', STR_PAD_LEFT );
-               } elseif ( extension_loaded( 'bcmath' ) ) {
-                       $ts = bcmod( // wrap around
-                               bcadd( bcmul( $sec, 1000 ), $msec ),
-                               bcpow( 2, 46 )
-                       );
-                       $id_bin = wfBaseConvert( $ts, 10, 2, 46 );
-               } else {
-                       throw new MWException( 'bcmath or gmp extension required for 32 bit machines.' );
+               $ts = 1000 * $sec + $msec;
+               if ( $ts > pow( 2, 52 ) ) {
+                       throw new MWException( __METHOD__ .
+                               ': sorry, this function doesn\'t work after the year 144680' );
                }
-               return $id_bin;
+               return substr( wfBaseConvert( $ts, 10, 2, 46 ), -46 );
        }
 
        /**