Repository: redis/redis-py
File: redis/cache.py (Python)

Code before:
                candidates.append(redis_key.encode("utf-8"))
            elif isinstance(redis_key, bytes):
                try:
                    candidates.append(redis_key.decode("utf-8"))
                except UnicodeDecodeError:
                    pass  # Non-UTF-8 bytes, skip str version

            for cache_key in self._cache:
                if any(candidate in cache_key.redis_keys for candidate in candidates):
                    keys_to_delete.append(cache_key)
                    response.append(True)

        for key in keys_to_delete:
            self._cache.pop(key)

        return response

    def flush(self) -> int:
        elem_count = len(self._cache)
        self._cache.clear()
        return elem_count

    def is_cachable(self, key: CacheKey) -> bool:
        return self._cache_config.is_allowed_to_cache(key.command)


class LRUPolicy(EvictionPolicyInterface):
    def __init__(self):
        self.cache = None

    @property
    def cache(self):
        return self._cache

    @cache.setter
    def cache(self, cache: CacheInterface):
        self._cache = cache

    @property
    def type(self) -> EvictionPolicyType:
        return EvictionPolicyType.time_based

    def evict_next(self) -> CacheKey:
        self._assert_cache()
        popped_entry = self._cache.collection.popitem(last=False)
        return popped_entry[0]

    def evict_many(self, count: int) -> List[CacheKey]:
        self._assert_cache()
        if count > len(self._cache.collection):
            raise ValueError("Evictions count is above cache size")

Review comment (performance):
This logic appends `True` to `response` for each cache key that matches, but it should append one boolean per input `redis_key`. If multiple cache keys match the same `redis_key`, this will append multiple `True` values, making the response list longer than the input list.

Code after:
            else:
                response.append(False)

        return response

    def delete_by_redis_keys(
        self, redis_keys: Union[List[bytes], List[str]]
    ) -> List[bool]:
        response = []
        keys_to_delete = []

        for redis_key in redis_keys:
            # Prepare both versions for lookup
            candidates = [redis_key]
            if isinstance(redis_key, str):
                candidates.append(redis_key.encode("utf-8"))
            elif isinstance(redis_key, bytes):
                try:
                    candidates.append(redis_key.decode("utf-8"))
                except UnicodeDecodeError:
                    pass  # Non-UTF-8 bytes, skip str version

            for cache_key in self._cache:
                if any(candidate in cache_key.redis_keys for candidate in candidates):
                    keys_to_delete.append(cache_key)
                    response.append(True)

        for key in keys_to_delete:
            self._cache.pop(key)

        return response

    def flush(self) -> int:
        elem_count = len(self._cache)
        self._cache.clear()
        return elem_count

    def is_cachable(self, key: CacheKey) -> bool:
        return self._cache_config.is_allowed_to_cache(key.command)


class LRUPolicy(EvictionPolicyInterface):
    def __init__(self):
        self.cache = None

    @property
    def cache(self):
        return self._cache

    @cache.setter
    def cache(self, cache: CacheInterface):