1 # vim: set fileencoding=utf-8 :
3 # (C) 2012 Intel Corporation <markus.lehtonen@linux.intel.com>
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 """Simple implementation of a doubly linked list"""
24 class LinkedListNode(object):
25 """Node of the linked list"""
27 def __init__(self, data="", prev_node=None, next_node=None):
37 """Get data stored into node"""
38 if self._data is None:
39 gbp.log.debug("BUG: referencing a deleted node!")
43 def set_data(self, data):
45 Set data stored into node
47 >>> node = LinkedListNode('foo')
50 >>> node.set_data('bar')
53 >>> node.set_data(None)
58 gbp.log.debug("BUG: trying to store 'None', not allowed")
66 self.prev.next = self.__next__
68 self.next.prev = self.prev
72 class LinkedListIterator(collections.abc.Iterator):
73 """Iterator for the linked list"""
75 def __init__(self, obj):
76 self._next = obj.first
81 self._next = ret.__next__
87 class LinkedList(collections.abc.Iterable):
88 """Doubly linked list"""
95 return LinkedListIterator(self)
98 for num, data in enumerate(self):
104 """Get the first node of the list"""
107 def prepend(self, data):
109 Insert to the beginning of list
111 >>> list = LinkedList()
112 >>> [str(data) for data in list]
114 >>> node = list.prepend("foo")
117 >>> node = list.prepend("bar")
118 >>> [str(data) for data in list]
121 if self._first is None:
122 new = self._first = self._last = LinkedListNode(data)
124 new = self.insert_before(self._first, data)
127 def append(self, data):
129 Insert to the end of list
131 >>> list = LinkedList()
132 >>> node = list.append('foo')
135 >>> node = list.append('bar')
136 >>> [str(data) for data in list]
139 if self._last is None:
140 return self.prepend(data)
142 return self.insert_after(self._last, data)
144 def insert_before(self, node, data=""):
148 >>> list = LinkedList()
149 >>> node1 = list.append('foo')
150 >>> node2 = list.insert_before(node1, 'bar')
151 >>> node3 = list.insert_before(node1, 'baz')
152 >>> [str(data) for data in list]
153 ['bar', 'baz', 'foo']
155 new = LinkedListNode(data, prev_node=node.prev, next_node=node)
163 def insert_after(self, node, data=""):
167 >>> list = LinkedList()
168 >>> node1 = list.prepend('foo')
169 >>> node2 = list.insert_after(node1, 'bar')
170 >>> node3 = list.insert_after(node1, 'baz')
171 >>> [str(data) for data in list]
172 ['foo', 'baz', 'bar']
174 new = LinkedListNode(data, prev_node=node, next_node=node.__next__)
182 def delete(self, node):
186 >>> list = LinkedList()
187 >>> node1 = list.prepend('foo')
188 >>> node2 = list.insert_after(node1, 'bar')
189 >>> node3 = list.insert_before(node2, 'baz')
190 >>> [str(data) for data in list]
191 ['foo', 'baz', 'bar']
192 >>> str(list.delete(node3))
194 >>> [str(data) for data in list]
196 >>> print "%s" % node3
198 >>> str(list.delete(node1))
200 >>> [str(data) for data in list]
202 >>> list.delete(node2)
203 >>> [str(data) for data in list]
207 if node is self._first:
208 ret = self._first = self._first.__next__
209 if node is self._last:
210 self._last = self._last.prev
214 # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: