Skip to content
Snippets Groups Projects
Commit 3a901044 authored by Fredrik Hübinette (Hubbe)'s avatar Fredrik Hübinette (Hubbe)
Browse files

fsort optimized, and remodeled not to duplicate code

Rev: src/fsort.c:1.2
Rev: src/fsort_template.h:1.1
parent e9f91412
Branches
Tags
No related merge requests found
...@@ -14,89 +14,62 @@ static long size; ...@@ -14,89 +14,62 @@ static long size;
static char *tmp_area; static char *tmp_area;
#define SWAP(X,Y) { tmp=*(X); *(X)=*(Y); *(Y)=tmp; } #define SWAP(X,Y) { tmp=*(X); *(X)=*(Y); *(Y)=tmp; }
#define STEP(X,Y) ((X)+(Y))
#define FSORT(ID,TYPE) \ #define ID fsort_1
static void ID(register TYPE *bas,register TYPE *last) \ typedef struct a1 { char b[1]; } b1;
{ \ #define TYPE b1
register TYPE *a,*b, tmp; \ #include "fsort_template.h"
if(bas >= last) return; \ #undef ID
a = bas + 1; \ #undef TYPE
if(a == last) \
{ \
if( (*cmpfun)((void *)bas,(void *)last) > 0) SWAP(bas,last); \
}else{ \
b=bas+((last-bas)>>1); \
SWAP(bas,b); \
b=last; \
while(a < b) \
{ \
while(a<=b && (*cmpfun)((void *)a,(void *)bas) < 0) a++; \
while(a< b && (*cmpfun)((void *)bas,(void *)b) < 0) b--; \
if(a<b) \
{ \
SWAP(a,b); \
a++; \
if(b > a+1) b--; \
} \
} \
a--; \
SWAP(a,bas); \
a--; \
ID(bas,a); \
ID(b,last); \
} \
}
#define FSWAP(X,Y) \ #define ID fsort_2
{ \ typedef struct a2 { char b[2]; } b2;
MEMCPY(tmp_area,X,size); \ #define TYPE b2
MEMCPY(X,Y,size); \ #include "fsort_template.h"
MEMCPY(Y,tmp_area,size); \ #undef ID
} #undef TYPE
static void fsort_n(register char *bas,register char *last) #define ID fsort_4
{ typedef struct a4 { char b[4]; } b4;
register char *a,*b; #define TYPE b4
register int dum; #include "fsort_template.h"
#undef ID
#undef TYPE
if(bas>=last) return;
a=bas+size;
if(a==last)
{
if((*cmpfun)(bas,last) > 0) FSWAP(bas,last);
}else{
dum=(last-bas)>>1;
dum-=dum % size;
FSWAP(bas,bas+dum);
b=last;
while(a<b)
{
while(a<=b && (*cmpfun)(a,bas) < 0) a+=size;
while(a< b && (*cmpfun)(bas,b) < 0) b-=size;
if(a<b)
{
FSWAP(a,b);
a+=size;
if(b-a>size) b-=size;
}
}
a-=size;
FSWAP(bas,a);
a-=size;
fsort_n(bas,a);
fsort_n(b,last);
}
}
typedef struct a { char b[1]; } onebyte; #define ID fsort_8
typedef struct b { char b[2]; } twobytes; typedef struct a8 { char b[8]; } b8;
typedef struct c { char b[4]; } fourbytes; #define TYPE b8
typedef struct d { char b[8]; } eightbytes; #include "fsort_template.h"
#undef ID
#undef TYPE
#define ID fsort_16
typedef struct a16 { char b[16]; } b16;
#define TYPE b16
#include "fsort_template.h"
#undef ID
#undef TYPE
#undef SWAP
#undef STEP
#define SWAP(X,Y) do { \
MEMCPY(tmp_area,X,size); \
MEMCPY(X,Y,size); \
MEMCPY(Y,tmp_area,size); \
} while(0)
FSORT(fsort_1, onebyte) #define STEP(X,Y) ((X)+(Y)*size)
FSORT(fsort_2, twobytes) #define TYPE char
FSORT(fsort_4, fourbytes) #define ID fsort_n
FSORT(fsort_8, eightbytes) #include "fsort_template.h"
#undef ID
#undef TYPE
#undef SWAP
#undef STEP
void fsort(void *base, void fsort(void *base,
long elms, long elms,
...@@ -110,10 +83,11 @@ void fsort(void *base, ...@@ -110,10 +83,11 @@ void fsort(void *base,
switch(elmSize) switch(elmSize)
{ {
case 1: fsort_1((onebyte *)base,(elms-1)+(onebyte *)base); break; case 1: fsort_1(( b1 *)base,(elms-1)+( b1 *)base); break;
case 2: fsort_2((twobytes *)base,(elms-1)+(twobytes *)base); break; case 2: fsort_2(( b2 *)base,(elms-1)+( b2 *)base); break;
case 4: fsort_4((fourbytes *)base,(elms-1)+(fourbytes *)base); break; case 4: fsort_4(( b4 *)base,(elms-1)+( b4 *)base); break;
case 8: fsort_8((eightbytes *)base,(elms-1)+(eightbytes *)base); break; case 8: fsort_8(( b8 *)base,(elms-1)+( b8 *)base); break;
case 16: fsort_16((b16 *)base,(elms-1)+(b16 *)base); break;
default: default:
tmp_area=(char *)alloca(elmSize); tmp_area=(char *)alloca(elmSize);
fsort_n((char *)base,((char *)base) + size * (elms - 1)); fsort_n((char *)base,((char *)base) + size * (elms - 1));
......
#define INC(X) X=STEP(X,1)
#define DEC(X) X=STEP(X,-1)
#define SIZE ((long)STEP((TYPE *)0,1))
static void ID(register TYPE *bas, register TYPE *last)
{
register TYPE *a,*b, tmp;
if(bas >= last) return;
a = STEP(bas,1);
if(a == last)
{
if( (*cmpfun)((void *)bas,(void *)last) > 0) SWAP(bas,last);
}else{
b=STEP(bas,((((char *)last)-((char *)bas))/SIZE)>>1);
SWAP(bas,b);
b=last;
while(a < b)
{
#if 1
while(a<b)
{
while(1)
{
if(a<=b && (*cmpfun)((void *)a,(void *)bas) <= 0)
INC(a);
else
{
while(a< b && (*cmpfun)((void *)bas,(void *)b) <= 0) DEC(b);
break;
}
if(a< b && (*cmpfun)((void *)bas,(void *)b) <= 0)
DEC(b);
else
{
while(a<=b && (*cmpfun)((void *)a,(void *)bas) <= 0) INC(a);
break;
}
}
if(a<b)
{
SWAP(a,b);
INC(a);
if(b > STEP(a,1)) DEC(b);
}
}
#else
while(a<=b && (*cmpfun)((void *)a,(void *)bas) < 0) INC(a);
while(a< b && (*cmpfun)((void *)bas,(void *)b) < 0) DEC(b);
if(a<b)
{
SWAP(a,b);
INC(a);
if(b > STEP(a,1)) DEC(b);
}
#endif
}
DEC(a);
SWAP(a,bas);
DEC(a);
ID(bas,a);
ID(b,last);
}
}
#undef INC
#undef DEC
#undef SIZE
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment