Source code for cybox.utils.caches

# Copyright (c) 2017, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.

[docs]class CacheMiss(Exception): """Item was not found in a cache.""" pass
class Cache(object): """Abstract class for storing and retrieving Objects and Observables.""" def put(self, value, id_=None): """Save a value in the cache. If `id_` is provided, this is the key used to save the item. Otherwise, if `value` has an `id_` attribute, it is used. Lastly, if no other ID can be determined, the cache provider is responsible for generating one. """ if not id_: try: id_ = value.id_ except AttributeError: id_ = self._generate_id() return self._save(value, id_) def _generate_id(self): raise NotImplementedError def _save(self, value, id_): """Private function to actually save the item. In some cases, the ID is determined in this step, so return it to the caller """ raise NotImplementedError def get(self, id_): """Retrieve a value from the cache""" raise NotImplementedError def count(self): """Return number of items in the cache""" raise NotImplementedError def clear(self): """Clear all items from the cache""" pass class DictCache(Cache): def __init__(self): self.__inner = {} self._next_id = 0 def _generate_id(self): # Find and unused integer ID. Note that this might not # correspond to the actual order items were entered while self._next_id in self.__inner: self._next_id += 1 return self._next_id def _save(self, value, id_): self.__inner[id_] = value return id_ def get(self, id_): try: return self.__inner[id_] except KeyError: raise CacheMiss def count(self): return len(self.__inner) def clear(self): self.__inner = {} # No need to reset _next_id # Singleton instance within this module. It is lazily instantiated, so simply # importing the utils module will not create the object. __cache = None def _get_cache(): """Return the `cybox.utils` module's global cache object. Only under rare circumstances should this function be called by external code. More likely, external code should initialize its own Cache object. The implicit, built-in global cache is used when parsing XML or JSON representations and dealing with internal references within a document. """ global __cache if not __cache: __cache = DictCache() return __cache
[docs]def cache_put(value, id_=None): """Save a value in the global cache""" new_id = _get_cache().put(value, id_) return new_id
[docs]def cache_get(id_): """Retrieve a value from the global cache""" return _get_cache().get(id_)
[docs]def cache_count(): """Get the number of items in the global cache""" return _get_cache().count()
[docs]def cache_clear(): """Clear the global cache""" _get_cache().clear()