def _get_unlocked(self, key, default=None): now = timeutils.utcnow_ts() try: timeout, value = self._cache[key] except KeyError: return (0, default) if timeout and now >= timeout: # NOTE(flaper87): Record expired, # remove it from the cache but catch # KeyError and ValueError in case # _purge_expired removed this key already. try: del self._cache[key] except KeyError: pass try: # NOTE(flaper87): Keys with ttl == 0 # don't exist in the _keys_expires dict self._keys_expires[timeout].remove(key) except (KeyError, ValueError): pass return (0, default) return (timeout, value)
def _exists_unlocked(self, key): now = timeutils.utcnow_ts() try: timeout = self._cache[key][0] return not timeout or now <= timeout except KeyError: return False
def _set_unlocked(self, key, value, ttl=0): expires_at = 0 if ttl != 0: expires_at = timeutils.utcnow_ts() + ttl self._cache[key] = (expires_at, value) if expires_at: self._keys_expires[expires_at].add(key)
def _incr_append(self, key, other): with lockutils.lock(key): timeout, value = self._get_unlocked(key) if value is None: return None ttl = timeutils.utcnow_ts() - timeout new_value = value + other self._set_unlocked(key, new_value, ttl) return new_value
def _purge_expired(self): """Removes expired keys from the cache.""" now = timeutils.utcnow_ts() for timeout in sorted(self._keys_expires.keys()): # NOTE(flaper87): If timeout is greater # than `now`, stop the iteration, remaining # keys have not expired. if now < timeout: break # NOTE(flaper87): Unset every key in # this set from the cache if its timeout # is equal to `timeout`. (The key might # have been updated) for subkey in self._keys_expires.pop(timeout): try: if self._cache[subkey][0] == timeout: del self._cache[subkey] except KeyError: continue