/****Copyright (c) 1997-2009 All rights reserved
 ****A. V. Gerbessiotis and C. J. Siniolakis
 ****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 "smrg.h"

/* more optimizations over gmerge 11 */
void gmerge21(void *asrc1, void *asrc2, int m1, int m2, int size, 
                int (*compare)(const void *,const void *))
{
 register char *temp,*SRC,*DES;
 register int i,j,l,M;
 register char *src1,*src2;

 if (((m1<=0)&&(m2<=0))||(size<=0)) return;

 src1=(char *) asrc1;
 src2=(char *) asrc2;
 temp = (char *) malloc((m1+m2)*size);
#ifdef SANITY_CHECK
 if (temp == NULL) {
   printf("gmerge11: malloc ERROR\n");
   return;	
 }
#endif
  i=j=l=0;
  while ((i < m1) && (j < m2)) {
    if (compare((src1),(src2)) < 0) {
      MEMCPY(temp,src1,size);
      i++;l++;src1+=size;temp+=size;
    }
    else {
      MEMCPY(temp,src2,size);
      j++;l++;src2+=size;temp+=size;
    }
  }

  if (i < m1) MEMCPY(temp,src1,(m1-i)*size);
  if (j < m2) MEMCPY(temp,src2,(m2-j)*size);
/*
  MEMCPY(src1-i*size,temp-l*size,m1*size);
  MEMCPY(src2-j*size,temp+(m1-l)*size,m2*size);
*/
  MEMCPY(asrc1,temp-l*size,m1*size);
  MEMCPY(asrc2,temp+(m1-l)*size,m2*size);

  free((void *)temp);
}
