WordPress.org

Make WordPress Core

Ticket #14254: 14254-batch-ids.diff

File 14254-batch-ids.diff, 4.0 KB (added by jipmoors, 5 years ago)

Batching meta ids when updating cache

  • src/wp-includes/meta.php

     
    785785                return false;
    786786        }
    787787
    788         $column = sanitize_key($meta_type . '_id');
     788        $column = sanitize_key( $meta_type . '_id' );
    789789
    790         if ( !is_array($object_ids) ) {
    791                 $object_ids = preg_replace('|[^0-9,]|', '', $object_ids);
    792                 $object_ids = explode(',', $object_ids);
     790        if ( ! is_array( $object_ids ) ) {
     791                $object_ids = preg_replace( '|[^0-9,]|', '', $object_ids );
     792                $object_ids = explode( ',', $object_ids );
    793793        }
    794794
    795         $object_ids = array_map('intval', $object_ids);
     795        $object_ids = array_map( 'intval', $object_ids );
    796796
    797797        $cache_key = $meta_type . '_meta';
    798         $ids = array();
    799         $cache = array();
     798        $ids       = array();
     799        $cache     = array();
    800800        foreach ( $object_ids as $id ) {
    801801                $cached_object = wp_cache_get( $id, $cache_key );
    802                 if ( false === $cached_object )
     802                if ( false === $cached_object ) {
    803803                        $ids[] = $id;
    804                 else
    805                         $cache[$id] = $cached_object;
     804                } else {
     805                        $cache[ $id ] = $cached_object;
     806                }
    806807        }
    807808
    808         if ( empty( $ids ) )
     809        if ( empty( $ids ) ) {
    809810                return $cache;
     811        }
    810812
    811         // Get meta info
    812         $id_list = join( ',', $ids );
    813         $id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id';
    814         $meta_list = $wpdb->get_results( "SELECT $column, meta_key, meta_value FROM $table WHERE $column IN ($id_list) ORDER BY $id_column ASC", ARRAY_A );
     813        // Batch IDs when there are over 250
    815814
    816         if ( !empty($meta_list) ) {
    817                 foreach ( $meta_list as $metarow) {
    818                         $mpid = intval($metarow[$column]);
    819                         $mkey = $metarow['meta_key'];
    820                         $mval = $metarow['meta_value'];
     815        $batch_size = apply_filters( 'meta_cache_batch_size', 250 );
     816        $chunks = array_chunk( $ids, $batch_size );
    821817
    822                         // Force subkeys to be array type:
    823                         if ( !isset($cache[$mpid]) || !is_array($cache[$mpid]) )
    824                                 $cache[$mpid] = array();
    825                         if ( !isset($cache[$mpid][$mkey]) || !is_array($cache[$mpid][$mkey]) )
    826                                 $cache[$mpid][$mkey] = array();
     818        while ( ! empty( $chunks ) ) {
     819                $batch = array_shift( $chunks );
    827820
    828                         // Add a value to the current pid/key:
    829                         $cache[$mpid][$mkey][] = $mval;
     821                // Get meta info
     822                $id_list   = join( ',', $batch );
     823                $id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id';
     824                $meta_list = $wpdb->get_results( "SELECT $column, meta_key, meta_value FROM $table WHERE $column IN ($id_list) ORDER BY $id_column ASC", ARRAY_A );
     825
     826                if ( ! empty( $meta_list ) ) {
     827                        foreach ( $meta_list as $metarow ) {
     828                                $mpid = intval( $metarow[ $column ] );
     829                                $mkey = $metarow['meta_key'];
     830                                $mval = $metarow['meta_value'];
     831
     832                                // Force subkeys to be array type:
     833                                if ( ! isset( $cache[ $mpid ] ) || ! is_array( $cache[ $mpid ] ) ) {
     834                                        $cache[ $mpid ] = array();
     835                                }
     836                                if ( ! isset( $cache[ $mpid ][ $mkey ] ) || ! is_array( $cache[ $mpid ][ $mkey ] ) ) {
     837                                        $cache[ $mpid ][ $mkey ] = array();
     838                                }
     839
     840                                // Add a value to the current pid/key:
     841                                $cache[ $mpid ][ $mkey ][] = $mval;
     842                        }
    830843                }
    831844        }
    832845
    833846        foreach ( $ids as $id ) {
    834                 if ( ! isset($cache[$id]) )
    835                         $cache[$id] = array();
    836                 wp_cache_add( $id, $cache[$id], $cache_key );
     847                if ( ! isset( $cache[ $id ] ) ) {
     848                        $cache[ $id ] = array();
     849                }
     850                wp_cache_add( $id, $cache[ $id ], $cache_key );
    837851        }
    838852
    839853        return $cache;
  • tests/phpunit/tests/cache.php

     
    305305                // Make sure $fake_key is not stored
    306306                $this->assertFalse( wp_cache_get( $fake_key ) );
    307307        }
     308
     309        function test_meta_cache_update() {
     310
     311                add_filter('meta_cache_batch_size', array($this, 'set_meta_cache_batch_size'));
     312
     313                $postIDs = array('1','2','3','4');
     314                $cache_results = array(
     315                        '1' => array(),
     316                        '2' => array(),
     317                        '3' => array(),
     318                        '4' => array()
     319                );
     320
     321                $this->assertEquals( $cache_results, update_meta_cache('post', $postIDs) );
     322        }
     323
     324        function set_meta_cache_batch_size($size) {
     325                return 2;
     326        }
    308327}