Make WordPress Core

Changeset 49212

Timestamp:
10/19/2020 09:49:58 PM (4 years ago)
Author:
helen
Message:

Multisite: More specific caching for get_dirsize.

Instead of one cache entry for all upload folders for a site on multisite, this now caches for each folder and invalidates that cache based on context. In multisite, this should speed up get_dirsize calls since older directories that are much less likely to change will no longer have the size recalculated.

Props janthiel, A5hleyRich, batmoo.
Fixes #19879.

Location:
trunk
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/file.php

    r49193 r49212  
    929929
    930930    if ( is_multisite() ) {
    931         delete_transient( 'dirsize_cache' );
     931        );
    932932    }
    933933
  • trunk/src/wp-includes/functions.php

    r49193 r49212  
    27402740    // Compute the URL.
    27412741    $url = $upload['url'] . "/$filename";
     2742
     2743
     2744
     2745
    27422746
    27432747    /** This filter is documented in wp-admin/includes/file.php */
     
    75617565 */
    75627566function get_dirsize( $directory, $max_execution_time = null ) {
    7563     $dirsize = get_transient( 'dirsize_cache' );
    7564 
    7565     if ( is_array( $dirsize ) && isset( $dirsize[ $directory ]['size'] ) ) {
    7566         return $dirsize[ $directory ]['size'];
    7567     }
    7568 
    7569     if ( ! is_array( $dirsize ) ) {
    7570         $dirsize = array();
    7571     }
    75727567
    75737568    // Exclude individual site directories from the total when checking the main site of a network,
    75747569    // as they are subdirectories and should not be counted.
    75757570    if ( is_multisite() && is_main_site() ) {
    7576         $dirsize[ $directory ]['size'] = recurse_dirsize( $directory, $directory . '/sites', $max_execution_time );
     7571        $ = recurse_dirsize( $directory, $directory . '/sites', $max_execution_time );
    75777572    } else {
    7578         $dirsize[ $directory ]['size'] = recurse_dirsize( $directory, null, $max_execution_time );
    7579     }
    7580 
    7581     set_transient( 'dirsize_cache', $dirsize, HOUR_IN_SECONDS );
    7582     return $dirsize[ $directory ]['size'];
     7573        $size = recurse_dirsize( $directory, null, $max_execution_time );
     7574    }
     7575
     7576    return $size;
    75837577}
    75847578
     
    75927586 * @since 4.3.0 $exclude parameter added.
    75937587 * @since 5.2.0 $max_execution_time parameter added.
     7588
    75947589 *
    75957590 * @param string       $directory          Full path of a directory.
     
    75987593 * @param int          $max_execution_time Maximum time to run before giving up. In seconds. The timeout is global
    75997594 *                                         and is measured from the moment WordPress started to load.
     7595
     7596
    76007597 * @return int|false|null Size in bytes if a valid directory. False if not. Null if timeout.
    76017598 */
    7602 function recurse_dirsize( $directory, $exclude = null, $max_execution_time = null ) {
     7599function recurse_dirsize( $directory, $exclude = null, $max_execution_time = null ) {
    76037600    $size = 0;
    76047601
    76057602    $directory = untrailingslashit( $directory );
     7603
     7604
     7605
     7606
     7607
     7608
     7609
     7610
     7611
     7612
     7613
    76067614
    76077615    if ( ! file_exists( $directory ) || ! is_dir( $directory ) || ! is_readable( $directory ) ) {
     
    76317639    }
    76327640
    7633     $handle = opendir( $directory );
    7634     if ( $handle ) {
    7635         while ( ( $file = readdir( $handle ) ) !== false ) {
    7636             $path = $directory . '/' . $file;
    7637             if ( '.' !== $file && '..' !== $file ) {
    7638                 if ( is_file( $path ) ) {
    7639                     $size += filesize( $path );
    7640                 } elseif ( is_dir( $path ) ) {
    7641                     $handlesize = recurse_dirsize( $path, $exclude, $max_execution_time );
    7642                     if ( $handlesize > 0 ) {
    7643                         $size += $handlesize;
     7641    /**
     7642    * Filters the amount of storage space used by one directory and all it's children, in megabytes.
     7643    * Return the actual used space to shortcircuit the recursive PHP file size calculation and use something else
     7644    * like a CDN API or native operating system tools for better performance
     7645    *
     7646    * @since 5.6.0
     7647    *
     7648    * @param int|false $space_used The amount of used space, in bytes. Default 0.
     7649    */
     7650    $size = apply_filters( 'calculate_current_dirsize', $size, $directory, $exclude, $max_execution_time, $directory_cache );
     7651
     7652    if ( 0 === $size ) {
     7653        $handle = opendir( $directory );
     7654        if ( $handle ) {
     7655            while ( ( $file = readdir( $handle ) ) !== false ) {
     7656                $path = $directory . '/' . $file;
     7657                if ( '.' !== $file && '..' !== $file ) {
     7658                    if ( is_file( $path ) ) {
     7659                        $size += filesize( $path );
     7660                    } elseif ( is_dir( $path ) ) {
     7661                        $handlesize = recurse_dirsize( $path, $exclude, $max_execution_time, $directory_cache );
     7662                        if ( $handlesize > 0 ) {
     7663                            $size += $handlesize;
     7664                        }
     7665                    }
     7666
     7667                    if ( $max_execution_time > 0 && microtime( true ) - WP_START_TIMESTAMP > $max_execution_time ) {
     7668                        // Time exceeded. Give up instead of risking a fatal timeout.
     7669                        $size = null;
     7670                        break;
    76447671                    }
    76457672                }
    7646 
    7647                 if ( $max_execution_time > 0 && microtime( true ) - WP_START_TIMESTAMP > $max_execution_time ) {
    7648                     // Time exceeded. Give up instead of risking a fatal timeout.
    7649                     $size = null;
    7650                     break;
    7651                 }
    76527673            }
    7653         }
    7654         closedir( $handle );
    7655     }
     7674            closedir( $handle );
     7675        }
     7676    }
     7677    $directory_cache[ $cache_path ] = $size;
     7678
     7679    // Only write the transient on the top level call and not on recursive calls
     7680    if ( $save_cache ) {
     7681        set_transient( 'dirsize_cache', $directory_cache );
     7682    }
     7683
    76567684    return $size;
     7685
     7686
     7687
     7688
     7689
     7690
     7691
     7692
     7693
     7694
     7695
     7696
     7697
     7698
     7699
     7700
     7701
     7702
     7703
     7704
     7705
     7706
     7707
     7708
     7709
     7710
     7711
     7712
     7713
     7714
     7715
     7716
     7717
     7718
     7719
     7720
     7721
     7722
     7723
     7724
     7725
     7726
     7727
     7728
    76577729}
    76587730
  • trunk/src/wp-includes/post.php

    r49193 r49212  
    59155915
    59165916    if ( is_multisite() ) {
    5917         delete_transient( 'dirsize_cache' );
     5917        );
    59185918    }
    59195919
Note: See TracChangeset for help on using the changeset viewer.