diff --git a/oslo_cache/backends/dictionary.py b/oslo_cache/backends/dictionary.py index dd845bbb..352b63d3 100644 --- a/oslo_cache/backends/dictionary.py +++ b/oslo_cache/backends/dictionary.py @@ -55,18 +55,32 @@ class DictCacheBackend(api.CacheBackend): return value + def get_multi(self, keys): + """Retrieves the value for a list of keys.""" + return [self.get(key) for key in keys] + def set(self, key, value): """Sets the value for a key. + Expunges expired keys during each set. :param key: dictionary key :param value: value associated with the key """ + self.set_multi({key: value}) + + def set_multi(self, mapping): + """Set multiple values in the cache. + Expunges expired keys during each set. + + :param mapping: dictionary with key/value pairs + """ self._clear() timeout = 0 if self.expiration_time > 0: timeout = timeutils.utcnow_ts() + self.expiration_time - self.cache[key] = (value, timeout) + for key, value in mapping.items(): + self.cache[key] = (value, timeout) def delete(self, key): """Deletes the value associated with the key if it exists. @@ -75,6 +89,14 @@ class DictCacheBackend(api.CacheBackend): """ self.cache.pop(key, None) + def delete_multi(self, keys): + """Deletes the value associated with each key in list if it exists. + + :param keys: list of dictionary keys + """ + for key in keys: + self.cache.pop(key, None) + def _clear(self): """Expunges expired keys.""" now = timeutils.utcnow_ts() diff --git a/oslo_cache/tests/test_dict_backend.py b/oslo_cache/tests/test_dict_backend.py index 4b2fe75c..be3ddb1a 100644 --- a/oslo_cache/tests/test_dict_backend.py +++ b/oslo_cache/tests/test_dict_backend.py @@ -88,6 +88,27 @@ class CacheDictBackendTest(test_cache.BaseTestCase): self.assertIs(NO_VALUE, self.region.get('key2')) self.assertEqual('value3', self.region.get('key3')) + def test_dict_backend_multi_keys_in_one_call(self): + single_value = 'Test Value' + single_key = 'testkey' + multi_values = {'key1': 1, 'key2': 2, 'key3': 3} + + self.region.set(single_key, single_value) + self.assertEqual(single_value, self.region.get(single_key)) + + self.region.delete(single_key) + self.assertEqual(NO_VALUE, self.region.get(single_key)) + + self.region.set_multi(multi_values) + cached_values = self.region.get_multi(multi_values.keys()) + for value in multi_values.values(): + self.assertIn(value, cached_values) + self.assertEqual(len(multi_values.values()), len(cached_values)) + + self.region.delete_multi(multi_values.keys()) + for value in self.region.get_multi(multi_values.keys()): + self.assertEqual(NO_VALUE, value) + def test_dict_backend_rewrite_value(self): self.region.set(KEY, 'value1') self.region.set(KEY, 'value2')