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 ;
 | |
| }
 |