00001
00002
00003
00004
00005
00006
00007
00008 #include <assert.h>
00009 #include <stdlib.h>
00010 #include <stdio.h>
00011 #include <math.h>
00012 #include "heap-sort.h"
00013
00014 #define NOEXP2
00015
00016 static void heapify(heap_t *heap, int i);
00017
00018
00019
00020 static inline int parent(int i) {
00021 return (i/2);
00022 }
00023
00024 static inline int left(int i) {
00025 return (2*i);
00026 }
00027
00028 static inline int right(int i) {
00029 return (2*i + 1);
00030 }
00031
00032 int ADIOI_Heap_create(heap_t *heap, int size) {
00033 heap->size = size;
00034 heap->nodes = (heap_node_t *) ADIOI_Calloc (size, sizeof(heap_node_t));
00035 if (heap->nodes == NULL)
00036 return 1;
00037 else
00038 return 0;
00039 }
00040
00041 void ADIOI_Heap_free(heap_t *heap) {
00042 ADIOI_Free(heap->nodes);
00043 }
00044
00045
00046 static void build_heap(heap_t *heap) ATTRIBUTE((unused, used));
00047
00048 static void build_heap(heap_t *heap)
00049 {
00050 int i;
00051 for (i=(heap->size/2-1); i >= 0; i--)
00052 heapify(heap, i);
00053 }
00054
00055 static void heapify(heap_t *heap, int i) {
00056 int l, r, smallest;
00057 heap_node_t *nodes;
00058 heap_node_t tmp_node;
00059
00060 nodes = heap->nodes;
00061
00062 l = left(i);
00063 r = right(i);
00064
00065 if ((l <= heap->size) && (nodes[l].offset < nodes[i].offset))
00066 smallest = l;
00067 else
00068 smallest = i;
00069
00070 if ((r <= heap->size) && (nodes[r].offset < nodes[smallest].offset))
00071 smallest = r;
00072
00073 if (smallest != i) {
00074 tmp_node = nodes[i];
00075 nodes[i] = nodes[smallest];
00076 nodes[smallest] = tmp_node;
00077 heapify(heap, smallest);
00078 }
00079 }
00080
00081 void ADIOI_Heap_insert(heap_t *heap, ADIO_Offset offset, int proc,
00082 ADIO_Offset reg_max_len) {
00083 heap_node_t *nodes;
00084 int i;
00085 nodes = heap->nodes;
00086 i = ++heap->size - 1;
00087 while ((i > 0) && (nodes[parent(i)].offset > offset)) {
00088 nodes[i] = nodes[parent(i)];
00089 i = parent(i);
00090 }
00091 nodes[i].offset = offset;
00092 nodes[i].proc = proc;
00093 nodes[i].reg_max_len = reg_max_len;
00094 }
00095
00096 void ADIOI_Heap_extract_min(heap_t *heap, ADIO_Offset* offset, int *proc,
00097 ADIO_Offset *reg_max_len) {
00098 heap_node_t *nodes;
00099 nodes = heap->nodes;
00100
00101 assert (heap->size > 0);
00102 *offset = nodes[0].offset;
00103 *proc = nodes[0].proc;
00104 *reg_max_len = nodes[0].reg_max_len;
00105 nodes[0] = nodes[heap->size-1];
00106 heap->size--;
00107 heapify(heap, 0);
00108 }
00109
00110
00111 static void print_heap(heap_t *heap) ATTRIBUTE((unused, used));
00112
00113 static void print_heap(heap_t *heap)
00114 {
00115 #ifndef NOEXP2
00116 int i;
00117 double level = 0;
00118 int next_level_idx = 1;
00119
00120 printf ("heap->size = %d\n", heap->size);
00121 printf ("offsets:\n");
00122 for (i=0; i < heap->size; i++) {
00123 printf ("%lld ", heap->nodes[i].offset);
00124
00125 if ((i+1) == next_level_idx) {
00126 printf ("\n");
00127 next_level_idx += (int) exp2(level+1);
00128 level++;
00129 }
00130 }
00131 printf ("\n");
00132 #endif
00133 }