backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / services / protocols / bgp / utils / circlist.py
diff --git a/ryu/build/lib.linux-armv7l-2.7/ryu/services/protocols/bgp/utils/circlist.py b/ryu/build/lib.linux-armv7l-2.7/ryu/services/protocols/bgp/utils/circlist.py
new file mode 100644 (file)
index 0000000..4a04f4f
--- /dev/null
@@ -0,0 +1,269 @@
+# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation.
+#
+# 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 six
+if six.PY3:
+    from sys import intern
+
+
+class CircularListType(object):
+    """Instances of this class represent a specific type of list.
+    Nodes are linked in a circular fashion, using attributes on the
+    nodes themselves.
+
+    Example:
+
+      ItemList = CircularListType(next_attr='_next',
+                                  prev_attr='_prev')
+
+      l = ItemList()
+      l.prepend(item)
+
+    The created list has the following properties:
+
+      - A node can be inserted O(1) time at the head, tail, or
+        after/before another specified node.
+
+      - A node can be removed in O(1) time from any list it may be on,
+        without providing a reference to the list.
+
+      - The current node in an iteration can be deleted safely.
+
+     """
+
+    class List(object):
+        """An object that represents a list.
+
+        This class is not expected to be used directly by clients. Rather, they
+        would use the 'create' method of a CircularListType object to create an
+        instance.
+        """
+
+        # Define the set of valid attributes so as to make the list
+        # head lightweight.
+        #
+        # We override __getattr__ and __setattr__ so as to store the
+        # the next and previous references on the list head in
+        # _next_slot_ and _prev_slot_ respectively.
+        __slots__ = ["list_type", "head", "_next_slot_",
+                     "_prev_slot_"]
+
+        def __init__(self, list_type):
+            self.list_type = list_type
+
+            # Save memory by using the List object itself as the head.
+            self.head = self
+            self.list_type.node_init(self.head)
+
+        def __getattr__(self, name):
+            if(name == self.list_type.next_name):
+                return self._next_slot_
+
+            if(name == self.list_type.prev_name):
+                return self._prev_slot_
+
+            raise AttributeError(name)
+
+        def __setattr__(self, name, value):
+            if(name in CircularListType.List.__slots__):
+                object.__setattr__(self, name, value)
+                return
+
+            if(name == self.list_type.next_name):
+                self._next_slot_ = value
+                return
+
+            if(name == self.list_type.prev_name):
+                self._prev_slot_ = value
+                return
+
+            raise AttributeError(name)
+
+        def is_empty(self):
+            return not self.list_type.node_is_on_list(self.head)
+
+        def clear(self):
+            """Remove all items from the list."""
+
+            # Make sure that all items are unlinked.
+            for node in self:
+                self.remove(node)
+
+        def is_on_list(self, node):
+            return self.list_type.node_is_on_list(node)
+
+        def append(self, node):
+            self.list_type.node_insert_before(self.head, node)
+
+        def prepend(self, node):
+            self.list_type.node_insert_after(self.head, node)
+
+        def __iter__(self):
+            return self.generator()
+
+        def remove(self, node):
+            """List the given node from the list.
+
+            Note that this does not verify that the node is on this
+            list. It could even be on a different list.
+            """
+            self.list_type.node_unlink(node)
+
+            self.list_type.node_del_attrs(node)
+
+        def pop_first(self):
+            """Remove the first item in the list and return it."""
+            node = self.list_type.node_next(self.head)
+            if(node is self.head):
+                return None
+
+            self.remove(node)
+            return node
+
+        def generator(self):
+            """Enables iteration over the list.
+
+            The current item can safely be removed from the list during
+            iteration.
+            """
+            # Keep a pointer to the next node when returning the
+            # current node. This allows the caller to remove the
+            # current node safely.
+            node = self.list_type.node_next(self.head)
+            next = self.list_type.node_next(node)
+            while(node is not self.head):
+                yield node
+
+                node = next
+                next = self.list_type.node_next(node)
+
+    #
+    # CircularListType methods
+    #
+
+    def __init__(self, next_attr_name=None, prev_attr_name=None):
+        """Initializes this list.
+
+        next_attr_name: The name of the attribute that holds a reference
+                        to the next item in the list.
+
+        prev_attr_name: the name of the attribute that holds a reference
+                        to the previous item in the list.
+        """
+
+        # Keep an interned version of the attribute names. This should
+        # speed up the process of looking up the attributes.
+        self.next_name = intern(next_attr_name)
+        self.prev_name = intern(prev_attr_name)
+
+    def create(self):
+        return CircularListType.List(self)
+
+    def __call__(self):
+        """Make a CircularListType instance look like a class by
+        creating a list object.
+        """
+        return self.create()
+
+    def node_init(self, node):
+        assert(not self.node_is_on_list(node))
+
+        # Set the node to point to itself as the previous and next
+        # entries.
+        self.node_set_next(node, node)
+        self.node_set_prev(node, node)
+
+    def node_next(self, node):
+        try:
+            return getattr(node, self.next_name)
+        except AttributeError:
+            return None
+
+    def node_set_next(self, node, next):
+        setattr(node, self.next_name, next)
+
+    def node_prev(self, node):
+        try:
+            return getattr(node, self.prev_name)
+        except AttributeError:
+            return None
+
+    def node_set_prev(self, node, prev):
+        setattr(node, self.prev_name, prev)
+
+    def node_del_attrs(self, node):
+        """Remove all attributes that are used for putting this node
+        on this type of list.
+        """
+        try:
+            delattr(node, self.next_name)
+            delattr(node, self.prev_name)
+        except AttributeError:
+            pass
+
+    def node_is_on_list(self, node):
+        """Returns True if this node is on *some* list.
+
+        A node is not on any list if it is linked to itself, or if it
+        does not have the next and/prev attributes at all.
+        """
+        next = self.node_next(node)
+        if next == node or next is None:
+            assert(self.node_prev(node) is next)
+            return False
+
+        return True
+
+    def node_insert_after(self, node, new_node):
+        """Insert the new node after node."""
+
+        assert(not self.node_is_on_list(new_node))
+        assert(node is not new_node)
+
+        next = self.node_next(node)
+        assert(next is not None)
+        self.node_set_next(node, new_node)
+        self.node_set_prev(new_node, node)
+
+        self.node_set_next(new_node, next)
+        self.node_set_prev(next, new_node)
+
+    def node_insert_before(self, node, new_node):
+        """Insert the new node before node."""
+
+        assert(not self.node_is_on_list(new_node))
+        assert(node is not new_node)
+
+        prev = self.node_prev(node)
+        assert(prev is not None)
+        self.node_set_prev(node, new_node)
+        self.node_set_next(new_node, node)
+
+        self.node_set_prev(new_node, prev)
+        self.node_set_next(prev, new_node)
+
+    def node_unlink(self, node):
+
+        if not self.node_is_on_list(node):
+            return
+
+        prev = self.node_prev(node)
+        next = self.node_next(node)
+
+        self.node_set_next(prev, next)
+        self.node_set_prev(next, prev)
+
+        self.node_set_next(node, node)
+        self.node_set_prev(node, node)