resourceloader: Use MD4 to compute file hash rather than SHA1
authorOri Livneh <ori@wikimedia.org>
Wed, 16 Sep 2015 23:51:53 +0000 (16:51 -0700)
committerOri.livneh <ori@wikimedia.org>
Fri, 18 Sep 2015 22:26:55 +0000 (22:26 +0000)
The hash value generated by ResourceLoaderModule::safeFileHash() is used for
versioning and cache invalidation, so a cryptographic hash function is not
necessary. We can get better performance by using MD4.

Wikimedia on-CPU time over 24 hours of safeFileHash() in load.php:
* 6.68% with safeFileHash using SHA1 (day 1)
* 7.07% with safeFileHash using SHA1 (day 2)
* 2.84% with safeFileHash using MD4 (day 3)

Change-Id: I6ff728f1240268517c0f03e0823129316bc901cb

includes/resourceloader/ResourceLoaderModule.php

index 1243f23..1a4d1f1 100644 (file)
@@ -849,16 +849,22 @@ abstract class ResourceLoaderModule {
        }
 
        /**
-        * Safe version of sha1_file(), which doesn't throw a PHP warning if the file doesn't exist.
-        * Defaults to empty string.
+        * Compute a non-cryptographic string hash of a file's contents.
+        * If the file does not exist or cannot be read, returns an empty string.
         *
+        * @since 1.26 Uses MD4 instead of SHA1.
         * @param string $filePath File path
         * @return string Hash
         */
        protected static function safeFileHash( $filePath ) {
                MediaWiki\suppressWarnings();
-               $hash = sha1_file( $filePath ) ?: '';
+               $contents = file_get_contents( $filePath );
                MediaWiki\restoreWarnings();
+               if ( $contents !== false ) {
+                       $hash = hash( 'md4', $contents );
+               } else {
+                       $hash = '';
+               }
                return $hash;
        }
 }