queue_head* pq_extract_best(struct queue* q, int num, int* get) { queue_head* qh = NULL; queue_head* qh2; int n = num; assert(num > 0); LOCK(q); if(num > q->length){ printf("NUM: %d Q: %d\n", num, q->length); n = q->length / 2; } *get = n; if(n == 0){ UNLOCK(q); return NULL; } while(n != 0) { qh2 = extract_helper(q->root_node, n); n -= qh2->length; q->length = q->root_node->length; qh = merge_helper(qh, qh2); } UNLOCK(q); return qh; }
/* left is the index of the leftmost element of the subarray; right is one * past the index of the rightmost element */ void merge_helper(int *input, unsigned long left, unsigned long right, int *scratch) { /* base case: one element */ if(right == left + 1) { return; } else { unsigned long i = 0; unsigned long length = right - left; unsigned long midpoint_distance = length/2; /* l and r are to the positions in the left and right subarrays */ unsigned long l = left, r = left + midpoint_distance; /* sort each subarray */ merge_helper(input, left, left + midpoint_distance, scratch); merge_helper(input, left + midpoint_distance, right, scratch); /* merge the arrays together using scratch for temporary storage */ for(i = 0; i < length; i++) { /* Check to see if any elements remain in the left array; if so, * we check if there are any elements left in the right array; if * so, we compare them. Otherwise, we know that the merge must * use take the element from the left array */ if(l < left + midpoint_distance && (r == right || min(input[l], input[r]) == input[l])) { scratch[i] = input[l]; l++; } else { scratch[i] = input[r]; r++; } } /* Copy the sorted subarray back to the input */ for(i = left; i < right; i++) { input[i] = scratch[i - left]; } } }
void pq_merge(queue* q1, queue* q2) { LOCK(q1); q1->root_node = merge_helper(q1->root_node, q2->root_node); q1->length += q2->length; UNLOCK(q1); q2->length = 0; q2->root_node = NULL; }
SparseNode * SparseArray_merge(SparseNode * array_1, SparseNode * array_2) { SparseNode *copy1; copy1 = SparseArray_copy(array_1); if(array_2 == NULL) { return copy1; } copy1 = merge_helper(copy1,array_2); return NULL; }
//not concurrent void pq_insert_nc(queue* q, float priority, solution_vector partial_solution) { NEW(queue_head, qh); qh->priority = priority; qh->partial_solution = partial_solution; qh->left_subtree = NULL; qh->right_subtree = NULL; qh->distance = 0; qh->length = 1; q->root_node = merge_helper(q->root_node, qh); q->length ++; }
int mergesort(int *input, unsigned long size) { int *scratch = (int *)malloc(size * sizeof(int)); if(scratch != NULL) { merge_helper(input, 0, size, scratch); free(scratch); return 1; } else { return 0; } }
queue_head* pq_extract(struct queue* q, int num) { queue_head* qh = NULL; queue_head* qh2; int n = num; assert(num > 0); LOCK(q); assert(num < q->length); while(n != 0) { qh2 = extract_helper(q->root_node, n); n -= qh2->length; q->length = q->root_node->length; qh = merge_helper(qh, qh2); } UNLOCK(q); return qh; }
queue_head* merge_helper(queue_head* q1, queue_head* q2) { queue_head* temp; if (q2 == NULL) return q1; if (q1 == NULL) return q2; if (q2->priority < q1->priority) { SWAP(q1, q2); } q1->right_subtree = merge_helper(q1->right_subtree, q2); if (node_distance(q1->right_subtree) > node_distance(q1->left_subtree)) { SWAP(q1->left_subtree, q1->right_subtree); } q1->distance = (MIN(node_distance(q1->right_subtree), node_distance(q1->left_subtree))) + 1; q1->length = node_length(q1->left_subtree) + node_length(q1->right_subtree) + 1; return q1; }
solution_vector pq_min_extract(queue* q, float* pr) { solution_vector* min_vector; LOCK(q); if (q->length == 0) { min_vector = NULL; } else { min_vector = q->root_node->partial_solution; *pr = q->root_node->priority; queue_head *left, *right; left = q->root_node->left_subtree; right = q->root_node->right_subtree; q->root_node = merge_helper(left, right); q->length --; } UNLOCK(q); return min_vector; }