view wsgraph/model.py @ 17:1053290ba067

finish up this throwaway thing
author Jeff Hammel <jhammel@mozilla.com>
date Mon, 10 Dec 2012 17:36:31 -0800
parents ee45f44394a0
children 24d57daaca21
line wrap: on
line source

from abc import abstractmethod
from copy import deepcopy
from utils import isiterable

class GraphModel(object):

    @abstractmethod
    def node(self, name, **values):
        """
        get or set a node

        When setting a node, a value of `None` will pop the value from
        the nodal values
        """
        # TODO: values should not be **kwargs as you could conceivably want
        # to set a node or edge to an empty dict
        # Instead, should be (self, name, values=None)

    @abstractmethod
    def nodes(self):
        """returns a list of all nodes"""

    @abstractmethod
    def edge(self, node1, node2, **values):
        """
        get or set edge from node1 to node2
        """

    @abstractmethod
    def edges(self):
        """returns a list of all edges"""

    def __getitem__(self, key):
        """
        if key is a basestring, return the node of that name;
        if key is a 2-tuple/list, return the edge of that name
        """

        if isinstance(key, basestring) or (not isiterable(key)):
            return self.node(key)
        else:
            return self.edge(*key)

    def __contains__(self, key):
        """
        if key is ..., returns if that node is in the graph
        if key is a 2-tuple/list, returns if the edge is in the graph
        """
        # XXX not necessarily the best implementation!
        if isinstance(key, basestring) or (not isiterable(key)):
            return key in self.nodes()
        else:
            return tuple(key) in self.edges()


class MemoryCache(GraphModel):
    """volatile in-memory representation of a graph"""

    def __init__(self):
        self._edges = {}
        self._nodes = {}

    def node(self, name, **values):
        if values:
            # setter
            self._nodes[name] = deepcopy(values)
        else:
            # getter
            # TODO: deepcopy
            return self._nodes.get(name, None)

    def nodes(self):
        return self._nodes.keys()

    def edge(self, node1, node2, **values):
        if values:
            # setter
            self._edges[(node1, node2)] = deepcopy(values)
        else:
            # getter
            # TODO: deepcopy
            return self._edges.get((node1, node2), None)

    def edges(self):
        return self._edges.keys()