def invalidate(self, key: KT) -> None: """Delete a key, or tree of entries If the cache is backed by a regular dict, then "key" must be of the right type for this cache If the cache is backed by a TreeCache, then "key" must be a tuple, but may be of lower cardinality than the TreeCache - in which case the whole subtree is deleted. """ self.check_thread() self.cache.del_multi(key) # if we have a pending lookup for this key, remove it from the # _pending_deferred_cache, which will (a) stop it being returned # for future queries and (b) stop it being persisted as a proper entry # in self.cache. entry = self._pending_deferred_cache.pop(key, None) # run the invalidation callbacks now, rather than waiting for the # deferred to resolve. if entry: # _pending_deferred_cache.pop should either return a CacheEntry, or, in the # case of a TreeCache, a dict of keys to cache entries. Either way calling # iterate_tree_cache_entry on it will do the right thing. for entry in iterate_tree_cache_entry(entry): entry.invalidate()
def cache_del_multi(key: KT) -> None: """ This will only work if constructed with cache_type=TreeCache """ popped = cache.pop(key) if popped is None: return # for each deleted node, we now need to remove it from the linked list # and run its callbacks. for leaf in iterate_tree_cache_entry(popped): delete_node(leaf)
def invalidate_many(self, key): self.check_thread() if not isinstance(key, tuple): raise TypeError("The cache key must be a tuple not %r" % (type(key), )) self.sequence += 1 self.cache.del_multi(key) entry_dict = self._pending_deferred_cache.pop(key, None) if entry_dict is not None: for entry in iterate_tree_cache_entry(entry_dict): entry.invalidate()
def invalidate_many(self, key): self.check_thread() if not isinstance(key, tuple): raise TypeError("The cache key must be a tuple not %r" % (type(key),)) self.cache.del_multi(key) # if we have a pending lookup for this key, remove it from the # _pending_deferred_cache, as above entry_dict = self._pending_deferred_cache.pop(key, None) if entry_dict is not None: for entry in iterate_tree_cache_entry(entry_dict): entry.invalidate()
def test_pop_mixedlevel(self): cache = TreeCache() cache[("a", "a")] = "AA" cache[("a", "b")] = "AB" cache[("b", "a")] = "BA" self.assertEquals(cache.get(("a", "a")), "AA") popped = cache.pop(("a", )) self.assertEquals(cache.get(("a", "a")), None) self.assertEquals(cache.get(("a", "b")), None) self.assertEquals(cache.get(("b", "a")), "BA") self.assertEquals(len(cache), 1) self.assertEquals({"AA", "AB"}, set(iterate_tree_cache_entry(popped)))
def invalidate_many(self, key): self.check_thread() if not isinstance(key, tuple): raise TypeError( "The cache key must be a tuple not %r" % (type(key),) ) self.cache.del_multi(key) # if we have a pending lookup for this key, remove it from the # _pending_deferred_cache, as above entry_dict = self._pending_deferred_cache.pop(key, None) if entry_dict is not None: for entry in iterate_tree_cache_entry(entry_dict): entry.invalidate()
def cache_del_multi(key: KT) -> None: """Delete an entry, or tree of entries If the LruCache is backed by a regular dict, then "key" must be of the right type for this cache If the LruCache is backed by a TreeCache, then "key" must be a tuple, but may be of lower cardinality than the TreeCache - in which case the whole subtree is deleted. """ popped = cache.pop(key, None) if popped is None: return # for each deleted node, we now need to remove it from the linked list # and run its callbacks. for leaf in iterate_tree_cache_entry(popped): delete_node(leaf)