Oolite 1.91.0.7644-241112-7f5034b
Loading...
Searching...
No Matches
OOPriorityQueue Class Reference

#include <OOPriorityQueue.h>

+ Inheritance diagram for OOPriorityQueue:
+ Collaboration diagram for OOPriorityQueue:

Instance Methods

(id) - initWithComparator:
 
(void) - addObject:
 
(void) - removeObject:
 
(void) - removeExactObject:
 
(NSUInteger) - count
 
(id) - nextObject
 
(id) - peekAtNextObject
 
(void) - removeNextObject
 
(void) - addObjects:
 
(NSArray *) - sortedObjects
 
(NSEnumerator *) - objectEnumerator
 
(id) - init [implementation]
 
(void) - dealloc [implementation]
 
(NSString *) - description [implementation]
 
(BOOL) - isEqual: [implementation]
 
(NSUInteger) - hash [implementation]
 
(id) - copyWithZone: [implementation]
 
(void) - makeObjectsPerformSelector: [implementation]
 
(void) - bubbleUpFrom: [implementation]
 
(void) - bubbleDownFrom: [implementation]
 
(void) - growBuffer [implementation]
 
(void) - shrinkBuffer [implementation]
 
(void) - removeObjectAtIndex: [implementation]
 

Class Methods

(instancetype) + queueWithComparator:
 

Private Attributes

SEL _comparator
 
OO_PQ_STRONG id * _heap
 
NSUInteger _count
 
NSUInteger _capacity
 

Detailed Description

Definition at line 52 of file OOPriorityQueue.h.

Method Documentation

◆ addObject:

- (void) addObject: (id) object

Definition at line 128 of file OOPriorityQueue.m.

271 :(id)object
272{
273 NSUInteger i;
274
275 // Validate object
276 if (object == nil)
277 {
278 [NSException raise:NSInvalidArgumentException
279 format:@"Attempt to insert nil into OOPriorityQueue."];
280 }
281
282 if (![object respondsToSelector:_comparator])
283 {
284 [NSException raise:NSInvalidArgumentException
285 format:@"Attempt to insert object (%@) which does not support comparator %@ into OOPriorityQueue.",
286 object, NSStringFromSelector(_comparator)];
287 }
288
289 // Ensure there is sufficent space.
290 if (_count == _capacity) [self growBuffer];
291
292 // insert object at end of buffer.
293 i = _count++;
294 _heap[i] = object;
295
296 [self bubbleUpFrom:i];
297 [object retain];
298}
return nil
OO_PQ_STRONG id * _heap
NSUInteger _capacity

◆ addObjects:

- (void) addObjects: (id) collection

Definition at line 128 of file OOPriorityQueue.m.

366 :(id)collection
367{
368 id value = nil;
369
370 if ([collection respondsToSelector:@selector(objectEnumerator)]) collection = [collection objectEnumerator];
371 if (![collection respondsToSelector:@selector(nextObject)]) return;
372
373 while ((value = [collection nextObject])) [self addObject:value];
374}
NSEnumerator * objectEnumerator()

◆ bubbleDownFrom:

- (void) bubbleDownFrom: (NSUInteger) i
implementation

Provided by category OOPriorityQueue(Private).

Definition at line 128 of file OOPriorityQueue.m.

428 :(NSUInteger)i
429{
430 NSUInteger end = _count - 1;
431 NSUInteger li, ri, next;
432 id obj = nil;
433
434 obj = _heap[i];
435 while (PQLeftChild(i) <= end)
436 {
437 li = PQLeftChild(i);
438 ri = PQRightChild(i);
439
440 // If left child has lower priority than right child, or there is only one child...
441 if (li == end || PQCompare(_heap[li], _heap[ri], _comparator) < 0)
442 {
443 next = li;
444 }
445 else
446 {
447 next = ri;
448 }
449
450 if (PQCompare(_heap[next], obj, _comparator) < 0)
451 {
452 // Exchange parent with lowest-priority child
453 _heap[i] = _heap[next];
454 _heap[next] = obj;
455 i = next;
456 }
457 else break;
458 }
459}
OOINLINE NSComparisonResult PQCompare(id a, id b, SEL comparator)
OOINLINE NSUInteger PQLeftChild(NSUInteger n) INLINE_CONST_FUNC
OOINLINE NSUInteger PQRightChild(NSUInteger n) INLINE_CONST_FUNC

◆ bubbleUpFrom:

- (void) bubbleUpFrom: (NSUInteger) i
implementation

Provided by category OOPriorityQueue(Private).

Definition at line 128 of file OOPriorityQueue.m.

406 :(NSUInteger)i
407{
408 NSUInteger pi;
409 id obj = nil, par = nil;
410
411 while (0 < i)
412 {
413 pi = PQParent(i);
414 obj = _heap[i];
415 par = _heap[pi];
416
417 if (PQCompare(obj, par, _comparator) < 0)
418 {
419 _heap[i] = par;
420 _heap[pi] = obj;
421 i = pi;
422 }
423 else break;
424 }
425}
OOINLINE NSUInteger PQParent(NSUInteger n) INLINE_CONST_FUNC

◆ copyWithZone:

- (id) copyWithZone: (NSZone *) zone
implementation

Definition at line 128 of file OOPriorityQueue.m.

243 :(NSZone *)zone
244{
245 OOPriorityQueue *copy = nil;
246
247 copy = [[self class] allocWithZone:zone];
248 if (copy != nil)
249 {
250 copy->_comparator = _comparator;
251 copy->_count = _count;
252 copy->_capacity = _count;
253
254 copy->_heap = malloc(_count * sizeof(id));
255 if (copy->_heap != NULL)
256 {
257 memcpy(copy->_heap, _heap, _count * sizeof(id));
258 [copy makeObjectsPerformSelector:@selector(retain)];
259 }
260 else if (_count != 0)
261 {
262 [copy release];
263 copy = nil;
264 }
265 }
266
267 return copy;
268}
void makeObjectsPerformSelector:(SEL selector)

◆ count

- (NSUInteger) count

Definition at line 128 of file OOPriorityQueue.m.

339{
340 return _count;
341}

◆ dealloc

- (void) dealloc
implementation

Definition at line 128 of file OOPriorityQueue.m.

169{
170 [self makeObjectsPerformSelector:@selector(release)];
171 free(_heap);
172
173 [super dealloc];
174}

◆ description

- (NSString *) description
implementation

Definition at line 128 of file OOPriorityQueue.m.

178{
179 return [NSString stringWithFormat:@"<%@ %p>{count=%lu, capacity=%lu}", [self class], self, _count, _capacity];
180}

◆ growBuffer

- (void) growBuffer
implementation

Provided by category OOPriorityQueue(Private).

Definition at line 128 of file OOPriorityQueue.m.

463{
464 id *newBuffer = NULL;
465 NSUInteger newCapacity;
466
467 newCapacity = _capacity * 3 / 2;
468 if (newCapacity < kMinCapacity) newCapacity = kMinCapacity;
469
470 // Note: realloc(NULL, size) with non-zero size is equivalent to malloc(size), so this is OK starting from a NULL buffer.
471 newBuffer = realloc(_heap, newCapacity * sizeof(id));
472 if (newBuffer == NULL)
473 {
474 // Attempt to grow by just one waffer-thin slot.
475 newCapacity = _capacity + 1;
476 newBuffer = realloc(_heap, newCapacity * sizeof(id));
477
478 if (newBuffer == NULL)
479 {
480 // Failed to grow.
481 [NSException raise:NSMallocException
482 format:@"Could not expand capacity of OOPriorityQueue."];
483 }
484 }
485
486 _heap = newBuffer;
487 _capacity = newCapacity;
488
489 assert(_count < _capacity);
490}
@ kMinCapacity

◆ hash

- (NSUInteger) hash
implementation

Definition at line 128 of file OOPriorityQueue.m.

237{
238 if (_count == 0) return NSNotFound;
239 return _count ^ [_heap[0] hash];
240}

◆ init

- (id) init
implementation

Definition at line 128 of file OOPriorityQueue.m.

163{
164 return [self initWithComparator:@selector(compare:)];
165}

◆ initWithComparator:

- (id) initWithComparator: (SEL) comparator

Definition at line 128 of file OOPriorityQueue.m.

144 :(SEL)comparator
145{
146 if (comparator == NULL)
147 {
148 [self release];
149 return nil;
150 }
151
152 self = [super init];
153 if (self != nil)
154 {
155 _comparator = comparator;
156 }
157
158 return self;
159}

◆ isEqual:

- (BOOL) isEqual: (id) object
implementation

Definition at line 128 of file OOPriorityQueue.m.

206 :(id)object
207{
208 NSUInteger i;
209 OOPriorityQueue *selfCopy = nil, *otherCopy = nil;
210 BOOL identical = YES;
211
212 if (object == self) return YES;
213 if (![object isKindOfClass:[self class]]) return NO;
214
215 if (_count != [object count]) return NO;
216 if (_count == 0) return YES;
217
218 selfCopy = [self copy];
219 otherCopy = [object copy];
220 i = _count;
221 while (i--)
222 {
223 if (![[selfCopy nextObject] isEqual:[otherCopy nextObject]])
224 {
225 identical = NO;
226 break;
227 }
228 }
229 [selfCopy release];
230 [otherCopy release];
231
232 return identical;
233}

◆ makeObjectsPerformSelector:

- (void) makeObjectsPerformSelector: (SEL) selector
implementation

Provided by category OOPriorityQueue(Private).

Definition at line 128 of file OOPriorityQueue.m.

393 :(SEL)selector
394{
395 NSUInteger i;
396
397 if (selector == NULL) return;
398
399 for (i = 0; i != _count; ++i)
400 {
401 [_heap[i] performSelector:selector];
402 }
403}

◆ nextObject

- (id) nextObject

Definition at line 128 of file OOPriorityQueue.m.

345{
346 id result = [self peekAtNextObject];
347 [self removeNextObject];
348 return result;
349}

◆ objectEnumerator

- (NSEnumerator *) objectEnumerator

Definition at line 128 of file OOPriorityQueue.m.

384{
385 return [[[OOPriorityQueueEnumerator alloc] initWithPriorityQueue:self] autorelease];
386}

◆ peekAtNextObject

- (id) peekAtNextObject

Definition at line 128 of file OOPriorityQueue.m.

353{
354 if (_count == 0) return nil;
355// return [[_heap[0] retain] autorelease];
356 return _heap[0];
357}

◆ queueWithComparator:

+ (instancetype) queueWithComparator: (SEL) comparator

Definition at line 128 of file OOPriorityQueue.m.

138 :(SEL)comparator
139{
140 return [[[self alloc] initWithComparator:comparator] autorelease];
141}

◆ removeExactObject:

- (void) removeExactObject: (id) object

Definition at line 128 of file OOPriorityQueue.m.

322 :(id)object
323{
324 NSUInteger i;
325
326 if (object == nil) return;
327
328 for (i = 0; i < _count; ++i)
329 {
330 if (object == _heap[i])
331 {
332 [self removeObjectAtIndex:i];
333 }
334 }
335}

◆ removeNextObject

- (void) removeNextObject

Definition at line 128 of file OOPriorityQueue.m.

361{
362 [self removeObjectAtIndex:0];
363}

◆ removeObject:

- (void) removeObject: (id) object

Definition at line 128 of file OOPriorityQueue.m.

301 :(id)object
302{
303 NSUInteger i;
304
305 /* Perform linear search for object (using comparator). A depth-first
306 search could skip leaves of lower priority, but I don't expect this to
307 be called very often.
308 */
309
310 if (object == nil) return;
311
312 for (i = 0; i < _count; ++i)
313 {
314 if (PQCompare(object, _heap[i], _comparator) == 0)
315 {
316 [self removeObjectAtIndex:i];
317 }
318 }
319}

◆ removeObjectAtIndex:

- (void) removeObjectAtIndex: (NSUInteger) i
implementation

Provided by category OOPriorityQueue(Private).

Definition at line 128 of file OOPriorityQueue.m.

517 :(NSUInteger)i
518{
519 id object = nil;
520
521 if (_count <= i) return;
522
523 object = _heap[i];
524 if (i < --_count)
525 {
526 // Overwrite object with last object in array
527 _heap[i] = _heap[_count];
528
529 // Push previously-last object down until tree is partially ordered.
530 [self bubbleDownFrom:i];
531 }
532 else
533 {
534 // Special case: removing last (or only) object. No bubbling needed.
535 }
536
537 [object autorelease];
538 if (_count * 2 <= _capacity) [self shrinkBuffer];
539}

◆ shrinkBuffer

- (void) shrinkBuffer
implementation

Provided by category OOPriorityQueue(Private).

Definition at line 128 of file OOPriorityQueue.m.

494{
495 NSUInteger amountToRemove;
496 id *newBuffer = NULL;
497 NSUInteger newCapacity;
498
499 if (kMinCapacity < _capacity)
500 {
501 // Remove two thirds of free space, if at least three slots are free.
502 amountToRemove = (_capacity - _count) * 2 / 3;
503 if (2 < amountToRemove)
504 {
505 newCapacity = _capacity - amountToRemove;
506 newBuffer = realloc(_heap, newCapacity * sizeof(id));
507 if (newBuffer != NULL)
508 {
509 _heap = newBuffer;
510 _capacity = newCapacity;
511 }
512 }
513 }
514}

◆ sortedObjects

- (NSArray *) sortedObjects

Definition at line 128 of file OOPriorityQueue.m.

378{
379 return [[self objectEnumerator] allObjects];
380}

Member Data Documentation

◆ _capacity

- (NSUInteger) _capacity
private

Definition at line 59 of file OOPriorityQueue.h.

◆ _comparator

- (SEL) _comparator
private

Definition at line 56 of file OOPriorityQueue.h.

◆ _count

- (NSUInteger) _count
private

Definition at line 58 of file OOPriorityQueue.h.

◆ _heap

- (OO_PQ_STRONG id*) _heap
private

Definition at line 57 of file OOPriorityQueue.h.


The documentation for this class was generated from the following files: