277 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			277 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/* s4init.c   (c)Copyright Sequiter Software Inc., 1988-1996.  All rights reserved. */
 | 
						|
 | 
						|
#include "d4all.h"
 | 
						|
#ifndef S4UNIX
 | 
						|
   #ifdef __TURBOC__
 | 
						|
      #pragma hdrstop
 | 
						|
   #endif
 | 
						|
#endif
 | 
						|
 | 
						|
/* no spools */
 | 
						|
int S4FUNCTION sort4getMemInit( SORT4 *s4 )
 | 
						|
{
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( s4 == 0 )
 | 
						|
         return error4( 0, e4parm_null, E91901 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   s4quick( (void **)s4->pointers, s4->pointersUsed, s4->cmp, s4->sortLen) ;
 | 
						|
   #ifdef  E4ANALYZE
 | 
						|
      if ( s4->seqwriteBuffer == 0 )
 | 
						|
         return error4( s4->codeBase, e4info, E91901 ) ;
 | 
						|
   #endif
 | 
						|
   u4free( s4->seqwriteBuffer ) ;
 | 
						|
   s4->seqwriteBuffer = 0 ;
 | 
						|
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
int S4FUNCTION sort4getInit( SORT4 *s4 )
 | 
						|
{
 | 
						|
   int rc ;
 | 
						|
 | 
						|
   #ifdef E4PARM_HIGH
 | 
						|
      if ( s4 == 0 )
 | 
						|
         return error4( 0, e4parm_null, E91902 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( error4code( s4->codeBase ) < 0 )
 | 
						|
      return e4codeBase ;
 | 
						|
 | 
						|
   if ( s4->spoolsMax > 0 )
 | 
						|
   {
 | 
						|
      rc = sort4spoolsInit( s4, 0 ) ;
 | 
						|
      if ( rc == e4memory )
 | 
						|
      {
 | 
						|
         sort4free( s4 ) ;
 | 
						|
         return error4( s4->codeBase, e4memory, E91902 ) ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
   else
 | 
						|
   {
 | 
						|
      sort4getMemInit( s4 ) ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   return rc ;
 | 
						|
}
 | 
						|
 | 
						|
int S4FUNCTION sort4spoolsInit( SORT4 *s4, const int prevCall )
 | 
						|
{
 | 
						|
   unsigned int entriesPerSpool, spoolsPerPool, entriesUsed ;
 | 
						|
   void *ptr, *memFree ;
 | 
						|
   int rc ;
 | 
						|
   char *poolEntry, *poolEntryIterate ;
 | 
						|
   long spoolDiskI ;
 | 
						|
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( s4 == 0 || prevCall < 0 || prevCall > 1 )
 | 
						|
         return error4( 0, e4parm, E91903 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   poolEntry = (char *) 0 ;
 | 
						|
   if ( !prevCall )
 | 
						|
   {
 | 
						|
      rc = s4flush( s4 ) ;
 | 
						|
      if ( rc < 0 )
 | 
						|
         return error4stack( s4->codeBase, (short)rc, E91903 ) ;
 | 
						|
      rc = file4seqWriteFlush(&s4->seqwrite ) ;
 | 
						|
      if ( rc < 0 )
 | 
						|
         return error4stack( s4->codeBase, (short)rc, E91903 ) ;
 | 
						|
      #ifdef E4ANALYZE
 | 
						|
         if (s4->seqwriteBuffer == 0 )
 | 
						|
            return error4( s4->codeBase, e4info, E91903 ) ;
 | 
						|
      #endif
 | 
						|
      u4free( s4->seqwriteBuffer ) ;
 | 
						|
      s4->seqwriteBuffer = 0 ;
 | 
						|
 | 
						|
      u4free( s4->pointers ) ;
 | 
						|
      s4->pointers = 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   for (;;)
 | 
						|
   {
 | 
						|
      s4->spoolPointer = (S4SPOOL *)u4alloc( (long)sizeof(S4SPOOL) * s4->spoolsMax ) ;
 | 
						|
      if ( s4->spoolPointer )
 | 
						|
         break ;
 | 
						|
 | 
						|
      if ( l4last( &s4->pool ) == 0 )
 | 
						|
         return e4memory ;
 | 
						|
 | 
						|
      memFree = l4pop( &s4->pool ) ;
 | 
						|
      mem4free( s4->poolMemory, memFree ) ;
 | 
						|
      s4->poolN-- ;
 | 
						|
   }
 | 
						|
 | 
						|
   for(;;)
 | 
						|
   {
 | 
						|
      /* Split up the pools between the spools */
 | 
						|
      if ( s4->poolN == 0 )
 | 
						|
         spoolsPerPool = s4->spoolsMax ;
 | 
						|
      else
 | 
						|
         spoolsPerPool = (s4->spoolsMax+s4->poolN-1) / s4->poolN ;
 | 
						|
 | 
						|
      entriesPerSpool = s4->poolEntries / spoolsPerPool ;
 | 
						|
 | 
						|
      if ( entriesPerSpool == 0 )
 | 
						|
         return e4memory ;
 | 
						|
 | 
						|
      if ( s4->poolN != 0 )
 | 
						|
         break ;
 | 
						|
 | 
						|
      ptr = mem4alloc( s4->poolMemory ) ;
 | 
						|
      if ( ptr != 0 )
 | 
						|
      {
 | 
						|
         l4add( &s4->pool, ptr ) ;
 | 
						|
         s4->poolN++ ;
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
         s4->poolEntries /= 2 ;
 | 
						|
         for ( ;; )
 | 
						|
         {
 | 
						|
            ptr = l4pop(&s4->pool) ;
 | 
						|
            if ( ptr == 0 )
 | 
						|
               break ;
 | 
						|
            mem4free( s4->poolMemory, ptr ) ;
 | 
						|
         }
 | 
						|
         mem4release( s4->poolMemory ) ;
 | 
						|
         s4->poolMemory = mem4create( s4->codeBase, 1, (unsigned) s4->poolEntries*s4->totLen+sizeof(LINK4), 1, 1 ) ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   s4->spoolMemLen = entriesPerSpool * s4->totLen ;
 | 
						|
   s4->spoolDiskLen = (long)s4->pointersInit * s4->totLen ;
 | 
						|
 | 
						|
   entriesUsed = s4->poolEntries+1 ;  /* Entries used in current pool. */
 | 
						|
   poolEntryIterate = 0 ;
 | 
						|
 | 
						|
   for ( spoolDiskI = 0L; s4->spoolsN < s4->spoolsMax; )
 | 
						|
   {
 | 
						|
      c4memmove( s4->spoolPointer+1, s4->spoolPointer, sizeof(S4SPOOL)*s4->spoolsN ) ;
 | 
						|
      if ( entriesUsed + entriesPerSpool > s4->poolEntries )
 | 
						|
      {
 | 
						|
         entriesUsed = 0 ;
 | 
						|
         poolEntryIterate= (char *) l4next( &s4->pool, poolEntryIterate);
 | 
						|
         poolEntry = poolEntryIterate + sizeof(LINK4) ;
 | 
						|
      }
 | 
						|
      s4->spoolPointer->ptr = poolEntry ;
 | 
						|
      poolEntry   += (s4->totLen*entriesPerSpool) ;
 | 
						|
      entriesUsed += entriesPerSpool ;
 | 
						|
 | 
						|
      s4->spoolPointer->spoolI = s4->spoolsN++ ;
 | 
						|
      s4->spoolPointer->disk = spoolDiskI ;
 | 
						|
      spoolDiskI += s4->spoolDiskLen ;
 | 
						|
 | 
						|
      s4->spoolPointer->len = 0 ;
 | 
						|
         if ( s4->spoolsN < s4->spoolsMax )
 | 
						|
            s4nextSpoolEntry(s4) ;
 | 
						|
   }
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
int S4FUNCTION sort4init( SORT4 *s4, CODE4 *c4, const int sortL, const int infoL )
 | 
						|
{
 | 
						|
   #ifdef E4PARM_HIGH
 | 
						|
      if ( s4 == 0 || c4 == 0 )
 | 
						|
         return error4( c4, e4parm_null, E91904 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( error4code( c4 ) < 0 )
 | 
						|
      return e4codeBase ;
 | 
						|
 | 
						|
   sort4initSet( s4, c4, sortL, infoL ) ;
 | 
						|
   if ( sort4initAlloc( s4 ) == e4memory )
 | 
						|
   {
 | 
						|
      sort4free( s4 ) ;
 | 
						|
      return error4( c4, e4memory, E91904 ) ;
 | 
						|
   }
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
int S4FUNCTION sort4initSet( SORT4 *s4, CODE4 *c4, const int sortL, const int infoL )
 | 
						|
{
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( s4 == 0 || c4 == 0 || sortL < 0 || infoL < 0 )
 | 
						|
         return error4( 0, e4parm, E91905 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   memset( (void *)s4, 0, sizeof(SORT4) ) ;
 | 
						|
   s4->file.hand = -1 ;
 | 
						|
 | 
						|
   s4->codeBase = c4 ;
 | 
						|
   s4->cmp = (S4CMP_FUNCTION *)u4memcmp ;
 | 
						|
 | 
						|
   s4->sortLen = (unsigned int)sortL ;
 | 
						|
   s4->infoLen = (unsigned int)infoL ;
 | 
						|
   s4->infoOffset = s4->sortLen + sizeof( long ) ;
 | 
						|
   s4->totLen = s4->infoOffset + s4->infoLen ;
 | 
						|
   s4->poolEntries = ( c4->memSizeSortPool - sizeof( LINK4 ) ) / s4->totLen ;
 | 
						|
   s4->pointersMax = c4->memSizeSortPool / sizeof( char * ) ;
 | 
						|
   s4->isMemAvail = 1 ;
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
int S4FUNCTION sort4initAlloc( SORT4 *s4 )
 | 
						|
{
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( s4 == 0 )
 | 
						|
         return error4( 0, e4parm_null, E91906 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( s4->seqwriteBuffer == 0 )
 | 
						|
   {
 | 
						|
      s4->seqwriteBuffer = (char *)u4alloc( (long)s4->codeBase->memSizeSortBuffer ) ;
 | 
						|
      if ( s4->seqwriteBuffer == 0 )
 | 
						|
         return e4memory ;
 | 
						|
      file4seqWriteInit( &s4->seqwrite, &s4->file, 0L, s4->seqwriteBuffer, s4->codeBase->memSizeSortBuffer ) ;
 | 
						|
   }
 | 
						|
 | 
						|
   if ( s4->pointers == 0 )
 | 
						|
      for(;;)
 | 
						|
      {
 | 
						|
         s4->pointers = (char **)u4alloc( (long)s4->pointersMax * sizeof(char *) ) ;
 | 
						|
         if ( s4->pointers != 0 )
 | 
						|
            break ;
 | 
						|
 | 
						|
         s4->pointersMax /= 2 ;
 | 
						|
         if ( s4->pointersMax < 256 )
 | 
						|
            return e4memory ;
 | 
						|
      }
 | 
						|
 | 
						|
   #ifdef E4ANALYZE
 | 
						|
      if ( s4->poolMemory )
 | 
						|
         return error4( s4->codeBase, e4info, E81901 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   s4->poolMemory = mem4create( s4->codeBase, 1, s4->codeBase->memSizeSortPool,1,1);
 | 
						|
   if ( s4->poolMemory == 0 )
 | 
						|
         return e4memory ;
 | 
						|
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
void sort4initPointers( SORT4 *s4, char *availMem, unsigned int len )
 | 
						|
{
 | 
						|
   /* Assign 'pointers' */
 | 
						|
   unsigned int n, i ;
 | 
						|
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( s4 == 0 || availMem == 0 )
 | 
						|
      {
 | 
						|
         error4( 0, e4parm_null, E91907 ) ;
 | 
						|
         return ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   n = len / s4->totLen ;
 | 
						|
   i = s4->pointersInit ;
 | 
						|
 | 
						|
   s4->pointersInit += n ;
 | 
						|
   if ( s4->pointersInit > s4->pointersMax )
 | 
						|
      s4->pointersInit = s4->pointersMax ;
 | 
						|
 | 
						|
   for ( ; i < s4->pointersInit ; i++, availMem += s4->totLen )
 | 
						|
      s4->pointers[i] = availMem ;
 | 
						|
}
 |