def Create(
            self,
            cls,
            category=None,
            # Override any of these for a custom configuration.
            start_empty=_unspecified,
            app_version=_unspecified):
        # Resolve namespace components.
        if start_empty is not _unspecified:
            start_empty = bool(start_empty)
        else:
            start_empty = self._start_empty
        if app_version is _unspecified:
            app_version = GetAppVersion()

        # Reserve & and = for namespace separators.
        for component in (category, app_version):
            if component and ('&' in component or '=' in component):
                raise ValueError('%s cannot be used in a namespace')

        namespace = '&'.join('%s=%s' % (key, value)
                             for key, value in (('class', cls.__name__),
                                                ('category', category),
                                                ('app_version', app_version))
                             if value is not None)

        if self._disable_wrappers:
            return self._store_type(namespace, start_empty=start_empty)

        if self._store_type is not None:
            chain = (self._store_type(namespace), )
        else:
            chain = (MemcacheObjectStore(namespace),
                     PersistentObjectStore(namespace))
        return CacheChainObjectStore(chain, start_empty=start_empty)
예제 #2
0
class InMemoryObjectStore(ObjectStore):
    def __init__(self, branch):
        self._branch = branch
        self._cache = {}
        self._object_store = MemcacheObjectStore()

    def _MakeNamespace(self, namespace):
        return 'ObjectStore.%s.%s' % (self._branch, namespace)

    def SetMulti(self, mapping, namespace, time=CACHE_TIMEOUT):
        namespace = self._MakeNamespace(namespace)
        for k, v in mapping.iteritems():
            if namespace not in self._cache:
                self._cache[namespace] = {}
            self._cache[namespace][k] = _CacheEntry(v, time)
            # TODO(cduvall): Use a batch set? App Engine kept throwing:
            # ValueError: Values may not be more than 1000000 bytes in length
            # for the batch set.
            self._object_store.Set(k, v, namespace, time=time)

    def GetMulti(self, keys, namespace, time=CACHE_TIMEOUT):
        namespace = self._MakeNamespace(namespace)
        keys = keys[:]
        mapping = {}
        if namespace not in self._cache:
            self._cache[namespace] = {}
        for key in keys:
            cache_entry = self._cache[namespace].get(key, None)
            if cache_entry is None or cache_entry.HasExpired():
                mapping[key] = None
            else:
                mapping[key] = cache_entry.value
                keys.remove(key)
        future = self._object_store.GetMulti(keys, namespace, time=time)
        return Future(delegate=_AsyncGetFuture(self._cache, time, namespace,
                                               future, mapping))

    def Delete(self, key, namespace):
        namespace = self._MakeNamespace(namespace)
        if namespace in self._cache and key in self._cache[namespace]:
            self._cache[namespace].pop(key)
        self._object_store.Delete(key, namespace)
 def Create(self, category=None, start_empty=False):
     '''Creates a new object store with the top namespace given in the
 constructor with an optional |category| for classes that need multiple
 object stores (e.g. one for stat and one for read).
 '''
     namespace = self._name
     if category is not None:
         assert not any(c.isdigit() for c in category)
         namespace = '%s/%s' % (namespace, category)
     if self._store_type is not None:
         return self._store_type(namespace, start_empty=start_empty)
     return CacheChainObjectStore(
         (MemcacheObjectStore(namespace), PersistentObjectStore(namespace)),
         start_empty=start_empty)
 def Create(self, version=None, category=None):
   '''Creates a new object store with the top namespace given in the
   constructor, at version |version|, with an optional |category| for classes
   that need multiple object stores (e.g. one for stat and one for read).
   '''
   namespace = self._name
   if category is not None:
     assert not any(c.isdigit() for c in category)
     namespace = '%s/%s' % (namespace, category)
   if version is not None:
     assert isinstance(version, int)
     namespace = '%s/%s' % (namespace, version)
   if self._store_type is not None:
     return self._store_type(namespace)
   return InMemoryObjectStore(MemcacheObjectStore(namespace))
예제 #5
0
 def __init__(self, branch):
     self._branch = branch
     self._cache = {}
     self._object_store = MemcacheObjectStore()