Created
November 29, 2011 22:12
-
-
Save paul-english/1406810 to your computer and use it in GitHub Desktop.
Objective-C PriorityQueue with ARC, http://three20.pypt.lt/cocoa-objective-c-priority-queue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@interface ExampleObject : NSObject { | |
@public | |
NSString *name; | |
NSUInteger distance; | |
} | |
@property (nonatomic, retain) NSString *name; | |
@property (nonatomic) NSUInteger distance; | |
+ (ExampleObject *)itemWithName:(NSString *)initName | |
distance:(NSUInteger)initDistance; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "ExampleObject.h" | |
@implementation ExampleObject | |
@synthesize name; | |
@synthesize distance; | |
+ (ExampleObject *)itemWithName:(NSString *)initName | |
distance:(NSUInteger)initDistance { | |
ExampleObject *item = [[[ExampleObject alloc] init] autorelease]; | |
item.name = initName; | |
item.distance = initDistance; | |
return item; | |
} | |
// This method is not required | |
- (NSString *)description { | |
return [NSString stringWithFormat: | |
@"ExampleObject = {\n" | |
"\tname = %@\n" | |
"\tdistance = %d\n" | |
"}", | |
[name description], | |
distance]; | |
} | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Don't forget to import CoreFoundation | |
#import <CoreFoundation/CoreFoundation.h> | |
// Type of object that will be contained within priority queue | |
#import "ExampleObject.h" | |
@interface ExamplePriorityQueue : NSObject { | |
@private | |
// Heap itself | |
CFBinaryHeapRef _heap; | |
} | |
// Returns number of items in the queue | |
- (NSUInteger)count; | |
// Returns all (sorted) objects in the queue | |
- (NSArray *)allObjects; | |
// Adds an object to the queue | |
- (void)addObject:(ExampleObject *)object; | |
// Removes all objects from the queue | |
- (void)removeAllObjects; | |
// Removes the "top-most" (as determined by the callback sort function) object from the queue | |
// and returns it | |
- (ExampleObject *)nextObject; | |
// Returns the "top-most" (as determined by the callback sort function) object from the queue | |
// without removing it from the queue | |
- (ExampleObject *)peekObject; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "ExamplePriorityQueue.h" | |
@implementation ExamplePriorityQueue | |
#pragma mark - | |
#pragma mark CFBinaryHeap functions for sorting the priority queue | |
static const void *ExampleObjectRetain(CFAllocatorRef allocator, const void *ptr) { | |
ExampleObject *event = (ExampleObject *)ptr; | |
return [event retain]; | |
} | |
static void ExampleObjectRelease(CFAllocatorRef allocator, const void *ptr) { | |
ExampleObject* event = (ExampleObject *) ptr; | |
[event release]; | |
} | |
static CFStringRef ExampleObjectCopyDescription(const void* ptr) { | |
ExampleObject *event = (ExampleObject *) ptr; | |
CFStringRef desc = (CFStringRef) [event description]; | |
return desc; | |
} | |
static CFComparisonResult ExampleObjectCompare(const void* ptr1, const void* ptr2, void* context) { | |
ExampleObject *item1 = (ExampleObject *) ptr1; | |
ExampleObject *item2 = (ExampleObject *) ptr2; | |
// In this example, we're sorting by distance property of the object | |
// Objects with smallest distance will be first in the queue | |
if ([item1 distance] < [item2 distance]) { | |
return kCFCompareLessThan; | |
} else if ([item1 distance] == [item2 distance]) { | |
return kCFCompareEqualTo; | |
} else { | |
return kCFCompareGreaterThan; | |
} | |
} | |
#pragma mark - | |
#pragma mark NSObject methods | |
- (id)init { | |
if ((self = [super init])) { | |
CFBinaryHeapCallBacks callbacks; | |
callbacks.version = 0; | |
// Callbacks to the functions above | |
callbacks.retain = ExampleObjectRetain; | |
callbacks.release = ExampleObjectRelease; | |
callbacks.copyDescription = ExampleObjectCopyDescription; | |
callbacks.compare = ExampleObjectCompare; | |
// Create the priority queue | |
_heap = CFBinaryHeapCreate(kCFAllocatorDefault, 0, &callbacks, NULL); | |
} | |
return self; | |
} | |
- (void)dealloc { | |
if (_heap) { | |
CFRelease(_heap); | |
} | |
[super dealloc]; | |
} | |
- (NSString *)description { | |
return [NSString stringWithFormat:@"PriorityQueue = {%@}", | |
(_heap ? [[self allObjects] description] : @"null")]; | |
} | |
#pragma mark - | |
#pragma mark Queue methods | |
- (NSUInteger)count { | |
return CFBinaryHeapGetCount(_heap); | |
} | |
- (NSArray *)allObjects { | |
const void **arrayC = calloc(CFBinaryHeapGetCount(_heap), sizeof(void *)); | |
CFBinaryHeapGetValues(_heap, arrayC); | |
NSArray *array = [NSArray arrayWithObjects:(id *)arrayC | |
count:CFBinaryHeapGetCount(_heap)]; | |
free(arrayC); | |
return array; | |
} | |
- (void)addObject:(ExampleObject *)object { | |
CFBinaryHeapAddValue(_heap, object); | |
} | |
- (void)removeAllObjects { | |
CFBinaryHeapRemoveAllValues(_heap); | |
} | |
- (ExampleObject *)nextObject { | |
ExampleObject *obj = [self peekObject]; | |
CFBinaryHeapRemoveMinimumValue(_heap); | |
return obj; | |
} | |
- (ExampleObject *)peekObject { | |
return (ExampleObject *)CFBinaryHeapGetMinimum(_heap); | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment