Cache return value of multiple calls.

        Args:
            key_pattern (str): the key pattern to use for generating
                               keys for caches of the decorated function.
            func (function): the function to call.
            all_args (list): a list of args to be used to make calls to
                             the function.
            timeout (int): the cache timeout

        Returns:
            A list of the return values of the calls.

        Example::

            def add(a, b):
                return a + b

            cache.map(key_pat, add, [(1, 2), (3, 4)]) == [3, 7]

def map(self, key_pattern, func, all_args, timeout=None):
        '''Cache return value of multiple calls.

        Args:
            key_pattern (str): the key pattern to use for generating
                               keys for caches of the decorated function.
            func (function): the function to call.
            all_args (list): a list of args to be used to make calls to
                             the function.
            timeout (int): the cache timeout

        Returns:
            A list of the return values of the calls.

        Example::

            def add(a, b):
                return a + b

            cache.map(key_pat, add, [(1, 2), (3, 4)]) == [3, 7]
        '''
        results = []
        keys = [
            make_key(key_pattern, func, args, {})
            for args in all_args
        ]
        cached = dict(zip(keys, self.get_many(keys)))
        cache_to_add = {}
        for key, args in zip(keys, all_args):
            val = cached[key]
            if val is None:
                val = func(*args)
                cache_to_add[key] = val if val is not None else NONE_RESULT
            if val == NONE_RESULT:
                val = None
            results.append(val)
        if cache_to_add:
            self.set_many(cache_to_add, timeout)
        return results