/****Copyright (c) 1997-2009 All rights reserved
 ****A. V. Gerbessiotis 
 ****Permission to use, copy, modify, and distribute this software,
 ****and to incorporate it, in whole or in part, into 
 ****other software,is hereby granted without fee, provided that
 ****  (1) the above copyright notice and this permission 
 ****      notice appear in all copies of the source code, and 
 ****      the above copyright notice appear in clearly visible 
 ****      form on all supporting documentation and distribution 
 ****      media, and
 ****     (2) any redistribution of the software, in original
 ****         or modified form, be without fee and subject to
 ****         these same conditions.
 ****   No guarantee, whatsoever, is offered that the code works as
 ****   advertised or is absent of any, even damaging,
 ****   side-effects. Use this code at your own personal risk.
 ****/

#include "ssrt.h"
#include "avgmain.h"
#define ALL_FUNCTIONS
#undef  ALL_FUNCTIONS
#undef  FEW_FUNCTIONS
#define FEW_FUNCTIONS

#define N_SORT_ALGS 42
#define DEBUG 0

int compare(const void *x,const void *y)
{
	return(int)(* ((data*)x)-*((data*)y));
}

int main(int argc,char *argv[]) {
  int i,j,k,n,runs, type;
  data *ptr,*bptr;
  double elapsed;
  void (*gfunc[N_SORT_ALGS])() = {  
	qsort,	  g50gnu,   g51wbh,   g52dbh,   g53fbc,   g55non1,	
	g61wbh,	  g62dbh,   g63fbc,   g65non1,  g65non2,  g65non2,
	g66non1,  g66non2,  g67,      g68non1,  g68non2,  g68wbh,     
        g69non1 , g30mrgit, g39mrgit, g33heapx, g34heapx, g35heapx, 
        g35heapn, g36heapx, g36heapn, g37heapx, my1,      my2,
        my3,      my4,      my5,      g168non1, g168wbh,  g162dbh,
	g170my3,  g170my4,  g266non2, g154fbc,  g253fbc,  g268wbh
  };
  char *labels[N_SORT_ALGS]   = {
	"qsort",    "g50gnu",   "g51wbh",   "g52dbh",   "g53fbc",   "g55non1",	
	"g61wbh",   "g62dbh",   "g63fbc",   "g65non1",  "g65non2",  "g65non2",
	"g66non1",  "g66non2",  "g67",      "g68non1",  "g68non2",  "g68wbh",     
        "g69non1",  "g30mrgit", "g39mrgit", "g33heapx", "g34heapx", "g35heapx", 
        "g35heapn", "g36heapx", "g36heapn", "g37heapx", "my1",      "my2",
        "my3",      "my4",      "my5",      "g168non1", "g168wbh/my1",  "g162dbh/my2",
	"g170my3",  "g170my4",  "g266non2", "g154fbc",  "g253fbc",  "g268wbh"
  };


  int doalg[N_SORT_ALGS] = {
 	1,1,0,0,0,0,
	0,0,0,0,0,0,
	0,0,0,0,0,0,
	0,1,1,0,0,0,
	0,0,0,0,0,0,
        0,0,0,0,0,0,
	0,0,0,0,0,0
/*
 	1,1,0,0,0,0,
	0,0,0,0,0,0,
	0,1,0,1,1,0,
	1,0,0,0,0,0,
	0,0,0,0,1,1,
        1,1,1,1,1,1,
	1,1,1,1,1,1
*/
       };


  void (*GTYPESORT)(void *,int,int,int (*) (const void *,const void *));

  n=1000;runs=1;
  if (( argc <= 1 ) || (argc > 4)) {
    printf("Usage: %s size runs type\nDEFAULTS= THRES16=%d TMERGE=%d SPLITTER=%d (0:left,1:middle,2:random)\n",argv[0],THRES16,TMERGE,SPLITTER);
    return(1);
  } 
  else {
    n = atoi(argv[1]);
    runs=atoi(argv[2]);
    type=atoi(argv[3]);
   }

   ptr = (data*) Malloc(n*sizeof(data),"ptr ");
   bptr= (data*) Malloc(n*sizeof(data),"bptr ");
   memset( ptr,0,n*sizeof(data));
   memset(bptr,0,n*sizeof(data));

   srandom(21+1001*11);
   for(i=0;i<n;i++)  {
    if  ( type==1 ) {
     bptr[i]=ptr[i]=(data) (random()&MODULO_UINT);
    }
    if  ( type==2 ) {
     bptr[i]=ptr[i]=(int) ((n)*(random()/((double)INT_MAX)));
    }
    if  ( type==3 ) {
     bptr[i]=ptr[i]=(int) 10;
    }
    if  ( type==4 ) {
     bptr[i]=ptr[i]=(int) i;
    }
    if  ( type>=5 ) {
     bptr[i]=ptr[i]=(int) n-i+1;
    }
   }

  
/*
     bptr[i]=ptr[i]=(int) ((n)*(random()/((double)INT_MAX)));
     bptr[i]=ptr[i]=(int) random();
*/
   for(k=0;k<N_SORT_ALGS;k++) {
    if (doalg[k]==1) {
     GTYPESORT=gfunc[k];
     WRITELINE1; WRITE1;
     GTYPESORT(ptr,n,sizeof(data),compare);
     WRITE2; WRITELINE2; CHECKLINE;
     printf("%12s generic: Elapsed time is: %10.8f\n",labels[k],elapsed/runs);
    }
   }

   Free((void *) bptr,n*sizeof(data),"bptr");
   Free((void *) ptr,n*sizeof(data),"ptr");

   return(0);
}
