void CFBinaryHeapAddValue(CFBinaryHeapRef heap, const void *value) { CFIndex idx, pidx; CFIndex cnt; CFAllocatorRef allocator = CFGetAllocator(heap); __CFGenericValidateType(heap, __kCFBinaryHeapTypeID); switch (__CFBinaryHeapMutableVariety(heap)) { case kCFBinaryHeapMutable: if (__CFBinaryHeapNumBucketsUsed(heap) == __CFBinaryHeapCapacity(heap)) __CFBinaryHeapGrow(heap, 1); break; } cnt = __CFBinaryHeapCount(heap); idx = cnt; __CFBinaryHeapSetNumBucketsUsed(heap, cnt + 1); __CFBinaryHeapSetCount(heap, cnt + 1); CFComparisonResult (*compare)(const void *, const void *, void *) = heap->_callbacks.compare; pidx = (idx - 1) >> 1; while (0 < idx) { void *item = heap->_buckets[pidx]._item; if ((!compare && item <= value) || (compare && kCFCompareGreaterThan != compare(item, value, heap->_context.info))) break; __CFAssignWithWriteBarrier((void **)&heap->_buckets[idx]._item, item); idx = pidx; pidx = (idx - 1) >> 1; } if (heap->_callbacks.retain) { __CFAssignWithWriteBarrier((void **)&heap->_buckets[idx]._item, (void *)heap->_callbacks.retain(allocator, (void *)value)); } else { __CFAssignWithWriteBarrier((void **)&heap->_buckets[idx]._item, (void *)value); } }
static CFStringRef __CFBinaryHeapCopyDescription(CFTypeRef cf) { CFBinaryHeapRef heap = (CFBinaryHeapRef)cf; CFMutableStringRef result; CFIndex idx; CFIndex cnt; const void **list, *buffer[256]; cnt = __CFBinaryHeapCount(heap); result = CFStringCreateMutable(CFGetAllocator(heap), 0); CFStringAppendFormat(result, NULL, CFSTR("<CFBinaryHeap %p [%p]>{count = %lu, capacity = %lu, objects = (\n"), cf, CFGetAllocator(heap), (unsigned long)cnt, (unsigned long)__CFBinaryHeapCapacity(heap)); list = (cnt <= 128) ? (const void **)buffer : (const void **)CFAllocatorAllocate(kCFAllocatorSystemDefault, cnt * sizeof(void *), 0); // GC OK if (__CFOASafe && list != buffer) __CFSetLastAllocationEventName(list, "CFBinaryHeap (temp)"); CFBinaryHeapGetValues(heap, list); for (idx = 0; idx < cnt; idx++) { CFStringRef desc = NULL; const void *item = list[idx]; if (NULL != heap->_callbacks.copyDescription) { desc = heap->_callbacks.copyDescription(item); } if (NULL != desc) { CFStringAppendFormat(result, NULL, CFSTR("\t%lu : %@\n"), (unsigned long)idx, desc); CFRelease(desc); } else { CFStringAppendFormat(result, NULL, CFSTR("\t%lu : <%p>\n"), (unsigned long)idx, item); } } CFStringAppend(result, CFSTR(")}")); if (list != buffer) CFAllocatorDeallocate(CFGetAllocator(heap), list); // GC OK return result; }