wi_array_t * wi_dictionary_keys_sorted_by_value(wi_dictionary_t *dictionary, wi_compare_func_t *compare) { wi_mutable_array_t *array, *buckets; _wi_dictionary_bucket_t *bucket; wi_array_callbacks_t callbacks; void **data; wi_uinteger_t i; if(dictionary->key_count == 0) return wi_autorelease(wi_array_init(wi_array_alloc())); callbacks.retain = NULL; callbacks.release = NULL; callbacks.is_equal = NULL; callbacks.description = NULL; buckets = wi_array_init_with_capacity_and_callbacks(wi_mutable_array_alloc(), dictionary->key_count, callbacks); for(i = 0; i < dictionary->buckets_count; i++) { for(bucket = dictionary->buckets[i]; bucket; bucket = bucket->next) wi_mutable_array_add_data(buckets, bucket); } data = wi_malloc(sizeof(void *) * dictionary->key_count); wi_array_get_data(buckets, data); #ifdef _WI_DICTIONARY_USE_QSORT_R qsort_r(data, dictionary->key_count, sizeof(void *), compare, _wi_dictionary_compare_buckets); #else wi_lock_lock(_wi_dictionary_sort_lock); _wi_dictionary_sort_function = compare; qsort(data, dictionary->key_count, sizeof(void *), _wi_dictionary_compare_buckets); wi_lock_unlock(_wi_dictionary_sort_lock); #endif callbacks.retain = dictionary->key_callbacks.retain; callbacks.release = dictionary->key_callbacks.release; callbacks.is_equal = dictionary->key_callbacks.is_equal; callbacks.description = dictionary->key_callbacks.description; array = wi_array_init_with_capacity_and_callbacks(wi_mutable_array_alloc(), dictionary->key_count, callbacks); for(i = 0; i < dictionary->key_count; i++) wi_mutable_array_add_data(array, ((_wi_dictionary_bucket_t *) data[i])->key); wi_free(data); wi_release(buckets); wi_runtime_make_immutable(array); return wi_autorelease(array); }
void wi_array_sort(wi_array_t *array, wi_compare_func_t *compare) { void **data; wi_uinteger_t i; if(array->data_count == 0) return; data = wi_malloc(sizeof(void *) * array->data_count); wi_array_get_data(array, data); #ifdef HAVE_QSORT_R qsort_r(data, array->data_count, sizeof(void *), compare, _wi_array_compare_data); #else wi_lock_lock(_wi_array_sort_lock); _wi_array_sort_function = compare; qsort(data, array->data_count, sizeof(void *), _wi_array_compare_data); wi_lock_unlock(_wi_array_sort_lock); #endif for(i = 0; i < array->data_count; i++) array->items[i]->data = data[i]; wi_free(data); }