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