¡@

Home 

OpenStack Study: backends.py

OpenStack Index

**** CubicPower OpenStack Study ****

# Copyright 2013 Red Hat, Inc.

#

# Licensed under the Apache License, Version 2.0 (the "License"); you may

# not use this file except in compliance with the License. You may obtain

# a copy of the License at

#

# http://www.apache.org/licenses/LICENSE-2.0

#

# Unless required by applicable law or agreed to in writing, software

# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT

# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the

# License for the specific language governing permissions and limitations

# under the License.

import abc

import six

NOTSET = object()

@six.add_metaclass(abc.ABCMeta)

**** CubicPower OpenStack Study ****

class BaseCache(object):

"""Base Cache Abstraction

:params parsed_url: Parsed url object.

:params options: A dictionary with configuration parameters

for the cache. For example:

-

**** CubicPower OpenStack Study ****

    def __init__(self, parsed_url, options=None):

        self._parsed_url = parsed_url

        self._options = options or {}

        self._default_ttl = int(self._options.get('default_ttl', 0))

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def _set(self, key, value, ttl, not_exists=False):

        """Implementations of this class have to override this method."""

**** CubicPower OpenStack Study ****

    def set(self, key, value, ttl, not_exists=False):

        """Sets or updates a cache entry

        NOTE: Thread-safety is required and has to be

        guaranteed by the backend implementation.

        :params key: Item key as string.

        :type key: `unicode string`

        :params value: Value to assign to the key. This

                       can be anything that is handled

                       by the current backend.

        :params ttl: Key's timeout in seconds. 0 means

                     no timeout.

        :type ttl: int

        :params not_exists: If True, the key will be set

                            if it doesn't exist. Otherwise,

                            it'll always be set.

        :type not_exists: bool

        :returns: True if the operation succeeds, False otherwise.

        """

        if ttl is None:

            ttl = self._default_ttl

        return self._set(key, value, ttl, not_exists)

**** CubicPower OpenStack Study ****

    def __setitem__(self, key, value):

        self.set(key, value, self._default_ttl)

**** CubicPower OpenStack Study ****

    def setdefault(self, key, value):

        """Sets the key value to `value` if it doesn't exist

        :params key: Item key as string.

        :type key: `unicode string`

        :params value: Value to assign to the key. This

                       can be anything that is handled

                       by the current backend.

        """

        try:

            return self[key]

        except KeyError:

            self[key] = value

            return value

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def _get(self, key, default):

        """Implementations of this class have to override this method."""

**** CubicPower OpenStack Study ****

    def get(self, key, default=None):

        """Gets one item from the cache

        NOTE: Thread-safety is required and it has to be

        guaranteed by the backend implementation.

        :params key: Key for the item to retrieve

                     from the cache.

        :params default: The default value to return.

        :returns: `key`'s value in the cache if it exists,

                  otherwise `default` should be returned.

        """

        return self._get(key, default)

**** CubicPower OpenStack Study ****

    def __getitem__(self, key):

        value = self.get(key, NOTSET)

        if value is NOTSET:

            raise KeyError

        return value

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def __delitem__(self, key):

        """Removes an item from cache.

        NOTE: Thread-safety is required and it has to be

        guaranteed by the backend implementation.

        :params key: The key to remove.

        :returns: The key value if there's one

        """

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def _clear(self):

        """Implementations of this class have to override this method."""

**** CubicPower OpenStack Study ****

    def clear(self):

        """Removes all items from the cache.

        NOTE: Thread-safety is required and it has to be

        guaranteed by the backend implementation.

        """

        return self._clear()

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def _incr(self, key, delta):

        """Implementations of this class have to override this method."""

**** CubicPower OpenStack Study ****

    def incr(self, key, delta=1):

        """Increments the value for a key

        :params key: The key for the value to be incremented

        :params delta: Number of units by which to increment

                       the value. Pass a negative number to

                       decrement the value.

        :returns: The new value

        """

        return self._incr(key, delta)

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def _append_tail(self, key, tail):

        """Implementations of this class have to override this method."""

**** CubicPower OpenStack Study ****

    def append_tail(self, key, tail):

        """Appends `tail` to `key`'s value.

        :params key: The key of the value to which

                     `tail` should be appended.

        :params tail: The list of values to append to the

                      original.

        :returns: The new value

        """

        if not hasattr(tail, "__iter__"):

            raise TypeError('Tail must be an iterable')

        if not isinstance(tail, list):

            # NOTE(flaper87): Make sure we pass a list

            # down to the implementation. Not all drivers

            # have support for generators, sets or other

            # iterables.

            tail = list(tail)

        return self._append_tail(key, tail)

**** CubicPower OpenStack Study ****

    def append(self, key, value):

        """Appends `value` to `key`'s value.

        :params key: The key of the value to which

                     `tail` should be appended.

        :params value: The value to append to the

                      original.

        :returns: The new value

        """

        return self.append_tail(key, [value])

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def __contains__(self, key):

        """Verifies that a key exists.

        :params key: The key to verify.

        :returns: True if the key exists,

                  otherwise False.

        """

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def _get_many(self, keys, default):

        """Implementations of this class have to override this method."""

        return ((k, self.get(k, default=default)) for k in keys)

**** CubicPower OpenStack Study ****

    def get_many(self, keys, default=NOTSET):

        """Gets keys' value from cache

        :params keys: List of keys to retrieve.

        :params default: The default value to return

                         for each key that is not in

                         the cache.

        :returns: A  generator of (key, value)

        """

        return self._get_many(keys, default)

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def _set_many(self, data, ttl):

        """Implementations of this class have to override this method."""

        for key, value in data.items():

            self.set(key, value, ttl=ttl)

**** CubicPower OpenStack Study ****

    def set_many(self, data, ttl=None):

        """Puts several items into the cache at once

        Depending on the backend, this operation may or may

        not be efficient. The default implementation calls

        set for each (key, value) pair passed, other backends

        support set_many operations as part of their protocols.

        :params data: A dictionary like {key: val} to store

                      in the cache.

        :params ttl: Key's timeout in seconds.

        """

        if ttl is None:

            ttl = self._default_ttl

        self._set_many(data, ttl)

**** CubicPower OpenStack Study ****

    def update(self, **kwargs):

        """Sets several (key, value) paris.

        Refer to the `set_many` docstring.

        """

        self.set_many(kwargs, ttl=self._default_ttl)

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def _unset_many(self, keys):

        """Implementations of this class have to override this method."""

        for key in keys:

            del self[key]

**** CubicPower OpenStack Study ****

    def unset_many(self, keys):

        """Removes several keys from the cache at once

        :params keys: List of keys to unset.

        """

        self._unset_many(keys)