00001
00002
00003
00004
00005
00006
00007
00008 #ifdef SORT_BY_INDEX
00009
00010
00011 #ifndef SWAP
00012 #error SWAP required when SORT_BY_INDEX is defined.
00013 #endif
00014
00015 #define PTYPE ptrdiff_t
00016
00017 #else
00018
00019
00020 #ifndef SWAP
00021 #define UNDEF_SWAP
00022 #define SWAP(X,Y) { TYPE tmp=*(X); *(X)=*(Y); *(Y)=tmp; }
00023 #endif
00024
00025 #define PTYPE TYPE *
00026
00027 #endif
00028
00029 #ifndef STEP
00030 #define UNDEF_STEP
00031 #define STEP(X,Y) ((X) + (Y))
00032 #endif
00033
00034 #define INC(X) X=STEP(X,1)
00035 #define DEC(X) X=STEP(X,-1)
00036 #define SIZE PTR_TO_INT(STEP((PTYPE)0,1))
00037
00038 #define PARENT(X) (((X)-1)>>1)
00039 #define CHILD1(X) (((X)<<1)+1)
00040
00041 #define MKNAME(X) MKNAME2(ID,X)
00042 #define MKNAME2(X,Y) PIKE_CONCAT(X,Y)
00043
00044 static void MKNAME(_do_sort)(register PTYPE bas,
00045 register PTYPE last,
00046 int max_recursion
00047 #ifdef EXTRA_ARGS
00048 EXTRA_ARGS
00049 #else
00050 #define UNDEF_XARGS
00051 #define XARGS
00052 #endif
00053 )
00054 {
00055 register PTYPE a;
00056 register PTYPE b;
00057 #ifdef EXTRA_LOCALS
00058 EXTRA_LOCALS
00059 #endif
00060
00061 while(bas < last)
00062 {
00063 a = STEP(bas,1);
00064 if(a == last)
00065 {
00066 if( CMP(bas,last) > 0) SWAP(bas,last);
00067 return;
00068 }else{
00069 if(--max_recursion <= 0)
00070 {
00071 ptrdiff_t howmany,x,y,z;
00072 howmany=((((char *)last)-((char *)bas))/SIZE)+1;
00073 if(howmany<2) return;
00074
00075 for(x=PARENT(howmany-1);x>=0;x--)
00076 {
00077 y=x;
00078 while(1)
00079 {
00080 z=CHILD1(y);
00081 if(z>=howmany) break;
00082 if(z+1 < howmany && CMP(STEP(bas,z),STEP(bas,z+1))<=0) z++;
00083 if(CMP( STEP(bas, y), STEP(bas, z)) >0) break;
00084 SWAP( STEP(bas, y), STEP(bas, z));
00085 y=z;
00086 }
00087 }
00088
00089 for(x=howmany-1;x;x--)
00090 {
00091 SWAP( STEP(bas,x), bas);
00092 y=0;
00093 while(1)
00094 {
00095 z=CHILD1(y);
00096 if(z>=x) break;
00097 if(z+1 < x && CMP(STEP(bas,z),STEP(bas,z+1))<=0) z++;
00098 if(CMP( STEP(bas, y), STEP(bas, z)) >0) break;
00099 SWAP( STEP(bas, y), STEP(bas, z));
00100 y=z;
00101 }
00102 }
00103
00104 #ifdef PIKE_DEBUG
00105 if(d_flag>1)
00106 for(x=howmany-1;x;x--)
00107 if( CMP( STEP(bas,x-1), STEP(bas,x) ) > 0)
00108 Pike_fatal("Sorting failed!\n");
00109 #endif
00110
00111 return;
00112 }
00113
00114 b=STEP(bas,((((char *)last)-((char *)bas))/SIZE)>>1);
00115 SWAP(bas,b);
00116 b=last;
00117 while(a < b)
00118 {
00119 #if 1
00120 while(a<b)
00121 {
00122 while(1)
00123 {
00124 if(a<=b && CMP(a,bas) <= 0)
00125 INC(a);
00126 else
00127 {
00128 while(a< b && CMP(bas,b) <= 0) DEC(b);
00129 break;
00130 }
00131 if(a< b && CMP(bas,b) <= 0)
00132 DEC(b);
00133 else
00134 {
00135 while(a<=b && CMP(a,bas) <= 0) INC(a);
00136 break;
00137 }
00138 }
00139
00140 if(a<b)
00141 {
00142 SWAP(a,b);
00143 INC(a);
00144 if(b > STEP(a,1)) DEC(b);
00145 }
00146 }
00147 #else
00148 while(a<=b && CMP(a,bas) < 0) INC(a);
00149 while(a< b && CMP(bas,b) < 0) DEC(b);
00150 if(a<b)
00151 {
00152 SWAP(a,b);
00153 INC(a);
00154 if(b > STEP(a,1)) DEC(b);
00155 }
00156 #endif
00157 }
00158
00159 DEC(a);
00160 if( a != bas ) {
00161 SWAP(a,bas);
00162 DEC(a);
00163
00164 if( (char *)a - (char *)bas < (char *)last - (char *)b )
00165 {
00166 MKNAME(_do_sort)(bas,a,max_recursion XARGS);
00167 bas=b;
00168 } else {
00169 MKNAME(_do_sort)(b,last,max_recursion XARGS);
00170 last=a;
00171 }
00172 }
00173 else
00174 {
00175 DEC(a);
00176 if( STEP(0,-1) < (char *)last - (char *)b )
00177 {
00178 MKNAME(_do_sort)(bas,a,max_recursion XARGS);
00179 bas=b;
00180 } else {
00181 MKNAME(_do_sort)(b,last,max_recursion XARGS);
00182 last=a;
00183 }
00184 }
00185 }
00186 }
00187 }
00188
00189 void ID(register PTYPE bas,
00190 register PTYPE last
00191 #ifdef EXTRA_ARGS
00192 EXTRA_ARGS
00193 #endif
00194 )
00195 {
00196 MKNAME(_do_sort)(bas,last, my_log2( last-bas ) * 2 XARGS);;
00197 }
00198
00199
00200 #undef PTYPE
00201 #undef INC
00202 #undef DEC
00203 #undef PARENT
00204 #undef CHILD1
00205
00206 #ifdef UNDEF_XARGS
00207 #undef XARGS
00208 #undef UNDEF_XARGS
00209 #endif
00210
00211 #ifdef UNDEF_SWAP
00212 #undef SWAP
00213 #undef UNDEF_SWAP
00214 #endif
00215
00216 #ifdef UNDEF_STEP
00217 #undef STEP
00218 #undef UNDEF_STEP
00219 #endif