204 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/* s4sort.c   (c)Copyright Sequiter Software Inc., 1988-1996.  All rights reserved.
 | 
						|
 | 
						|
Internal sort information is saved as follows:
 | 
						|
   Sort Info, Rec Num, Other Info
 | 
						|
 | 
						|
s4quick assumes there is an extra four bytes where the record number
 | 
						|
is put.
 | 
						|
*/
 | 
						|
 | 
						|
#include "d4all.h"
 | 
						|
#ifndef S4UNIX
 | 
						|
   #ifdef __TURBOC__
 | 
						|
      #pragma hdrstop
 | 
						|
   #endif
 | 
						|
#endif
 | 
						|
 | 
						|
void s4deleteSpoolEntry( SORT4 *s4 )
 | 
						|
{
 | 
						|
   memcpy( (void *)s4->spoolPointer, (void *)( s4->spoolPointer + 1 ), --s4->spoolsN * sizeof( S4SPOOL ) ) ;
 | 
						|
}
 | 
						|
 | 
						|
int s4flush( SORT4 *s4 )
 | 
						|
{
 | 
						|
   unsigned i ;
 | 
						|
   int rc ;
 | 
						|
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( s4 == 0 )
 | 
						|
         return error4( 0, e4parm_null, E91801 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   rc = s4quick( (void **) s4->pointers, s4->pointersUsed, s4->cmp, s4->sortLen ) ;
 | 
						|
   if ( rc < 0 )
 | 
						|
      return error4stack( s4->codeBase, (short)rc, E91801 ) ;
 | 
						|
 | 
						|
   if ( s4->spoolsMax == 0 )  /* Temporary file must be created. */
 | 
						|
   {
 | 
						|
      file4tempLow( &s4->file, s4->codeBase, 1 ) ;
 | 
						|
      file4seqWriteInit( &s4->seqwrite, &s4->file, 0L, s4->seqwriteBuffer, s4->codeBase->memSizeSortBuffer ) ;
 | 
						|
   }
 | 
						|
 | 
						|
   for ( i = 0; i < s4->pointersUsed; i++ )
 | 
						|
      if ( file4seqWrite( &s4->seqwrite, s4->pointers[i], s4->totLen) < 0 ) return -1 ;
 | 
						|
 | 
						|
   s4->pointersUsed = 0 ;
 | 
						|
   if ( (unsigned long) s4->spoolsMax * (unsigned long) sizeof(S4SPOOL) >= (unsigned long) UINT_MAX )
 | 
						|
   {
 | 
						|
      sort4free( s4 ) ;
 | 
						|
      return error4( s4->codeBase, e4memory, E91801 ) ;
 | 
						|
   }
 | 
						|
   s4->spoolsMax++ ;
 | 
						|
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
int S4FUNCTION sort4free( SORT4 *s4 )
 | 
						|
{
 | 
						|
   void *poolPtr ;
 | 
						|
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( s4 == 0 )
 | 
						|
         return error4( 0, e4parm_null, E91804 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   u4free( s4->spoolPointer ) ;
 | 
						|
   u4free( s4->pointers ) ;
 | 
						|
   u4free( s4->seqwriteBuffer ) ;
 | 
						|
 | 
						|
   if ( s4->file.hand >= 0 )
 | 
						|
      if ( file4close( &s4->file ) < 0 )
 | 
						|
         return -1 ;
 | 
						|
 | 
						|
   for ( ;; )
 | 
						|
   {
 | 
						|
      poolPtr = l4pop( &s4->pool ) ;
 | 
						|
      if ( poolPtr == 0 )
 | 
						|
         break ;
 | 
						|
      mem4free( s4->poolMemory, poolPtr ) ;
 | 
						|
   }
 | 
						|
   mem4release( s4->poolMemory ) ;
 | 
						|
 | 
						|
   memset( (void *)s4, 0, sizeof(SORT4) ) ;
 | 
						|
   s4->file.hand = -1 ;
 | 
						|
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
int S4FUNCTION sort4get( SORT4 *s4, long *recPtr, void **sortData, void **infoPtr )
 | 
						|
{
 | 
						|
   char *ptr ;
 | 
						|
   int rc ;
 | 
						|
 | 
						|
   #ifdef E4PARM_HIGH
 | 
						|
      if ( s4 == 0 )
 | 
						|
         return error4( 0, e4parm_null, E91802 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( error4code( s4->codeBase ) < 0 )
 | 
						|
      return e4codeBase ;
 | 
						|
 | 
						|
   rc = sort4getPtrPtr( s4, &ptr ) ;
 | 
						|
   if ( rc < 0 )
 | 
						|
      return error4stack( s4->codeBase, (short)rc, E91802 ) ;
 | 
						|
   if ( rc )
 | 
						|
      return rc ;
 | 
						|
 | 
						|
   memcpy( (void *)recPtr, ptr + s4->sortLen, sizeof( long ) ) ;
 | 
						|
   *sortData= (void *)ptr ;
 | 
						|
   *infoPtr = (void *)( ptr + s4->infoOffset ) ;
 | 
						|
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
int sort4getPtrPtr( SORT4 *s4, char **ptrPtr )
 | 
						|
{
 | 
						|
   if ( s4->pointers != 0 )  /* then no spooling was done */
 | 
						|
   {
 | 
						|
      if ( s4->pointersI < s4->pointersUsed )
 | 
						|
      {
 | 
						|
         *ptrPtr = (char *)s4->pointers[s4->pointersI++] ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
      if ( sort4free( s4 ) < 0 )
 | 
						|
         return -1 ;
 | 
						|
      return 1 ;
 | 
						|
   }
 | 
						|
 | 
						|
   if ( s4->spoolsN == 0 )
 | 
						|
   {
 | 
						|
      if ( sort4free( s4 ) < 0 )
 | 
						|
         return -1 ;
 | 
						|
      return 1 ;  /* None available */
 | 
						|
   }
 | 
						|
 | 
						|
   if ( s4nextSpoolEntry( s4 ) < 0 )
 | 
						|
      return -1 ;
 | 
						|
 | 
						|
   if ( s4->spoolsN == 0 )
 | 
						|
   {
 | 
						|
      if ( sort4free( s4 ) < 0 )
 | 
						|
         return -1 ;
 | 
						|
      return 1 ;
 | 
						|
   }
 | 
						|
   *ptrPtr = s4->spoolPointer->ptr + s4->spoolPointer->pos ;
 | 
						|
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
int S4FUNCTION sort4put( SORT4 *s4, const long rec, const void *sortData, const void *info )
 | 
						|
{
 | 
						|
   char *ptr ;
 | 
						|
   int rc ;
 | 
						|
   unsigned ptrMemAvail, newEntries ;
 | 
						|
 | 
						|
   #ifdef E4PARM_HIGH
 | 
						|
      if ( s4 == 0 || rec < 0L || sortData == 0 )
 | 
						|
         return error4( 0, e4parm, E91803 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( error4code( s4->codeBase ) < 0 )
 | 
						|
      return e4codeBase ;
 | 
						|
 | 
						|
   if ( s4->pointersUsed >= s4->pointersInit )
 | 
						|
   {
 | 
						|
      if ( s4->pointersUsed < s4->pointersMax && s4->isMemAvail )
 | 
						|
      {
 | 
						|
         ptr = (char *)mem4alloc( s4->poolMemory ) ;
 | 
						|
         if ( ptr == 0 )
 | 
						|
         {
 | 
						|
            ptrMemAvail = ( s4->pointersMax - s4->pointersUsed ) * ( sizeof( char * ) ) - ( sizeof( long ) ) ;
 | 
						|
            newEntries = ptrMemAvail / ( sizeof( char * ) + s4->totLen ) ;
 | 
						|
            s4->pointersMax = s4->pointersUsed + newEntries ;
 | 
						|
            sort4initPointers( s4, (char *)( s4->pointers + s4->pointersMax ), newEntries * s4->totLen ) ;
 | 
						|
            s4->isMemAvail = 0  ;
 | 
						|
         }
 | 
						|
         else
 | 
						|
         {
 | 
						|
            l4add( &s4->pool, ptr ) ;
 | 
						|
            s4->poolN++ ;
 | 
						|
            sort4initPointers( s4, ptr + sizeof( LINK4 ), s4->codeBase->memSizeSortPool - sizeof( LINK4 ) ) ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   if ( s4->pointersUsed >= s4->pointersInit )
 | 
						|
   {
 | 
						|
      rc = s4flush( s4 ) ;
 | 
						|
      if ( rc < 0 )
 | 
						|
         return error4stack( s4->codeBase, (short)rc, E91803 ) ;
 | 
						|
   }
 | 
						|
 | 
						|
   #ifdef E4ANALYZE
 | 
						|
      if ( s4->pointersUsed >= s4->pointersInit )
 | 
						|
         return error4( s4->codeBase, e4result, E91803 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   ptr = s4->pointers[s4->pointersUsed++] ;
 | 
						|
   memcpy( ptr, sortData, s4->sortLen ) ;
 | 
						|
   memcpy( ptr+ s4->sortLen, (void *)&rec, sizeof( rec ) ) ;
 | 
						|
   memcpy( ptr+ s4->infoOffset, info, s4->infoLen ) ;
 | 
						|
 | 
						|
   return 0 ;
 | 
						|
}
 |