Source code for seccs.rc

"""Simple reference counter implementations."""
import abc


[docs]class BaseReferenceCounter(object): """Abstract base class for reference counters.""" __metaclass__ = abc.ABCMeta __slots__ = []
[docs] def inc(self, key): """Abstract increment interface. Args: key: Key whose reference counter shall be incremented. Returns: Number of references of key after increment. """ raise NotImplementedError
[docs] def dec(self, key): """Abstract decrement interface. Args: key: Key whose reference counter shall be decremented. Returns: Number of references of key after decrement. """ raise NotImplementedError
[docs] def get(self, key): """Abstract get interface. Args: key: Key whose reference counter shall be retrieved. Returns: Number of references of key. """ raise NotImplementedError
[docs]class NoReferenceCounter(BaseReferenceCounter): """Non-counting reference counter, always returns 1 for any key. Can be used to disable reference counting where a reference counter is required. """ __slots__ = []
[docs] def inc(self, key): """Increment interface. Returns: 1 """ return 1
[docs] def dec(self, key): """Decrement interface. Returns: 1 """ return 1
[docs] def get(self, key): """Get interface. Returns: 1 """ return 1
[docs]class DatabaseReferenceCounter(BaseReferenceCounter): """Database-backed reference counter. Uses a given database to store reference counters. The reference counter of an element `key` is stored as follows: * If its value is 0, `key` is not stored in the database. * If its value is > 0, its int value is stored in the database under `key`. Args: database: Database object with a dict-like interface, i.e., implementing the operations __getitem__, __setitem__ and __delitem__. """ __slots__ = ['_database'] def __init__(self, database): super(DatabaseReferenceCounter, self).__init__() self._database = database
[docs] def inc(self, key): """Incrementes reference counter of key. See :meth:`.BaseReferenceCounter.inc`. """ database = self._database database[key] = new_count = ( database[key] if key in database else 0) + 1 return new_count
[docs] def dec(self, key): """Decrementes reference counter of key. See :meth:`.BaseReferenceCounter.dec`. """ database = self._database new_count = database[key] - 1 if new_count == 0: del database[key] else: database[key] = new_count return new_count
[docs] def get(self, key): """Gets reference counter of key. See :meth:`.BaseReferenceCounter.get`. """ database = self._database if key in database: return database[key] else: return 0
[docs]class KeySuffixDatabaseReferenceCounter(DatabaseReferenceCounter): """Database-backed reference counter. Similar to :class:`.DatabaseReferenceCounter`, but the reference counter of a `key` is not stored directly under `key`, but under `key` || `suffix`. Args: database: Database object with a dict-like interface, i.e., implementing the operations __getitem__, __setitem__ and __delitem__. suffix: Suffix for keys. """ __slots__ = ['_suffix'] def __init__(self, database, suffix): super(KeySuffixDatabaseReferenceCounter, self).__init__(database) self._suffix = suffix
[docs] def inc(self, key): """Incrementes reference counter of key. See :meth:`.DatabaseReferenceCounter.inc`. """ return DatabaseReferenceCounter.inc(self, key + self._suffix)
[docs] def dec(self, key): """Decrementes reference counter of key. See :meth:`.DatabaseReferenceCounter.dec`. """ return DatabaseReferenceCounter.dec(self, key + self._suffix)
[docs] def get(self, key): """Gets reference counter of key. See :meth:`.DatabaseReferenceCounter.get`. """ return DatabaseReferenceCounter.get(self, key + self._suffix)