1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import threading
19
20
21
22
23
25
26 _name = None
27 _value = None
28
32
35
38
41
44
47
50
53
54 MINUS_INFINITY = SpecialValue('MINUS_INFINITY', 0)
55 INFINITY = SpecialValue('INFINITY', 1)
56 DEBUG = True
57 WRITE_BUFFER_CAPACITY = 1000
58 LOCK_WAIT_TIME = 1.0
59
61 n = len(x)
62 if n == 0:
63 boundaries = ''
64 elif n == 1:
65 boundaries = str(x[0])
66 elif n == 2:
67 boundaries = '%s, %s' % (x[0], x[1])
68 else:
69 boundaries = '%s .. %s' % (x[0], x[-1])
70 return '%s[%s]' % (len(x), boundaries)
71
73
74 _nodes = None
75 _inputs = None
76 _first_input = None
77 _key = None
78
80 self._key = key
81 self._inputs = inputs
82
83 leaves = 1
84 while leaves < self._inputs:
85 leaves *= 2
86 nodes = 2 * leaves - 1
87
88 self._first_input = leaves - 1
89 self._nodes = []
90
91 for i in xrange(self._first_input):
92 self._nodes.append(_InteriorNode(self))
93
94 for i in xrange(self._inputs):
95 self._nodes.append(_InputNode(self, i))
96
97 while len(self._nodes) < nodes:
98 self._nodes.append(_FillerNode(self))
99
100
101
102 for i in xrange(self._first_input + self._inputs, len(self._nodes)):
103 node = self._nodes[i]
104 while ((not node.is_root) and
105 node.parent.right is node and
106 type(node.parent.left) is not _InputNode and
107
108 node.parent.left.content is INFINITY):
109 node = node.parent
110 node.content = INFINITY
111
113 return 'PriorityQueue<%s>' % id(self)
114
116
117 root = self._nodes[0]
118 while root.content is MINUS_INFINITY:
119 root.promote()
120 output = root.content
121 while output is not INFINITY:
122
123 yield output
124 root.promote()
125 output = root.content
126
127 - def add(self, index, object):
130
131 - def done(self, index):
133
134 - def dump(self, label = None):
135 if label:
136 label = [label]
137 else:
138 label = []
139 return '\n'.join(label + ['%s: %s' % (node._id, str(node)) for node in self._nodes])
140
141
143
144 _priority_queue = None
145 _key = None
146 _id = None
147
149 self._priority_queue = priority_queue
150 self._key = priority_queue._key
151 self._id = len(priority_queue._nodes)
152
154 return '%s#%s(%s)' % (self.node_type(), self._id, self.content)
155
157 if type(x) is type(y):
158
159 if isinstance(x, SpecialValue):
160 c = cmp(x, y)
161 else:
162 key = self._key
163 kx = key(x)
164 ky = key(y)
165 c = cmp(kx, ky)
166 elif x is INFINITY:
167 c = 1
168 elif y is INFINITY:
169 c = -1
170 elif x is MINUS_INFINITY:
171 c = -1
172 elif y is MINUS_INFINITY:
173 c = 1
174 else:
175 assert False, (type(x), x, type(y), y)
176 return c
177
178 is_root = property(lambda self: self._id == 0)
179 parent = property(lambda self: self._priority_queue._nodes[(self._id - 1) / 2])
180 left = property(lambda self: self._priority_queue._nodes[self._id * 2 + 1])
181 right = property(lambda self: self._priority_queue._nodes[self._id * 2 + 2])
182
185
188
190
191 _content = None
192
196
199
209
210 - def _get_content(self):
212
213 - def _set_content(self, content):
214 self._content = content
215
216 content = property(_get_content, _set_content)
217
250
252
254 _Node.__init__(self, priority_queue)
255
258
259 content = property(lambda self: INFINITY)
260
262
263 _lock = None
264 _input_node = None
265 _read = None
266 _read_position = None
267 _write = None
268 _last_input = None
269 _done = None
270
272 self._lock = threading.Condition()
273 self._input_node = input_node
274 self._read = []
275 self._read_position = 0
276 self._write = []
277 self._last_input = None
278 self._done = False
279
280
282 buffer = ['buffer<']
283 buffer.append(str(id(self)))
284 buffer.append('>#')
285 buffer.append(str(self._input_node.source))
286 buffer.append('(pq:')
287 buffer.append(str(self._priority_queue))
288 buffer.append(', read:')
289 buffer.append(_describe_list(self._read))
290 buffer.append(', write: ')
291 buffer.append(_describe_list(self._write))
292 buffer.append(')')
293 return ''.join(buffer)
294
296 if self._done:
297 current = INFINITY
298 else:
299 self._ensure_read_not_empty()
300 current = self._read[self._read_position]
301 if current is INFINITY:
302 self._done = True
303 return current
304
307
309 write_buffer_size = len(self._write)
310 return (write_buffer_size < WRITE_BUFFER_CAPACITY and
311 (write_buffer_size == 0 or self._last_input is not INFINITY))
312
314 if self._read_position == len(self._read):
315 self._lock.acquire()
316 while self._read_blocked():
317
318 self._lock.wait(LOCK_WAIT_TIME)
319
320 self._read = self._write
321 self._read_position = 0
322 self._write = []
323 self._lock.notify()
324 self._lock.release()
325
326 _priority_queue = property(lambda self: self._input_node._priority_queue)
327
328 - def add(self, input):
329
330 if (self._last_input is not None) and (self._input_node._compare(input, self._last_input) < 0):
331 raise PriorityQueueInputOrderingException(self._input_node, input, self._last_input)
332 if self._write_blocked():
333 self._lock.acquire()
334
335
336 self._lock.notify()
337 while self._write_blocked():
338
339 self._lock.wait(LOCK_WAIT_TIME)
340
341 self._lock.notify()
342 self._lock.release()
343 self._write.append(input)
344 self._last_input = input
345 if input is INFINITY:
346
347
348
349 self._lock.acquire()
350 self._lock.notify()
351 self._lock.release()
352
354 if self._done:
355 output = INFINITY
356 else:
357 self._ensure_read_not_empty()
358 output = self._read[self._read_position]
359 self._read[self._read_position] = None
360 self._read_position += 1
361 return output
362
369
377