<commit_before><?php
/*
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * and is licensed under the MIT license. For more information, see
 * <http://www.doctrine-project.org>.
 */

namespace Doctrine\Common\Cache;

/**
 * Cache provider that allows to easily chain multiple cache providers
 *
 * @author <NAME> <<EMAIL>>
 */
class ChainCache extends CacheProvider
{
    /**
     * @var CacheProvider[]
     */
    private $cacheProviders = [];

    /**
     * Constructor
     *
     * @param CacheProvider[] $cacheProviders
     */
    public function __construct($cacheProviders = [])
    {
        $this->cacheProviders = $cacheProviders instanceof \Traversable
            ? iterator_to_array($cacheProviders, false)
            : array_values($cacheProviders);
    }

    /**
     * {@inheritDoc}
     */
    public function setNamespace($namespace)
    {
        parent::setNamespace($namespace);

        foreach ($this->cacheProviders as $cacheProvider) {
            $cacheProvider->setNamespace($namespace);
        }
    }

    /**
     * {@inheritDoc}
     */
    protected function doFetch($id)
    {
        foreach ($this->cacheProviders as $key => $cacheProvider) {
            if ($cacheProvider->doContains($id)) {
                $value = $cacheProvider->doFetch($id);

                // We populate all the previous cache layers (that are assumed to be faster)
                for ($subKey = $key - 1 ; $subKey >= 0 ; $subKey--) {
                    $this->cacheProviders[$subKey]->doSave($id, $value);
                }

                return $value;
            }
        }

        return false;
    }

    /**
     * {@inheritdoc}
     */
    protected function doFetchMultiple(array $keys)
    {
        $count = count($keys);
        $values = array();

        foreach ($this->cacheProviders as $key => $cacheProvider) {
            $values = $cacheProvider->doFetchMultiple($keys);

            // We populate all the previous cache layers (that are assumed to be faster)
            if (count($values) === $count) {
                for ($subKey = $key - 1 ; $subKey >= 0 ; $subKey--) {
                    $this->cacheProviders[$subKey]->doSaveMultiple($values);
                }

                return $values;
            }
        }

        return $values;
    }

    /**
     * {@inheritDoc}
     */
    protected function doContains($id)
    {
        foreach ($this->cacheProviders as $cacheProvider) {<commit_msg>#155 simplified traversal of cache providers when saving results of multi-fetches into faster chain cache entries<commit_after><?php
/*
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * and is licensed under the MIT license. For more information, see
 * <http://www.doctrine-project.org>.
 */

namespace Doctrine\Common\Cache;

/**
 * Cache provider that allows to easily chain multiple cache providers
 *
 * @author <NAME> <<EMAIL>>
 */
class ChainCache extends CacheProvider
{
    /**
     * @var CacheProvider[]
     */
    private $cacheProviders = [];

    /**
     * Constructor
     *
     * @param CacheProvider[] $cacheProviders
     */
    public function __construct($cacheProviders = [])
    {
        $this->cacheProviders = $cacheProviders instanceof \Traversable
            ? iterator_to_array($cacheProviders, false)
            : array_values($cacheProviders);
    }

    /**
     * {@inheritDoc}
     */
    public function setNamespace($namespace)
    {
        parent::setNamespace($namespace);

        foreach ($this->cacheProviders as $cacheProvider) {
            $cacheProvider->setNamespace($namespace);
        }
    }

    /**
     * {@inheritDoc}
     */
    protected function doFetch($id)
    {
        foreach ($this->cacheProviders as $key => $cacheProvider) {
            if ($cacheProvider->doContains($id)) {
                $value = $cacheProvider->doFetch($id);

                // We populate all the previous cache layers (that are assumed to be faster)
                for ($subKey = $key - 1 ; $subKey >= 0 ; $subKey--) {
                    $this->cacheProviders[$subKey]->doSave($id, $value);
                }

                return $value;
            }
        }

        return false;
    }

    /**
     * {@inheritdoc}
     */
    protected function doFetchMultiple(array $keys)
    {
        /* @var $traversedProviders CacheProvider[] */
        $traversedProviders = [];
        $keysCount          = count($keys);
        $fetchedValues      = [];

        foreach ($this->cacheProviders as $key => $cacheProvider) {
            $fetchedValues = $cacheProvider->doFetchMultiple($keys);

            // We populate all the previous cache layers (that are assumed to be faster)
            if (count($fetchedValues) === $keysCount) {
                foreach ($traversedProviders as $previousCacheProvider) {
                    $previousCacheProvider->doSaveMultiple($fetchedValues);
                }

                return $fetchedValues;
            }

            $traversedProviders[] = $cacheProvider;
        }

        return $fetchedValues;
    }

    /**
     * {@inheritDoc}
     */
    protected function doContains($id)
    {
        foreach ($this->cacheProviders as $cacheProvider) {
{'fraction_non_alphanumeric': 0.10535531883846491, 'fraction_numerical': 0.0013132934481249088, 'mean_word_length': 2.3614516920058852, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2876062', 'n_tokens_mistral': 1880, 'n_tokens_neox': 1717, 'n_words': 571}