Implement get/set/delete multiple keys for dictionary backend
For some Nova scenarios, we will need suppot for set_multi/get_multi/delete_multi for writing to either memcache or dictionary backend. So let's add support for operating on multiple keys. Note that if we don't implement this the default CacheBackend class throws NotImplementedError Closes-Bug: #1483322 Change-Id: I1aca9e65b3be038a507ced8dd039c5413d6c4ac2
This commit is contained in:
parent
72c9267874
commit
0a7c3bf46b
@ -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()
|
||||
|
@ -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')
|
||||
|
Loading…
Reference in New Issue
Block a user