00001 #include <parmetislib.h>
00002
00003
00004
00005 #define QSSWAP(a, b, stmp) do { stmp = (a); (a) = (b); (b) = stmp; } while (0)
00006
00007
00008
00009 #define MAX_THRESH 20
00010
00011
00012 typedef struct {
00013 KeyValueType *lo;
00014 KeyValueType *hi;
00015 } stack_node;
00016
00017
00018
00019 #define STACK_SIZE (8 * sizeof(unsigned long int))
00020 #define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
00021 #define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi)))
00022 #define STACK_NOT_EMPTY (stack < top)
00023
00024
00025 void ikeyvalsort(int total_elems, KeyValueType *pbase)
00026 {
00027 KeyValueType pivot, stmp;
00028
00029 if (total_elems == 0)
00030
00031 return;
00032
00033 if (total_elems > MAX_THRESH) {
00034 KeyValueType *lo = pbase;
00035 KeyValueType *hi = &lo[total_elems - 1];
00036 stack_node stack[STACK_SIZE];
00037 stack_node *top = stack + 1;
00038
00039 while (STACK_NOT_EMPTY) {
00040 KeyValueType *left_ptr;
00041 KeyValueType *right_ptr;
00042 KeyValueType *mid = lo + ((hi - lo) >> 1);
00043
00044 if (mid->key < lo->key || (mid->key == lo->key && mid->val < lo->val))
00045 QSSWAP(*mid, *lo, stmp);
00046 if (hi->key < mid->key || (hi->key == mid->key && hi->val < mid->val))
00047 QSSWAP(*mid, *hi, stmp);
00048 else
00049 goto jump_over;
00050 if (mid->key < lo->key || (mid->key == lo->key && mid->val < lo->val))
00051 QSSWAP(*mid, *lo, stmp);
00052
00053 jump_over:;
00054 pivot = *mid;
00055 left_ptr = lo + 1;
00056 right_ptr = hi - 1;
00057
00058
00059
00060
00061 do {
00062 while (left_ptr->key < pivot.key || (left_ptr->key == pivot.key && left_ptr->val < pivot.val))
00063 left_ptr++;
00064
00065 while (pivot.key < right_ptr->key || (pivot.key == right_ptr->key && pivot.val < right_ptr->val))
00066 right_ptr--;
00067
00068 if (left_ptr < right_ptr) {
00069 QSSWAP (*left_ptr, *right_ptr, stmp);
00070 left_ptr++;
00071 right_ptr--;
00072 }
00073 else if (left_ptr == right_ptr) {
00074 left_ptr++;
00075 right_ptr--;
00076 break;
00077 }
00078 } while (left_ptr <= right_ptr);
00079
00080
00081
00082
00083
00084
00085 if ((size_t) (right_ptr - lo) <= MAX_THRESH) {
00086 if ((size_t) (hi - left_ptr) <= MAX_THRESH)
00087
00088 POP (lo, hi);
00089 else
00090
00091 lo = left_ptr;
00092 }
00093 else if ((size_t) (hi - left_ptr) <= MAX_THRESH)
00094
00095 hi = right_ptr;
00096 else if ((right_ptr - lo) > (hi - left_ptr)) {
00097
00098 PUSH (lo, right_ptr);
00099 lo = left_ptr;
00100 }
00101 else {
00102
00103 PUSH (left_ptr, hi);
00104 hi = right_ptr;
00105 }
00106 }
00107 }
00108
00109
00110
00111
00112
00113
00114
00115 {
00116 KeyValueType *end_ptr = &pbase[total_elems - 1];
00117 KeyValueType *tmp_ptr = pbase;
00118 KeyValueType *thresh = (end_ptr < pbase + MAX_THRESH ? end_ptr : pbase + MAX_THRESH);
00119 register KeyValueType *run_ptr;
00120
00121
00122
00123
00124
00125 for (run_ptr = tmp_ptr + 1; run_ptr <= thresh; run_ptr++)
00126 if (run_ptr->key < tmp_ptr->key || (run_ptr->key == tmp_ptr->key && run_ptr->val < tmp_ptr->val))
00127 tmp_ptr = run_ptr;
00128
00129 if (tmp_ptr != pbase)
00130 QSSWAP(*tmp_ptr, *pbase, stmp);
00131
00132
00133 run_ptr = pbase + 1;
00134 while (++run_ptr <= end_ptr) {
00135 tmp_ptr = run_ptr - 1;
00136 while (run_ptr->key < tmp_ptr->key || (run_ptr->key == tmp_ptr->key && run_ptr->val < tmp_ptr->val))
00137 tmp_ptr--;
00138
00139 tmp_ptr++;
00140 if (tmp_ptr != run_ptr) {
00141 KeyValueType elmnt = *run_ptr;
00142 KeyValueType *mptr;
00143
00144 for (mptr=run_ptr; mptr>tmp_ptr; mptr--)
00145 *mptr = *(mptr-1);
00146 *mptr = elmnt;
00147 }
00148 }
00149 }
00150 }
00151