Main Page | Class List | Directories | File List | Class Members | File Members

fsort_template.h

Go to the documentation of this file.
00001 /*
00002 || This file is part of Pike. For copyright information see COPYRIGHT.
00003 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
00004 || for more information.
00005 || $Id: fsort_template.h,v 1.18 2003/08/29 16:34:27 nilsson Exp $
00006 */
00007 
00008 #ifdef SORT_BY_INDEX
00009 /* Sort by index. */
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  /* !SORT_BY_INDEX */
00018 /* Sort by pointer. */
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  /* !SORT_BY_INDEX */
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

Generated on Fri Jul 22 23:44:24 2005 for Pike by  doxygen 1.3.9.1