2247 lines
		
	
	
		
			60 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			2247 lines
		
	
	
		
			60 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/* m4map.c   (c)Copyright Sequiter Software Inc., 1988-1996.  All rights reserved. */
 | 
						|
 | 
						|
#include "d4all.h"
 | 
						|
 | 
						|
#ifndef S4UNIX
 | 
						|
   #ifdef __TURBOC__
 | 
						|
      #pragma hdrstop
 | 
						|
   #endif
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef S4CLIENT
 | 
						|
#ifndef S4INDEX_OFF
 | 
						|
 | 
						|
static void bitmaps4free( BITMAP4 * ) ;
 | 
						|
 | 
						|
/* create a single bitmap structure */
 | 
						|
BITMAP4 *bitmap4create( L4LOGICAL *log, RELATE4 *relate, const char andOr, const char branch )
 | 
						|
{
 | 
						|
   BITMAP4 *map ;
 | 
						|
 | 
						|
   map = (BITMAP4 *)mem4alloc( log->codeBase->bitmapMemory ) ;
 | 
						|
   if ( map == 0 )  /* must handle by freeing... */
 | 
						|
      return 0 ;
 | 
						|
   memset( (void *)map, 0, sizeof( BITMAP4 ) ) ;
 | 
						|
 | 
						|
   map->log = log ;
 | 
						|
   map->relate = relate ;
 | 
						|
   map->andOr = andOr ;
 | 
						|
   map->branch = branch ;
 | 
						|
   return map ;
 | 
						|
}
 | 
						|
 | 
						|
/* free up a single bitmap structure */
 | 
						|
int bitmap4destroy( BITMAP4 *map )
 | 
						|
{
 | 
						|
   CONST4 *c_on, *c_next ;
 | 
						|
 | 
						|
   #ifdef E4PARM_HIGH
 | 
						|
      if ( map == 0 )
 | 
						|
         return error4( 0, e4parm_null, E93701 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   c_on = (CONST4 *)l4first( &map->ne ) ;
 | 
						|
   while( c_on != 0 )
 | 
						|
   {
 | 
						|
      c_next = (CONST4 *)l4next( &map->ne, c_on ) ;
 | 
						|
      const4deleteNe( &map->ne, c_on ) ;
 | 
						|
      c_on = c_next ;
 | 
						|
   }
 | 
						|
   mem4free( map->log->codeBase->bitmapMemory, map ) ;
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
/* can a query or subquery be bitmap optimized?  Also builds the bitmap representation */
 | 
						|
static BITMAP4 *bitmap4can( L4LOGICAL *log, int *pos, RELATE4 *relate )
 | 
						|
{
 | 
						|
   E4INFO *infoPtr, *infoTwo ;
 | 
						|
   int i, keyLen, tagPos, tagPos2, constPos ;
 | 
						|
   BITMAP4 *map, *childMap ;
 | 
						|
   CONST4 *temp, hold ;
 | 
						|
   char cTemp ;
 | 
						|
 | 
						|
   infoPtr = log->expr->info + *pos ;
 | 
						|
 | 
						|
   if ( infoPtr->functionI == E4AND || infoPtr->functionI == E4OR )
 | 
						|
   {
 | 
						|
      (*pos)-- ;
 | 
						|
      if ( infoPtr->functionI == E4AND && relate == 0 )
 | 
						|
         relate = (RELATE4 *)log->infoReport[*pos].relateDataList->pointers[0] ;
 | 
						|
 | 
						|
      if ( infoPtr->functionI == E4AND )
 | 
						|
         cTemp = 1 ;
 | 
						|
      else
 | 
						|
         cTemp = 2 ;
 | 
						|
 | 
						|
      map = bitmap4create( log, relate, cTemp, 1 ) ;
 | 
						|
      if ( map == 0 )
 | 
						|
         return 0 ;
 | 
						|
 | 
						|
      for( i = 0 ; i < infoPtr->numParms ; i++ )
 | 
						|
      {
 | 
						|
         childMap = bitmap4can( log, pos, relate ) ;
 | 
						|
         if ( childMap == 0 && error4code( log->codeBase ) == e4memory )
 | 
						|
         {
 | 
						|
            error4set( log->codeBase, 0 ) ;
 | 
						|
            bitmaps4free( map ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
 | 
						|
         if ( childMap != 0 )
 | 
						|
         {
 | 
						|
            l4add( &map->children, childMap ) ;
 | 
						|
            if ( childMap->andOr == 0 )
 | 
						|
               childMap->andOr = map->andOr ;
 | 
						|
         }
 | 
						|
         else
 | 
						|
            if ( cTemp == 2 )   /* if an or case, then cannot create if any sub-expression is not bitmap optimizeable */
 | 
						|
               for ( ;; )
 | 
						|
               {
 | 
						|
                  childMap = (BITMAP4 *)l4first( &map->children ) ;
 | 
						|
                  if ( childMap == 0 )
 | 
						|
                  {
 | 
						|
                     bitmap4destroy( map ) ;
 | 
						|
                     return 0 ;
 | 
						|
                  }
 | 
						|
                  l4remove( &map->children, childMap ) ;
 | 
						|
                  bitmap4destroy( childMap ) ;
 | 
						|
               }
 | 
						|
      }
 | 
						|
      if ( map->children.nLink == 0 )   /* not bitmap optimizeable */
 | 
						|
      {
 | 
						|
         bitmap4destroy( map ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
   else
 | 
						|
   {
 | 
						|
      if ( infoPtr->functionI >= E4COMPARE_START && infoPtr->functionI <= E4COMPARE_END )
 | 
						|
      {
 | 
						|
         /* One must be a constant and the other a tag. */
 | 
						|
         infoPtr-- ;
 | 
						|
         tagPos = *pos - 1 ;
 | 
						|
         tagPos2 = tagPos - infoPtr->numEntries ;
 | 
						|
         infoTwo = infoPtr - infoPtr->numEntries ;
 | 
						|
         (*pos) -= 1 + infoPtr->numEntries + infoTwo->numEntries ;
 | 
						|
 | 
						|
         if ( e4isConstant( infoPtr ) )
 | 
						|
         {
 | 
						|
            if ( !e4isTag( log->infoReport + tagPos2, log->expr, infoTwo, relate->data ) )
 | 
						|
               return 0 ;
 | 
						|
            constPos = tagPos ;
 | 
						|
            tagPos = tagPos2 ;
 | 
						|
         }
 | 
						|
         else
 | 
						|
         {
 | 
						|
            if ( e4isConstant( infoTwo ) == 0 || !e4isTag( log->infoReport + tagPos, log->expr, infoPtr, relate->data ) )
 | 
						|
               return 0 ;
 | 
						|
            constPos = tagPos2 ;
 | 
						|
            infoPtr = infoTwo ;
 | 
						|
         }
 | 
						|
 | 
						|
         map = bitmap4create( log, relate, 0, 0 ) ;
 | 
						|
         if ( map == 0 )
 | 
						|
            return 0 ;
 | 
						|
         map->tag = ( log->infoReport + tagPos )->tag ;
 | 
						|
 | 
						|
         infoPtr++ ;
 | 
						|
 | 
						|
         memset( (void *)&hold, 0, sizeof( CONST4 ) ) ;
 | 
						|
         if ( const4get( &hold, map, log, constPos ) < 0 )
 | 
						|
         {
 | 
						|
            bitmap4destroy( map ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
 | 
						|
         if ( infoPtr->functionI >= E4COMPARE_START && infoPtr->functionI <= E4COMPARE_END )
 | 
						|
         {
 | 
						|
            if ( infoPtr->functionI >= E4NOT_EQUAL && infoPtr->functionI < E4GREATER_EQ ) /* != */
 | 
						|
            {
 | 
						|
               temp = (CONST4 *)u4alloc( (long)sizeof( CONST4 ) ) ;
 | 
						|
               if ( temp == 0 )
 | 
						|
               {
 | 
						|
                  error4set( log->codeBase, 0 ) ;
 | 
						|
                  bitmaps4free( map ) ;
 | 
						|
                  return 0 ;
 | 
						|
               }
 | 
						|
               memcpy( (void *)temp, (void *)&hold, sizeof( CONST4 ) ) ;
 | 
						|
               l4add( &map->ne, temp ) ;
 | 
						|
            }
 | 
						|
            if (infoPtr->functionI >= E4EQUAL && infoPtr->functionI < E4GREATER) /* == */
 | 
						|
               memcpy( (void *)&map->eq, (void *)&hold, sizeof( CONST4 ) ) ;
 | 
						|
            if ( infoPtr->functionI >= E4GREATER && infoPtr->functionI < E4LESS ) /* > */
 | 
						|
            {
 | 
						|
               keyLen = map->tag->header.keyLen ;
 | 
						|
               #ifdef S4VFP_KEY
 | 
						|
                  if ( map->type == r4str && tfile4vfpKey( map->tag ) )
 | 
						|
                  {
 | 
						|
                     #ifdef E4_ANALYZE
 | 
						|
                        if ( keyLen%2 == 1 )
 | 
						|
                           return error4( data->codeBase, e4index, E82107 ) ;
 | 
						|
                     #endif
 | 
						|
                     keyLen = keyLen / 2 ;
 | 
						|
                  }
 | 
						|
               #endif
 | 
						|
               if ( map->type == r4str && hold.len < keyLen )   /* same as >= since a partial > */
 | 
						|
                  memcpy( (void *)&map->ge, (void *)&hold, sizeof( CONST4 ) ) ;
 | 
						|
               else
 | 
						|
                  memcpy( (void *)&map->gt, (void *)&hold, sizeof( CONST4 ) ) ;
 | 
						|
            }
 | 
						|
            if ( infoPtr->functionI >= E4GREATER_EQ && infoPtr->functionI < E4LESS_EQ ) /* >= */
 | 
						|
               memcpy( (void *)&map->ge, (void *)&hold, sizeof( CONST4 ) ) ;
 | 
						|
            if ( infoPtr->functionI >= E4LESS && infoPtr->functionI < E4CHR )  /* < */
 | 
						|
               memcpy( (void *)&map->lt, (void *)&hold, sizeof( CONST4 ) ) ;
 | 
						|
            if ( infoPtr->functionI >= E4LESS_EQ && infoPtr->functionI < E4EQUAL ) /* <= */
 | 
						|
               memcpy( (void *)&map->le, (void *)&hold, sizeof( CONST4 ) ) ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
      else
 | 
						|
         return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   return map ;
 | 
						|
}
 | 
						|
 | 
						|
/* free the bitmap tree */
 | 
						|
static void bitmaps4free( BITMAP4 *map )
 | 
						|
{
 | 
						|
   BITMAP4 *mapOn, *mapNext ;
 | 
						|
 | 
						|
   if ( map->branch == 1 )
 | 
						|
   {
 | 
						|
      mapOn = (BITMAP4 *)l4first( &map->children ) ;
 | 
						|
      while( mapOn != 0 )
 | 
						|
      {
 | 
						|
         mapNext = (BITMAP4 *)l4next( &map->children, mapOn ) ;
 | 
						|
         l4remove( &map->children, mapOn ) ;
 | 
						|
         bitmaps4free( mapOn ) ;
 | 
						|
         mapOn = mapNext ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   bitmap4destroy( map ) ;
 | 
						|
}
 | 
						|
 | 
						|
/* free all the bitmap info */
 | 
						|
static void bitmap4free( L4LOGICAL *log, BITMAP4 *map )
 | 
						|
{
 | 
						|
   bitmaps4free( map ) ;
 | 
						|
   u4free( log->buf ) ;
 | 
						|
   log->buf = 0 ;
 | 
						|
   log->bufLen = 0 ;
 | 
						|
   log->bufPos = 0 ;
 | 
						|
}
 | 
						|
 | 
						|
/* initialize the bitmap structures, determine if bitmapping is possible */
 | 
						|
static BITMAP4 *bitmap4init( L4LOGICAL *log, int pos )
 | 
						|
{
 | 
						|
   E4INFO *infoPtr ;
 | 
						|
   int passPos ;
 | 
						|
   BITMAP4 *map ;
 | 
						|
 | 
						|
   infoPtr = log->expr->info + pos ;
 | 
						|
 | 
						|
   /* for testing purposes only, allow bitmap disabling */
 | 
						|
   if ( log->relation->bitmapDisable == 1 || ( (unsigned long)d4recCount( log->relation->relate.data ) / 16UL >= ( (unsigned long)((unsigned long)UINT_MAX - 2UL)) / 2UL ) )
 | 
						|
   {
 | 
						|
      log->relation->bitmapsFreed = 1 ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   if ( log->codeBase->bitmapMemory == 0 )
 | 
						|
   {
 | 
						|
      log->codeBase->bitmapMemory = mem4create( log->codeBase, 10, sizeof( BITMAP4 ), 5, 0 ) ;
 | 
						|
      if ( log->codeBase->bitmapMemory == 0 )  /* no memory available for bitmap optimization */
 | 
						|
         return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   passPos = pos ;
 | 
						|
   if ( infoPtr->functionI == E4AND )
 | 
						|
      map = bitmap4can( log, &passPos, &log->relation->relate ) ;
 | 
						|
   else
 | 
						|
      map = bitmap4can( log, &passPos, &log->relation->relate ) ;
 | 
						|
 | 
						|
   if ( map == 0 && error4code( log->codeBase ) == e4memory )
 | 
						|
      error4set( log->codeBase, 0 ) ;
 | 
						|
 | 
						|
   return map ;
 | 
						|
}
 | 
						|
 | 
						|
/* this function removes all bitmaps from the parent and marks the parent as zero */
 | 
						|
static BITMAP4 *bitmap4collapse( BITMAP4 *parent )
 | 
						|
{
 | 
						|
   BITMAP4 *childOn, *childNext ;
 | 
						|
 | 
						|
   childOn = (BITMAP4 *)l4first( &parent->children ) ;
 | 
						|
   if ( parent->tag == 0 && childOn->tag != 0 )
 | 
						|
      parent->tag = childOn->tag ;
 | 
						|
   while( childOn != 0 )
 | 
						|
   {
 | 
						|
      #ifdef E4ANALYZE
 | 
						|
         if ( childOn->tag == 0 && childOn->children.nLink == 0 )
 | 
						|
         {
 | 
						|
            error4( parent->log->codeBase, e4info, E93701 ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
      #endif
 | 
						|
      childNext = (BITMAP4 *)l4next( &parent->children, childOn ) ;
 | 
						|
      l4remove( &parent->children, childOn ) ;
 | 
						|
      bitmap4destroy( childOn ) ;
 | 
						|
      childOn = childNext ;
 | 
						|
   }
 | 
						|
   parent->noMatch = 1 ;
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* 0 = successful merger, 1 means collaps because now no records belong to the set */
 | 
						|
static int bitmap4combineAndLe( BITMAP4 *map1, BITMAP4 *map2 )
 | 
						|
{
 | 
						|
   CONST4 *cOn, *cNext ;
 | 
						|
   char eqFound ;
 | 
						|
 | 
						|
   if ( map1->eq.len )
 | 
						|
   {
 | 
						|
      if ( const4less( &map2->le, &map1->eq, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
      else
 | 
						|
      {
 | 
						|
         memset( (void *)&map2->le, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->gt.len )
 | 
						|
      if ( const4lessEq( &map2->le, &map1->gt, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
 | 
						|
   if ( map1->ge.len )
 | 
						|
   {
 | 
						|
      if ( const4less( &map2->le, &map1->ge, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
      if ( const4eq( &map2->le, &map1->ge, map1 ) )
 | 
						|
      {
 | 
						|
         if ( map2->eq.len )
 | 
						|
            if ( !const4eq( &map2->eq, &map2->le, map1 ) )
 | 
						|
               return 1 ;
 | 
						|
         memcpy( (void *)&map2->eq, (void *)&map2->le, sizeof( CONST4 ) ) ;
 | 
						|
         memset( (void *)&map2->le, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->ne.nLink != 0 )  /* special case */
 | 
						|
   {
 | 
						|
      cOn = (CONST4 *)l4first( &map1->ne ) ;
 | 
						|
      eqFound = 0 ;
 | 
						|
      while ( cOn != 0 )
 | 
						|
      {
 | 
						|
         cNext = (CONST4 *)l4next( &map1->ne, cOn ) ;
 | 
						|
         if ( const4less( &map2->le, cOn, map1 ) )
 | 
						|
            const4deleteNe( &map1->ne, cOn ) ;
 | 
						|
         else
 | 
						|
            if ( eqFound == 0 )
 | 
						|
               if ( const4eq( &map2->le, cOn, map1 ) )
 | 
						|
                  eqFound = 1 ;
 | 
						|
         cOn = cNext ;
 | 
						|
      }
 | 
						|
      if ( eqFound )
 | 
						|
      {
 | 
						|
         memcpy( (void *)&map2->lt, (void *)&map2->le, sizeof( CONST4 ) ) ;
 | 
						|
         memset( (void *)&map2->le, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->lt.len )
 | 
						|
   {
 | 
						|
      if ( const4less( &map2->le, &map1->lt, map1 ) )
 | 
						|
      {
 | 
						|
         memcpy( (void *)&map1->le, (void *)&map2->le, sizeof( CONST4 ) ) ;
 | 
						|
         memset( (void *)&map1->lt, 0, sizeof( CONST4 ) ) ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
   else
 | 
						|
   {
 | 
						|
      if ( map1->le.len )
 | 
						|
      {
 | 
						|
         if ( const4less( &map2->le, &map1->le, map1 ) )
 | 
						|
            memcpy( (void *)&map1->le, (void *)&map2->le, sizeof( CONST4 ) ) ;
 | 
						|
      }
 | 
						|
      else
 | 
						|
         memcpy( (void *)&map1->le, (void *)&map2->le, sizeof( CONST4 ) ) ;
 | 
						|
   }
 | 
						|
 | 
						|
   memset( (void *)&map2->le, 0, sizeof( CONST4 ) ) ;
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
/* 0 = successful merger, 1 means collaps because now no records belong to the set */
 | 
						|
static int bitmap4combineAndGe( BITMAP4 *map1, BITMAP4 *map2 )
 | 
						|
{
 | 
						|
   CONST4 *cOn, *cNext ;
 | 
						|
   char eqFound ;
 | 
						|
 | 
						|
   if ( map1->eq.len )
 | 
						|
   {
 | 
						|
      if ( const4less( &map1->eq, &map2->ge, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
      else
 | 
						|
      {
 | 
						|
         memset( (void *)&map2->ge, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->lt.len )
 | 
						|
   {
 | 
						|
      if ( const4lessEq( &map1->lt, &map2->ge, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
   }
 | 
						|
   else
 | 
						|
      if ( map1->le.len )
 | 
						|
      {
 | 
						|
         if ( const4less( &map1->le, &map2->ge, map1 ) )
 | 
						|
            return 1 ;
 | 
						|
         if ( const4eq( &map1->le, &map2->ge, map1 ) )
 | 
						|
         {
 | 
						|
            if ( map2->eq.len )
 | 
						|
               if ( !const4eq( &map2->eq, &map2->ge, map1 ) )
 | 
						|
                  return 1 ;
 | 
						|
            memcpy( (void *)&map2->eq, (void *)&map2->ge, sizeof( CONST4 ) ) ;
 | 
						|
            memset( (void *)&map2->ge, 0, sizeof( CONST4 ) ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
 | 
						|
   if ( map1->ne.nLink != 0 )  /* special case */
 | 
						|
   {
 | 
						|
      cOn = (CONST4 *)l4first( &map1->ne ) ;
 | 
						|
      eqFound = 0 ;
 | 
						|
      while ( cOn != 0 )
 | 
						|
      {
 | 
						|
         cNext = (CONST4 *)l4next( &map1->ne, cOn ) ;
 | 
						|
         if ( const4less( cOn, &map2->ge, map1 ) )
 | 
						|
            const4deleteNe( &map1->ne, cOn ) ;
 | 
						|
         else
 | 
						|
            if ( eqFound == 0 )
 | 
						|
               if ( const4eq( cOn, &map2->ge, map1 ) )
 | 
						|
                  eqFound = 1 ;
 | 
						|
         cOn = cNext ;
 | 
						|
      }
 | 
						|
      if ( eqFound )
 | 
						|
      {
 | 
						|
         memcpy( (void *)&map2->gt, (void *)&map2->ge, sizeof( CONST4 ) ) ;
 | 
						|
         memset( (void *)&map2->ge, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->gt.len )
 | 
						|
   {
 | 
						|
      if ( const4less( &map1->gt, &map2->ge, map1 ) )
 | 
						|
      {
 | 
						|
         memcpy( (void *)&map1->ge, (void *)&map2->ge, sizeof( CONST4 ) ) ;
 | 
						|
         memset( (void *)&map1->gt, 0, sizeof( CONST4 ) ) ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
   else
 | 
						|
   {
 | 
						|
      if ( map1->ge.len )
 | 
						|
      {
 | 
						|
         if ( const4less( &map1->ge, &map2->ge, map1 ) )
 | 
						|
            memcpy( (void *)&map1->ge, (void *)&map2->ge, sizeof( CONST4 ) ) ;
 | 
						|
      }
 | 
						|
      else
 | 
						|
         memcpy( (void *)&map1->ge, (void *)&map2->ge, sizeof( CONST4 ) ) ;
 | 
						|
   }
 | 
						|
   memset( (void *)&map2->ge, 0, sizeof( CONST4 ) ) ;
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
/* 0 = successful merger, 1 means collaps because now no records belong to the set */
 | 
						|
static int bitmap4combineAndLt( BITMAP4 *map1, BITMAP4 *map2 )
 | 
						|
{
 | 
						|
   CONST4 *cOn, *cNext ;
 | 
						|
 | 
						|
   if ( map1->eq.len )
 | 
						|
   {
 | 
						|
      if ( const4lessEq( &map2->lt, &map1->eq, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
      else
 | 
						|
      {
 | 
						|
         memset( (void *)&map2->lt, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->ne.nLink != 0 )  /* special case */
 | 
						|
   {
 | 
						|
      cOn = (CONST4 *)l4first( &map1->ne ) ;
 | 
						|
      while ( cOn != 0 )
 | 
						|
      {
 | 
						|
         cNext = (CONST4 *)l4next( &map1->ne, cOn ) ;
 | 
						|
         if ( const4lessEq( &map2->lt, cOn, map1 ) )
 | 
						|
            const4deleteNe( &map1->ne, cOn ) ;
 | 
						|
         cOn = cNext ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->gt.len )
 | 
						|
   {
 | 
						|
      if ( const4lessEq( &map2->lt, &map1->gt, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
   }
 | 
						|
   else
 | 
						|
      if ( map1->ge.len )
 | 
						|
         if ( const4lessEq( &map2->lt, &map1->ge, map1 ) )
 | 
						|
            return 1 ;
 | 
						|
 | 
						|
   if ( map1->lt.len )
 | 
						|
   {
 | 
						|
      if ( const4lessEq( &map2->lt, &map1->lt, map1 ) )
 | 
						|
         memcpy( (void *)&map1->lt, (void *)&map2->lt, sizeof( CONST4 ) ) ;
 | 
						|
   }
 | 
						|
   else
 | 
						|
   {
 | 
						|
      if ( map1->le.len )
 | 
						|
      {
 | 
						|
         if ( const4lessEq( &map2->lt, &map1->le, map1 ) )
 | 
						|
         {
 | 
						|
            memcpy( (void *)&map1->lt, (void *)&map2->lt, sizeof( CONST4 ) ) ;
 | 
						|
            memset( (void *)&map1->le, 0, sizeof( CONST4 ) ) ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
      else
 | 
						|
         memcpy( (void *)&map1->lt, (void *)&map2->lt, sizeof( CONST4 ) ) ;
 | 
						|
   }
 | 
						|
   memset( (void *)&map2->lt, 0, sizeof( CONST4 ) ) ;
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
/* 0 = successful merger, 1 means collaps because now no records belong to the set */
 | 
						|
static int bitmap4combineAndGt( BITMAP4 *map1, BITMAP4 *map2 )
 | 
						|
{
 | 
						|
   CONST4 *cOn, *cNext ;
 | 
						|
 | 
						|
   if ( map1->eq.len )
 | 
						|
   {
 | 
						|
      if ( const4lessEq( &map1->eq, &map2->gt, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
      else
 | 
						|
      {
 | 
						|
         memset( (void *)&map2->gt, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->ne.nLink != 0 )  /* special case */
 | 
						|
   {
 | 
						|
      cOn = (CONST4 *)l4first( &map1->ne ) ;
 | 
						|
      while ( cOn != 0 )
 | 
						|
      {
 | 
						|
         cNext = (CONST4 *)l4next( &map1->ne, cOn ) ;
 | 
						|
         if ( const4lessEq( cOn, &map2->gt, map1 ) )
 | 
						|
            const4deleteNe( &map1->ne, cOn ) ;
 | 
						|
         cOn = cNext ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->lt.len )
 | 
						|
   {
 | 
						|
      if ( const4lessEq( &map1->lt, &map2->gt, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
   }
 | 
						|
   else
 | 
						|
      if ( map1->le.len )
 | 
						|
         if ( const4lessEq( &map1->le, &map2->gt, map1 ) )
 | 
						|
            return 1 ;
 | 
						|
 | 
						|
   if ( map1->gt.len )
 | 
						|
   {
 | 
						|
      if ( const4less( &map1->gt, &map2->gt, map1 ) )
 | 
						|
         memcpy( (void *)&map1->gt, (void *)&map2->gt, sizeof( CONST4 ) ) ;
 | 
						|
   }
 | 
						|
   else
 | 
						|
   {
 | 
						|
      if ( map1->ge.len )
 | 
						|
      {
 | 
						|
         if ( const4lessEq( &map1->ge, &map2->gt, map1 ) )
 | 
						|
         {
 | 
						|
            memcpy( (void *)&map1->gt, (void *)&map2->gt, sizeof( CONST4 ) ) ;
 | 
						|
            memset( (void *)&map1->ge, 0, sizeof( CONST4 ) ) ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
      else
 | 
						|
         memcpy( (void *)&map1->gt, (void *)&map2->gt, sizeof( CONST4 ) ) ;
 | 
						|
   }
 | 
						|
   memset( (void *)&map2->gt, 0, sizeof( CONST4 ) ) ;
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
/* 0 = successful merger, 1 means collaps because now no records belong to the set */
 | 
						|
static int bitmap4combineAndNe( BITMAP4 *map1, BITMAP4 *map2 )
 | 
						|
{
 | 
						|
   CONST4 *cOn, *cNext, *cOn2, *cNext2 ;
 | 
						|
   int eqFound ;
 | 
						|
 | 
						|
   cOn = (CONST4 *)l4first( &map2->ne ) ;
 | 
						|
   while ( cOn != 0 )
 | 
						|
   {
 | 
						|
      cNext = (CONST4 *)l4next( &map2->ne, cOn ) ;
 | 
						|
 | 
						|
      if ( map1->eq.len )
 | 
						|
      {
 | 
						|
         if ( const4eq( cOn, &map1->eq, map1 ) )
 | 
						|
            return 1 ;
 | 
						|
         else
 | 
						|
         {
 | 
						|
            const4deleteNe( &map2->ne, cOn ) ;
 | 
						|
            cOn = cNext ;
 | 
						|
            continue ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
 | 
						|
      if ( map1->gt.len )
 | 
						|
      {
 | 
						|
         if ( const4lessEq( cOn, &map1->gt, map1 ) )
 | 
						|
         {
 | 
						|
            const4deleteNe( &map2->ne, cOn ) ;
 | 
						|
            cOn = cNext ;
 | 
						|
            continue ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
      else
 | 
						|
         if ( map1->ge.len )
 | 
						|
         {
 | 
						|
            if ( const4eq( cOn, &map1->ge, map1 ) )
 | 
						|
            {
 | 
						|
               memcpy( (void *)&map1->gt, (void *)&map1->ge, sizeof( CONST4 ) ) ;
 | 
						|
               memset( (void *)&map1->ge, 0, sizeof( CONST4 ) ) ;
 | 
						|
               const4deleteNe( &map2->ne, cOn ) ;
 | 
						|
               cOn = cNext ;
 | 
						|
               continue ;
 | 
						|
            }
 | 
						|
            if ( const4lessEq( cOn, &map1->ge, map1 ) )
 | 
						|
            {
 | 
						|
               const4deleteNe( &map2->ne, cOn ) ;
 | 
						|
               cOn = cNext ;
 | 
						|
               continue ;
 | 
						|
            }
 | 
						|
         }
 | 
						|
 | 
						|
      if ( map1->lt.len )
 | 
						|
      {
 | 
						|
         if ( const4lessEq( &map1->lt, cOn, map1 ) )
 | 
						|
         {
 | 
						|
            const4deleteNe( &map2->ne, cOn ) ;
 | 
						|
            cOn = cNext ;
 | 
						|
            continue ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
      else
 | 
						|
         if ( map1->le.len )
 | 
						|
         {
 | 
						|
            if ( const4eq( cOn, &map1->le, map1 ) )
 | 
						|
            {
 | 
						|
               memcpy( (void *)&map1->lt, (void *)&map1->le, sizeof( CONST4 ) ) ;
 | 
						|
               memset( (void *)&map1->le, 0, sizeof( CONST4 ) ) ;
 | 
						|
               const4deleteNe( &map2->ne, cOn ) ;
 | 
						|
               cOn = cNext ;
 | 
						|
               continue ;
 | 
						|
            }
 | 
						|
            if ( const4lessEq( &map1->le, cOn, map1 ) )
 | 
						|
            {
 | 
						|
               const4deleteNe( &map2->ne, cOn ) ;
 | 
						|
               cOn = cNext ;
 | 
						|
               continue ;
 | 
						|
            }
 | 
						|
         }
 | 
						|
 | 
						|
      if ( map1->ne.nLink != 0 )  /* special case */
 | 
						|
      {
 | 
						|
         cOn2 = (CONST4 *)l4first( &map1->ne ) ;
 | 
						|
         eqFound = 0 ;
 | 
						|
         while ( cOn2 != 0 )
 | 
						|
         {
 | 
						|
            cNext2 = (CONST4 *)l4next( &map1->ne, cOn2 ) ;
 | 
						|
            if ( const4eq( cOn, cOn2, map1 ) )
 | 
						|
            {
 | 
						|
               const4deleteNe( &map2->ne, cOn ) ;
 | 
						|
               cOn = cNext ;
 | 
						|
               eqFound = 1 ;
 | 
						|
               break ;
 | 
						|
            }
 | 
						|
            cOn2 = cNext2 ;
 | 
						|
         }
 | 
						|
         if ( eqFound != 1 )
 | 
						|
         {
 | 
						|
            l4remove( &map2->ne, cOn ) ;
 | 
						|
            l4add( &map1->ne, cOn ) ;
 | 
						|
         }
 | 
						|
         cOn = cNext ;
 | 
						|
         continue ;
 | 
						|
      }
 | 
						|
 | 
						|
      /* must add the ne */
 | 
						|
      l4remove( &map2->ne, cOn ) ;
 | 
						|
      l4add( &map1->ne, cOn ) ;
 | 
						|
      cOn = cNext ;
 | 
						|
   }
 | 
						|
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
/* 0 = successful merger, 1 means collaps because now no records belong to the set */
 | 
						|
static int bitmap4combineAndEq( BITMAP4 *map1, BITMAP4 *map2 )
 | 
						|
{
 | 
						|
   CONST4 *cOn, *cNext ;
 | 
						|
 | 
						|
   if ( map1->eq.len )
 | 
						|
   {
 | 
						|
      if ( const4eq( &map2->eq, &map1->eq, map1 ) )
 | 
						|
      {
 | 
						|
         memset( (void *)&map2->eq, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
      else
 | 
						|
         return 1 ;
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->ne.nLink != 0 )  /* special case */
 | 
						|
   {
 | 
						|
      cOn = (CONST4 *)l4first( &map1->ne ) ;
 | 
						|
      while ( cOn != 0 )
 | 
						|
      {
 | 
						|
         cNext = (CONST4 *)l4next( &map1->ne, cOn ) ;
 | 
						|
         if ( const4eq( &map2->eq, cOn, map1 ) )
 | 
						|
            return 1 ;
 | 
						|
         else
 | 
						|
            const4deleteNe( &map1->ne, cOn ) ;
 | 
						|
         cOn = cNext ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->le.len )
 | 
						|
   {
 | 
						|
      if ( const4less( &map1->le, &map2->eq, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
      memset( (void *)&map1->le, 0, sizeof( CONST4 ) ) ;
 | 
						|
   }
 | 
						|
   else
 | 
						|
      if ( map1->lt.len )
 | 
						|
      {
 | 
						|
         if ( const4lessEq( &map1->lt, &map2->eq, map1 ) )
 | 
						|
            return 1 ;
 | 
						|
         memset( (void *)&map1->lt, 0, sizeof( CONST4 ) ) ;
 | 
						|
      }
 | 
						|
 | 
						|
   if ( map1->ge.len )
 | 
						|
   {
 | 
						|
      if ( const4less( &map2->eq, &map1->ge, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
      memset( (void *)&map1->ge, 0, sizeof( CONST4 ) ) ;
 | 
						|
   }
 | 
						|
   else
 | 
						|
      if ( map1->gt.len )
 | 
						|
      {
 | 
						|
         if ( const4lessEq( &map2->eq, &map1->gt, map1 ) )
 | 
						|
            return 1 ;
 | 
						|
         memset( (void *)&map1->gt, 0, sizeof( CONST4 ) ) ;
 | 
						|
      }
 | 
						|
 | 
						|
   memcpy( (void *)&map1->eq, (void *)&map2->eq, sizeof( CONST4 ) ) ;
 | 
						|
   memset( (void *)&map2->eq, 0, sizeof( CONST4 ) ) ;
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
static int bitmap4combineOrLe( BITMAP4 *map1, BITMAP4 *map2 )
 | 
						|
{
 | 
						|
   CONST4 *cOn ;
 | 
						|
 | 
						|
   if ( map1->eq.len )
 | 
						|
      if ( const4lessEq( &map1->eq, &map2->le, map1 ) )
 | 
						|
         memset( (void *)&map1->eq, 0, sizeof( CONST4 ) ) ;
 | 
						|
 | 
						|
   if ( map1->gt.len )
 | 
						|
   {
 | 
						|
      if ( const4lessEq( &map1->gt, &map2->le, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
   }
 | 
						|
   else
 | 
						|
      if ( map1->ge.len )
 | 
						|
         if ( const4lessEq( &map1->ge, &map2->le, map1 ) )
 | 
						|
            return 1 ;
 | 
						|
 | 
						|
   if ( map1->ne.nLink != 0 )  /* special case */
 | 
						|
   {
 | 
						|
      #ifdef E4ANALYZE
 | 
						|
         if ( map1->ne.nLink != 1 )  /* if 2 links, all must belong... */
 | 
						|
            return error4( map1->log->codeBase, e4info, E93701 ) ;
 | 
						|
      #endif
 | 
						|
      cOn = (CONST4 *)l4first( &map1->ne ) ;
 | 
						|
      if ( const4lessEq( cOn, &map2->le, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
      else
 | 
						|
      {
 | 
						|
         memset( (void *)&map2->le, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->lt.len )
 | 
						|
   {
 | 
						|
      if ( const4lessEq( &map1->lt, &map2->le, map1 ) )
 | 
						|
         memset( (void *)&map1->lt, 0, sizeof( CONST4 ) ) ;
 | 
						|
      else
 | 
						|
      {
 | 
						|
         memset( (void *)&map2->le, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
   else
 | 
						|
      if ( map1->le.len )
 | 
						|
         if ( !const4lessEq( &map1->le, &map2->le, map1 ) )
 | 
						|
         {
 | 
						|
            memset( (void *)&map2->le, 0, sizeof( CONST4 ) ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
 | 
						|
   memcpy( (void *)&map1->le, (void *)&map2->le, sizeof( CONST4 ) ) ;
 | 
						|
   memset( (void *)&map2->le, 0, sizeof( CONST4 ) ) ;
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
static int bitmap4combineOrGe( BITMAP4 *map1, BITMAP4 *map2 )
 | 
						|
{
 | 
						|
   CONST4 *cOn ;
 | 
						|
 | 
						|
   if ( map1->eq.len )
 | 
						|
      if ( const4lessEq( &map2->ge, &map1->eq, map1 ) )
 | 
						|
         memset( (void *)&map1->eq, 0, sizeof( CONST4 ) ) ;
 | 
						|
 | 
						|
   if ( map1->lt.len )
 | 
						|
   {
 | 
						|
      if ( const4lessEq( &map2->ge, &map1->lt, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
   }
 | 
						|
   else
 | 
						|
      if ( map1->le.len )
 | 
						|
         if ( const4lessEq( &map2->ge, &map1->le, map1 ) )
 | 
						|
            return 1 ;
 | 
						|
 | 
						|
   if ( map1->ne.nLink != 0 )  /* special case */
 | 
						|
   {
 | 
						|
      #ifdef E4ANALYZE
 | 
						|
         if ( map1->ne.nLink != 1 )  /* if 2 links, all must belong... */
 | 
						|
            return error4( map1->log->codeBase, e4info, E93701 ) ;
 | 
						|
      #endif
 | 
						|
      cOn = (CONST4 *)l4first( &map1->ne ) ;
 | 
						|
      if ( const4lessEq( &map2->ge, cOn, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
      else
 | 
						|
      {
 | 
						|
         memset( (void *)&map2->ge, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->gt.len )
 | 
						|
   {
 | 
						|
      if ( const4lessEq( &map2->ge, &map1->gt, map1 ) )
 | 
						|
         memset( (void *)&map1->gt, 0, sizeof( CONST4 ) ) ;
 | 
						|
      else
 | 
						|
      {
 | 
						|
         memset( (void *)&map2->ge, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
   else
 | 
						|
      if ( map1->ge.len )
 | 
						|
         if ( !const4lessEq( &map2->ge, &map1->ge, map1 ) )
 | 
						|
         {
 | 
						|
            memset( (void *)&map2->ge, 0, sizeof( CONST4 ) ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
 | 
						|
   memcpy( (void *)&map1->ge, (void *)&map2->ge, sizeof( CONST4 ) ) ;
 | 
						|
   memset( (void *)&map2->ge, 0, sizeof( CONST4 ) ) ;
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
static int bitmap4combineOrLt( BITMAP4 *map1, BITMAP4 *map2 )
 | 
						|
{
 | 
						|
   CONST4 *cOn ;
 | 
						|
 | 
						|
   if ( map1->eq.len )
 | 
						|
   {
 | 
						|
      if ( const4eq( &map1->eq, &map2->lt, map1 ) )
 | 
						|
      {
 | 
						|
         #ifdef E4ANALYZE
 | 
						|
            if ( map2->le.len != 0 )
 | 
						|
               return error4( map1->log->codeBase, e4info, E93701 ) ;
 | 
						|
         #endif
 | 
						|
         memcpy( (void *)&map2->le, (void *)&map2->lt, sizeof( CONST4 ) ) ;
 | 
						|
         memset( (void *)&map2->lt, 0, sizeof( CONST4 ) ) ;
 | 
						|
         memset( (void *)&map1->eq, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
      if ( const4less( &map1->eq, &map2->lt, map1 ) )
 | 
						|
         memset( (void *)&map1->eq, 0 , sizeof( CONST4 ) ) ;
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->ne.nLink != 0 )  /* special case */
 | 
						|
   {
 | 
						|
      #ifdef E4ANALYZE
 | 
						|
         if ( map1->ne.nLink != 1 )  /* if 2 links, all must belong... */
 | 
						|
            return error4( map1->log->codeBase, e4info, E93701 ) ;
 | 
						|
      #endif
 | 
						|
      cOn = (CONST4 *)l4first( &map1->ne ) ;
 | 
						|
      if ( const4less( cOn, &map2->lt, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
      else
 | 
						|
      {
 | 
						|
         memset( (void *)&map2->lt, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->gt.len )
 | 
						|
   {
 | 
						|
      if ( const4less( &map1->gt, &map2->lt, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
      if ( const4eq( &map1->gt, &map2->lt, map1 ) )
 | 
						|
      {
 | 
						|
         const4addNe( map1, &map2->lt ) ;
 | 
						|
         memset( (void *)&map1->gt, 0, sizeof( CONST4 ) ) ;
 | 
						|
         memset( (void *)&map2->lt, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
   else
 | 
						|
      if ( map1->ge.len )
 | 
						|
         if ( const4lessEq( &map1->ge, &map2->lt, map1 ) )
 | 
						|
            return 1 ;
 | 
						|
 | 
						|
   if ( map1->lt.len )
 | 
						|
   {
 | 
						|
      if ( !const4less( &map1->lt, &map2->lt, map1 ) )
 | 
						|
      {
 | 
						|
         memset( (void *)&map2->lt, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
   else
 | 
						|
      if ( map1->le.len )
 | 
						|
      {
 | 
						|
         if ( const4lessEq( &map2->lt, &map1->le, map1 ) )
 | 
						|
         {
 | 
						|
            memset( (void *)&map2->lt, 0, sizeof( CONST4 ) ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
         else
 | 
						|
            memset( (void *)&map1->le, 0, sizeof( CONST4 ) ) ;
 | 
						|
      }
 | 
						|
 | 
						|
   memcpy( (void *)&map1->lt, (void *)&map2->lt, sizeof( CONST4 ) ) ;
 | 
						|
   memset( (void *)&map2->lt, 0, sizeof( CONST4 ) ) ;
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
static int bitmap4combineOrGt( BITMAP4 *map1, BITMAP4 *map2 )
 | 
						|
{
 | 
						|
   CONST4 *cOn ;
 | 
						|
 | 
						|
   if ( map1->eq.len )
 | 
						|
   {
 | 
						|
      if ( const4eq( &map1->eq, &map2->gt, map1 ) )
 | 
						|
      {
 | 
						|
         #ifdef E4ANALYZE
 | 
						|
            if ( map2->ge.len != 0 )
 | 
						|
               return error4( map1->log->codeBase, e4info, E93701 ) ;
 | 
						|
         #endif
 | 
						|
         memcpy( (void *)&map2->ge, (void *)&map2->gt, sizeof( CONST4 ) ) ;
 | 
						|
         memset( (void *)&map2->gt, 0, sizeof( CONST4 ) ) ;
 | 
						|
         memset( (void *)&map1->eq, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
      if ( const4less( &map2->gt, &map1->eq, map1 ) )
 | 
						|
         memset( (void *)&map1->eq, 0 , sizeof( CONST4 ) ) ;
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->ne.nLink != 0 )  /* special case */
 | 
						|
   {
 | 
						|
      #ifdef E4ANALYZE
 | 
						|
         if ( map1->ne.nLink != 1 )  /* if 2 links, all must belong... */
 | 
						|
            return error4( map1->log->codeBase, e4info, E93701 ) ;
 | 
						|
      #endif
 | 
						|
      cOn = (CONST4 *)l4first( &map1->ne ) ;
 | 
						|
      if ( const4less( &map2->gt, cOn, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
      else
 | 
						|
      {
 | 
						|
         memset( (void *)&map2->gt, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->lt.len )
 | 
						|
   {
 | 
						|
      if ( const4less( &map2->gt, &map1->lt, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
      if ( const4eq( &map2->gt, &map1->lt, map1 ) )
 | 
						|
      {
 | 
						|
         const4addNe( map1, &map2->gt ) ;
 | 
						|
         memset( (void *)&map1->lt, 0, sizeof( CONST4 ) ) ;
 | 
						|
         memset( (void *)&map2->gt, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
   else
 | 
						|
      if ( map1->le.len )
 | 
						|
         if ( const4lessEq( &map2->gt, &map1->le, map1 ) )
 | 
						|
            return 1 ;
 | 
						|
 | 
						|
   if ( map1->gt.len )
 | 
						|
   {
 | 
						|
      if ( const4less( &map1->gt, &map2->gt, map1 ) )
 | 
						|
      {
 | 
						|
         memset( (void *)&map2->gt, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
   else
 | 
						|
      if ( map1->ge.len )
 | 
						|
      {
 | 
						|
         if ( const4lessEq( &map1->ge, &map2->gt, map1 ) )
 | 
						|
         {
 | 
						|
            memset( (void *)&map2->gt, 0, sizeof( CONST4 ) ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
         else
 | 
						|
            memset( (void *)&map1->ge, 0, sizeof( CONST4 ) ) ;
 | 
						|
      }
 | 
						|
 | 
						|
   memcpy( (void *)&map1->gt, (void *)&map2->gt, sizeof( CONST4 ) ) ;
 | 
						|
   memset( (void *)&map2->gt, 0, sizeof( CONST4 ) ) ;
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
static int bitmap4combineOrEq( BITMAP4 *map1, BITMAP4 *map2 )
 | 
						|
{
 | 
						|
   CONST4 *cOn ;
 | 
						|
 | 
						|
   if ( map1->eq.len )
 | 
						|
   {
 | 
						|
      if ( const4eq( &map1->eq, &map2->eq, map1 ) )
 | 
						|
      {
 | 
						|
         memset( (void *)&map2->eq, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->ne.nLink != 0 )  /* special case */
 | 
						|
   {
 | 
						|
      #ifdef E4ANALYZE
 | 
						|
         if ( map1->ne.nLink != 1 )  /* if 2 links, all must belong... */
 | 
						|
            return error4( map1->log->codeBase, e4info, E93701 ) ;
 | 
						|
      #endif
 | 
						|
      cOn = (CONST4 *)l4first( &map1->ne ) ;
 | 
						|
      if ( const4eq( &map2->eq, cOn, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
      memset( (void *)&map2->eq, 0, sizeof( CONST4 ) ) ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->lt.len )
 | 
						|
   {
 | 
						|
      if ( const4eq( &map1->lt, &map2->eq, map1 ) )
 | 
						|
      {
 | 
						|
         memcpy( (void *)&map1->le, (void *)&map1->lt, sizeof( CONST4 ) ) ;
 | 
						|
         memset( (void *)&map1->lt, 0, sizeof( CONST4 ) ) ;
 | 
						|
         memset( (void *)&map2->eq, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
      if ( const4less( &map2->eq, &map1->lt, map1 ) )
 | 
						|
      {
 | 
						|
         memset( (void *)&map2->eq, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
   else
 | 
						|
      if ( map1->le.len )
 | 
						|
         if ( const4lessEq( &map2->eq, &map1->le, map1 ) )
 | 
						|
         {
 | 
						|
            memset( (void *)&map2->eq, 0, sizeof( CONST4 ) ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
 | 
						|
   if ( map1->gt.len )
 | 
						|
   {
 | 
						|
      if ( const4eq( &map1->gt, &map2->eq, map1 ) )
 | 
						|
      {
 | 
						|
         memcpy( (void *)&map1->ge, (void *)&map1->gt, sizeof( CONST4 ) ) ;
 | 
						|
         memset( (void *)&map1->gt, 0, sizeof( CONST4 ) ) ;
 | 
						|
         memset( (void *)&map2->eq, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
      if ( const4less( &map1->gt, &map2->eq, map1 ) )
 | 
						|
      {
 | 
						|
         memset( (void *)&map2->eq, 0, sizeof( CONST4 ) ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
   else
 | 
						|
      if ( map1->ge.len )
 | 
						|
         if ( const4lessEq( &map1->ge, &map2->eq, map1 ) )
 | 
						|
         {
 | 
						|
            memset( (void *)&map2->eq, 0, sizeof( CONST4 ) ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
 | 
						|
   if ( map1->eq.len == 0 )
 | 
						|
   {
 | 
						|
      memcpy( (void *)&map1->eq, (void *)&map2->eq, sizeof( CONST4 ) ) ;
 | 
						|
      memset( (void *)&map2->eq, 0, sizeof( CONST4 ) ) ;
 | 
						|
   }
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
static int bitmap4combineOrNe( BITMAP4 *map1, BITMAP4 *map2 )
 | 
						|
{
 | 
						|
   CONST4 *cOn, *cOn2 ;
 | 
						|
 | 
						|
   #ifdef E4ANALYZE
 | 
						|
      if ( map2->ne.nLink != 1 )  /* if 2 links, all must belong... */
 | 
						|
         return error4( map1->log->codeBase, e4info, E93701 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   cOn = (CONST4 *)l4first( &map2->ne ) ;
 | 
						|
 | 
						|
   if ( map1->eq.len )
 | 
						|
   {
 | 
						|
      if ( const4eq( &map1->eq, cOn, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
      memset( (void *)&map1->eq, 0, sizeof( CONST4 ) ) ;
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->ne.nLink != 0 )  /* special case */
 | 
						|
   {
 | 
						|
      #ifdef E4ANALYZE
 | 
						|
         if ( map1->ne.nLink != 1 )  /* if 2 links, all must belong... */
 | 
						|
            return error4( map1->log->codeBase, e4info, E93701 ) ;
 | 
						|
      #endif
 | 
						|
      cOn2 = (CONST4 *)l4first( &map1->ne ) ;
 | 
						|
      if ( const4eq( cOn2, cOn, map1 ) )
 | 
						|
      {
 | 
						|
         const4deleteNe( &map2->ne, cOn ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
      else
 | 
						|
         return 1 ;
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map1->lt.len )
 | 
						|
   {
 | 
						|
      if ( const4less( cOn, &map1->lt, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
      else
 | 
						|
         memset( (void *)&map1->lt, 0, sizeof( CONST4 ) ) ;
 | 
						|
   }
 | 
						|
   else
 | 
						|
      if ( map1->le.len )
 | 
						|
      {
 | 
						|
         if ( const4lessEq( cOn, &map1->le, map1 ) )
 | 
						|
            return 1 ;
 | 
						|
         else
 | 
						|
            memset( (void *)&map1->le, 0, sizeof( CONST4 ) ) ;
 | 
						|
      }
 | 
						|
 | 
						|
   if ( map1->gt.len )
 | 
						|
   {
 | 
						|
      if ( const4less( &map1->gt, cOn, map1 ) )
 | 
						|
         return 1 ;
 | 
						|
      else
 | 
						|
         memset( (void *)&map1->gt, 0, sizeof( CONST4 ) ) ;
 | 
						|
   }
 | 
						|
   else
 | 
						|
      if ( map1->ge.len )
 | 
						|
      {
 | 
						|
         if ( const4lessEq( &map1->ge, cOn, map1 ) )
 | 
						|
            return 1 ;
 | 
						|
         else
 | 
						|
            memset( (void *)&map1->ge, 0, sizeof( CONST4 ) ) ;
 | 
						|
      }
 | 
						|
 | 
						|
   l4remove( &map2->ne, cOn ) ;
 | 
						|
   l4add( &map1->ne, cOn ) ;
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
/* merge two leaf maps together */
 | 
						|
BITMAP4 * bitmap4combineLeafs( BITMAP4 *parent, BITMAP4 *map1, BITMAP4 *map2 )
 | 
						|
{
 | 
						|
   BITMAP4 *childOn ;
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( parent == 0 || map1 == 0 || map2 == 0 )
 | 
						|
      {
 | 
						|
         error4( 0, e4parm_null, E93701 ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
      if ( map1->type != map2->type )
 | 
						|
      {
 | 
						|
         error4( map1->log->codeBase, e4info, E83704 ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( parent->andOr == 1 )  /* and */
 | 
						|
   {
 | 
						|
      if ( map2->le.len )
 | 
						|
         if ( bitmap4combineAndLe( map1, map2 ) == 1 )
 | 
						|
            return bitmap4collapse( parent ) ;
 | 
						|
 | 
						|
      if ( map2->ge.len )
 | 
						|
         if ( bitmap4combineAndGe( map1, map2 ) == 1 )
 | 
						|
            return bitmap4collapse( parent ) ;
 | 
						|
 | 
						|
      if ( map2->lt.len )
 | 
						|
         if ( bitmap4combineAndLt( map1, map2 ) == 1 )
 | 
						|
            return bitmap4collapse( parent ) ;
 | 
						|
 | 
						|
      if ( map2->gt.len )
 | 
						|
         if ( bitmap4combineAndGt( map1, map2 ) == 1 )
 | 
						|
            return bitmap4collapse( parent ) ;
 | 
						|
 | 
						|
      if ( map2->ne.nLink != 0 )  /* special case */
 | 
						|
         if ( bitmap4combineAndNe( map1, map2 ) == 1 )
 | 
						|
            return bitmap4collapse( parent ) ;
 | 
						|
 | 
						|
      if ( map2->eq.len )
 | 
						|
         if ( bitmap4combineAndEq( map1, map2 ) == 1 )
 | 
						|
            return bitmap4collapse( parent ) ;
 | 
						|
 | 
						|
      #ifdef E4ANALYZE
 | 
						|
         if ( map2->le.len || map2->ge.len || map2->lt.len || map2->gt.len || map2->eq.len || map2->ne.nLink )
 | 
						|
         {
 | 
						|
            error4( parent->log->codeBase, e4info, E93701 ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
         if ( map1->eq.len )
 | 
						|
            if ( map1->le.len || map1->ge.len || map1->lt.len || map1->gt.len || map1->ne.nLink )
 | 
						|
            {
 | 
						|
               error4( parent->log->codeBase, e4info, E93701 ) ;
 | 
						|
               return 0 ;
 | 
						|
            }
 | 
						|
         if ( map1->ne.nLink )
 | 
						|
            if ( map1->eq.len )
 | 
						|
            {
 | 
						|
               error4( parent->log->codeBase, e4info, E93701 ) ;
 | 
						|
               return 0 ;
 | 
						|
            }
 | 
						|
         if ( map1->ge.len )
 | 
						|
            if ( map1->gt.len || map1->eq.len )
 | 
						|
            {
 | 
						|
               error4( parent->log->codeBase, e4info, E93701 ) ;
 | 
						|
               return 0 ;
 | 
						|
            }
 | 
						|
         if ( map1->gt.len )
 | 
						|
            if ( map1->ge.len || map1->eq.len )
 | 
						|
            {
 | 
						|
               error4( parent->log->codeBase, e4info, E93701 ) ;
 | 
						|
               return 0 ;
 | 
						|
            }
 | 
						|
         if ( map1->le.len )
 | 
						|
            if ( map1->lt.len || map1->eq.len )
 | 
						|
            {
 | 
						|
               error4( parent->log->codeBase, e4info, E93701 ) ;
 | 
						|
               return 0 ;
 | 
						|
            }
 | 
						|
         if ( map1->lt.len )
 | 
						|
            if ( map1->le.len || map1->eq.len )
 | 
						|
            {
 | 
						|
               error4( parent->log->codeBase, e4info, E93701 ) ;
 | 
						|
               return 0 ;
 | 
						|
            }
 | 
						|
      #endif
 | 
						|
 | 
						|
      l4remove( &parent->children, map2 ) ;
 | 
						|
      bitmap4destroy( map2 ) ;
 | 
						|
      return map1 ;
 | 
						|
   }
 | 
						|
   else if ( parent->andOr == 2 )  /* or */
 | 
						|
   {
 | 
						|
      childOn = map2 ;
 | 
						|
      while( childOn != 0 )
 | 
						|
      {
 | 
						|
         if ( map2->lt.len )
 | 
						|
            if ( bitmap4combineOrLt( map1, map2 ) == 1 )
 | 
						|
               return bitmap4collapse( parent ) ;
 | 
						|
 | 
						|
         if ( map2->gt.len )
 | 
						|
            if ( bitmap4combineOrGt( map1, map2 ) == 1 )
 | 
						|
               return bitmap4collapse( parent ) ;
 | 
						|
 | 
						|
         if ( map2->le.len )
 | 
						|
            if ( bitmap4combineOrLe( map1, map2 ) == 1 )
 | 
						|
               return bitmap4collapse( parent ) ;
 | 
						|
 | 
						|
         if ( map2->ge.len )
 | 
						|
            if ( bitmap4combineOrGe( map1, map2 ) == 1 )
 | 
						|
               return bitmap4collapse( parent ) ;
 | 
						|
 | 
						|
         if ( map2->ne.nLink != 0 )  /* special case */
 | 
						|
            if ( bitmap4combineOrNe( map1, map2 ) == 1 )
 | 
						|
               return bitmap4collapse( parent ) ;
 | 
						|
 | 
						|
         if ( map2->eq.len )
 | 
						|
            if ( bitmap4combineOrEq( map1, map2 ) == 1 )
 | 
						|
               return bitmap4collapse( parent ) ;
 | 
						|
 | 
						|
         childOn = (BITMAP4 *)l4next( &parent->children, childOn ) ;
 | 
						|
      }
 | 
						|
 | 
						|
      if ( map2->le.len || map2->ge.len || map2->lt.len || map2->gt.len || map2->eq.len || map2->ne.nLink )
 | 
						|
         return map2 ;
 | 
						|
      else
 | 
						|
      {
 | 
						|
         l4remove( &parent->children, map2 ) ;
 | 
						|
         bitmap4destroy( map2 ) ;
 | 
						|
         return map1 ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
int bitmap4copy( BITMAP4 *to, const BITMAP4 *from )
 | 
						|
{
 | 
						|
   CONST4 *cOn, *temp ;
 | 
						|
 | 
						|
   #ifdef E4ANALYZE
 | 
						|
      if ( from->branch )
 | 
						|
         return error4( to->log->codeBase, e4info, E93701 ) ;
 | 
						|
   #endif
 | 
						|
   memset( (void *)to, 0, sizeof( BITMAP4 ) ) ;
 | 
						|
   to->andOr = from->andOr ;
 | 
						|
   to->log = from->log ;
 | 
						|
   to->relate = from->relate ;
 | 
						|
   to->type = from->type ;
 | 
						|
   to->tag = from->tag ;
 | 
						|
   const4duplicate( &to->lt, &from->lt, from->log ) ;
 | 
						|
   const4duplicate( &to->le, &from->le, from->log ) ;
 | 
						|
   const4duplicate( &to->gt, &from->gt, from->log ) ;
 | 
						|
   const4duplicate( &to->ge, &from->ge, from->log ) ;
 | 
						|
   const4duplicate( &to->eq, &from->eq, from->log ) ;
 | 
						|
   cOn = (CONST4 *)l4first( &from->ne ) ;
 | 
						|
   while ( cOn != 0 )
 | 
						|
   {
 | 
						|
      temp = (CONST4 *)u4alloc( (long)sizeof( CONST4 ) ) ;
 | 
						|
      if ( temp == 0 )
 | 
						|
         break ;
 | 
						|
      const4duplicate( temp, cOn, from->log ) ;
 | 
						|
      l4add( &to->ne, temp ) ;
 | 
						|
   }
 | 
						|
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
/* flags a range of bits for the given F4FLAG and map */
 | 
						|
static long bitmap4flagRange( F4FLAG *flags, BITMAP4 *map, CONST4 *startCon, CONST4 *endCon, long doFlip, char startVal, char endVal, long check )
 | 
						|
{
 | 
						|
   long start, end, rc ;
 | 
						|
   double pos1 = 0.0 ;
 | 
						|
   double pos2 = 0.0 ;
 | 
						|
   TAG4FILE *tag ;
 | 
						|
 | 
						|
   #ifdef S4MDX
 | 
						|
      int isDesc ;
 | 
						|
      long doSkip ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   tag = map->tag ;
 | 
						|
   #ifdef S4MDX
 | 
						|
      isDesc = ( tag->header.typeCode & 8 ) ? 1 : 0 ;
 | 
						|
   #endif
 | 
						|
   start = end = 0L ;
 | 
						|
 | 
						|
   if ( startCon != 0 )
 | 
						|
   {
 | 
						|
      start = bitmap4seek( map, startCon, startVal, 0L, 0 ) ;
 | 
						|
      if ( start == -1L || tfile4eof( map->tag ) )
 | 
						|
         return -2L ;
 | 
						|
      if ( start > 0L )
 | 
						|
         pos1 = tfile4position( tag ) ;
 | 
						|
   }
 | 
						|
 | 
						|
   if ( endCon != 0 )
 | 
						|
   {
 | 
						|
      end = bitmap4seek( map, endCon, endVal, start, (int)check ) ;
 | 
						|
      if ( end == -1L )
 | 
						|
         return -2L ;
 | 
						|
      if ( end > 0L )
 | 
						|
         pos2 = tfile4position( tag ) ;
 | 
						|
   }
 | 
						|
 | 
						|
   #ifdef S4MDX
 | 
						|
      if ( isDesc )
 | 
						|
      {
 | 
						|
         if ( start > 0L )
 | 
						|
         {
 | 
						|
            if ( end > 0L )
 | 
						|
            {
 | 
						|
               if ( pos1 < pos2 )   /* wrap around case, no matches */
 | 
						|
                  return doFlip ;
 | 
						|
               if ( doFlip == 0 && ( pos1 - pos2 ) > 0.5 )   /* go around */
 | 
						|
               {
 | 
						|
                  rc = doFlip = -1L ;
 | 
						|
                  for(;;)
 | 
						|
                  {
 | 
						|
                     if ( tfile4skip( tag, -1L ) != -1L )
 | 
						|
                        break ;
 | 
						|
                     f4flagSet( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
                  }
 | 
						|
                  start = bitmap4seek( map, startCon, startVal, 0, 0 ) ;
 | 
						|
                  for(;;)
 | 
						|
                  {
 | 
						|
                     if ( tfile4skip( tag, 1L ) != 1L )
 | 
						|
                        break ;
 | 
						|
                     f4flagSet( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
                  }
 | 
						|
               }
 | 
						|
               else
 | 
						|
               {
 | 
						|
                  if ( doFlip == 0 )
 | 
						|
                     doFlip = 1 ;
 | 
						|
                  rc = doFlip ;
 | 
						|
                  for( ; rc == doFlip ; )
 | 
						|
                  {
 | 
						|
                     if ( doFlip == -1 )
 | 
						|
                        f4flagReset( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
                     else
 | 
						|
                        f4flagSet( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
                     if ( tfile4recNo( tag ) == start )
 | 
						|
                        break ;
 | 
						|
                     rc = tfile4skip( tag, 1L ) == 1L ? doFlip : -doFlip ;
 | 
						|
                  }
 | 
						|
               }
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
               if ( doFlip == 0 )
 | 
						|
               {
 | 
						|
                  if ( pos1 > 0.5 )
 | 
						|
                  {
 | 
						|
                     doSkip = 1L ;
 | 
						|
                     doFlip = -1L ;
 | 
						|
                     rc = tfile4skip( tag, 1L ) ;
 | 
						|
                  }
 | 
						|
                  else
 | 
						|
                  {
 | 
						|
                     rc = doSkip = -1L ;
 | 
						|
                     doFlip = 1L ;
 | 
						|
                  }
 | 
						|
               }
 | 
						|
               else
 | 
						|
                  rc = doSkip = -doFlip ;
 | 
						|
 | 
						|
              for( ; rc == doSkip ; )
 | 
						|
               {
 | 
						|
                  f4flagSet( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
                  rc = tfile4skip( tag, doSkip ) ;
 | 
						|
               }
 | 
						|
            }
 | 
						|
         }
 | 
						|
         else
 | 
						|
         {
 | 
						|
            if ( end > 0L )
 | 
						|
            {
 | 
						|
               if ( doFlip == 0 )
 | 
						|
               {
 | 
						|
                  if ( pos2 > .5 )
 | 
						|
                  {
 | 
						|
                     rc = doSkip = 1L ;
 | 
						|
                     doFlip = 1L ;
 | 
						|
                  }
 | 
						|
                  else
 | 
						|
                  {
 | 
						|
                     doFlip = -1L ;
 | 
						|
                     doSkip = -1L ;
 | 
						|
                     rc = tfile4skip( tag, doSkip ) ;
 | 
						|
                  }
 | 
						|
               }
 | 
						|
               else
 | 
						|
                  rc = doSkip = -doFlip ;
 | 
						|
 | 
						|
               for( ; rc == doSkip ; )
 | 
						|
               {
 | 
						|
                f4flagSet( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
                  rc = tfile4skip( tag, doSkip ) ;
 | 
						|
               }
 | 
						|
           }
 | 
						|
            else
 | 
						|
               return -1L ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
   #endif
 | 
						|
   if ( start > 0L )
 | 
						|
   {
 | 
						|
      if ( end > 0L )
 | 
						|
      {
 | 
						|
         if ( pos1 > pos2 )   /* wrap around case, no matches */
 | 
						|
            return doFlip ;
 | 
						|
         if ( doFlip == 0 && ( pos2 - pos1 ) > 0.5 )   /* go around */
 | 
						|
         {
 | 
						|
            rc = doFlip = -1L ;
 | 
						|
            for(;;)
 | 
						|
            {
 | 
						|
               if ( tfile4skip( tag, 1L ) != 1L )
 | 
						|
                  break ;
 | 
						|
               f4flagSet( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
            }
 | 
						|
            bitmap4seek( map, startCon, startVal, 0L, 0 ) ;
 | 
						|
            for(;;)
 | 
						|
            {
 | 
						|
               if ( tfile4skip( tag, -1L ) != -1L )
 | 
						|
                  break ;
 | 
						|
               f4flagSet( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
            }
 | 
						|
         }
 | 
						|
         else
 | 
						|
         {
 | 
						|
            if ( doFlip == 0 )
 | 
						|
               doFlip = 1 ;
 | 
						|
            rc = doFlip ;
 | 
						|
            for( ; rc == doFlip ; )
 | 
						|
            {
 | 
						|
               if ( doFlip == -1 )
 | 
						|
                  f4flagReset( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
               else
 | 
						|
                  f4flagSet( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
               if ( tfile4recNo( tag ) == start )
 | 
						|
                  break ;
 | 
						|
               rc = tfile4skip( tag, -1L ) == -1L ? doFlip : -doFlip ;
 | 
						|
            }
 | 
						|
         }
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
         if ( doFlip == 0 )
 | 
						|
         {
 | 
						|
            if ( pos1 < 0.5 )
 | 
						|
            {
 | 
						|
               doFlip = -1L ;
 | 
						|
               rc = tfile4skip( tag, doFlip ) ;
 | 
						|
            }
 | 
						|
            else
 | 
						|
               rc = doFlip = 1L ;
 | 
						|
         }
 | 
						|
         else
 | 
						|
            rc = doFlip ;
 | 
						|
         for( ; rc == doFlip ; )
 | 
						|
         {
 | 
						|
            f4flagSet( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
            rc = tfile4skip( tag, doFlip ) ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
   }
 | 
						|
   else
 | 
						|
   {
 | 
						|
      if ( end > 0L )
 | 
						|
      {
 | 
						|
         if ( doFlip == 0 )
 | 
						|
         {
 | 
						|
            if ( pos2 < .5 )
 | 
						|
               rc = doFlip = -1L ;
 | 
						|
            else
 | 
						|
            {
 | 
						|
               doFlip = 1L ;
 | 
						|
               rc = tfile4skip( tag, doFlip ) ;
 | 
						|
            }
 | 
						|
         }
 | 
						|
         else
 | 
						|
            rc = doFlip ;
 | 
						|
         for( ; rc == doFlip ; )
 | 
						|
         {
 | 
						|
            f4flagSet( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
            rc = tfile4skip( tag, doFlip ) ;
 | 
						|
         }
 | 
						|
         doFlip = ( doFlip == -1L ) ? 1L : -1L ;
 | 
						|
      }
 | 
						|
      else
 | 
						|
         return -1L ;
 | 
						|
   }
 | 
						|
   #ifdef S4MDX
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   return doFlip ;
 | 
						|
}
 | 
						|
 | 
						|
static long bmf4AndEq( BITMAP4 *map, F4FLAG *flags, long doFlip )
 | 
						|
{
 | 
						|
   CONST4 *startCon, *endCon ;
 | 
						|
   char startVal, endVal ;
 | 
						|
 | 
						|
   #ifdef E4ANALYZE
 | 
						|
      if ( map->gt.len || map->ge.len || map->le.len || map->lt.len || l4first( &map->ne ) != 0 )
 | 
						|
         return error4( map->log->codeBase, e4info, E83705 ) ;
 | 
						|
   #endif
 | 
						|
   startCon = endCon = &map->eq ;
 | 
						|
   startVal = 1 ;
 | 
						|
   endVal = 2 ;
 | 
						|
   return bitmap4flagRange( flags, map, startCon, endCon, doFlip, startVal, endVal, 0L ) ;
 | 
						|
}
 | 
						|
 | 
						|
static long bmf4AndOt( BITMAP4 *map, F4FLAG *flags, long doFlip )
 | 
						|
{
 | 
						|
   CONST4 *startCon, *endCon, *cOn ;
 | 
						|
   char startVal, endVal ;
 | 
						|
   long prevFlip ;
 | 
						|
 | 
						|
   startVal = endVal = 0 ;
 | 
						|
   startCon = endCon = 0 ;
 | 
						|
 | 
						|
 | 
						|
   if ( map->gt.len )
 | 
						|
   {
 | 
						|
      startCon = &map->gt ;
 | 
						|
      startVal = 3 ;
 | 
						|
   }
 | 
						|
   else
 | 
						|
      if ( map->ge.len )
 | 
						|
      {
 | 
						|
         startCon = &map->ge ;
 | 
						|
         startVal = 1 ;
 | 
						|
      }
 | 
						|
 | 
						|
   if ( map->lt.len )
 | 
						|
   {
 | 
						|
      endCon = &map->lt ;
 | 
						|
      endVal = 0 ;
 | 
						|
   }
 | 
						|
   else
 | 
						|
      if ( map->le.len )
 | 
						|
      {
 | 
						|
         endCon = &map->le ;
 | 
						|
         endVal = 2 ;
 | 
						|
      }
 | 
						|
 | 
						|
   doFlip = bitmap4flagRange( flags, map, startCon, endCon, doFlip, startVal, endVal, 1L ) ;
 | 
						|
   if ( doFlip == -2L )  /* no matches */
 | 
						|
   {
 | 
						|
      f4flagSetAll( flags ) ;
 | 
						|
      flags->isFlip = 1 ;
 | 
						|
      return -999L ;
 | 
						|
   }
 | 
						|
 | 
						|
   cOn = (CONST4 *)l4first( &map->ne ) ;
 | 
						|
   if( cOn != 0 )
 | 
						|
   {
 | 
						|
      if ( doFlip != 0L )
 | 
						|
         prevFlip = doFlip = ( doFlip == 1L ) ? -1L : 1L ;
 | 
						|
      else
 | 
						|
         prevFlip = 0L ;
 | 
						|
      while ( cOn != 0 )
 | 
						|
      {
 | 
						|
         startCon = endCon = cOn ;
 | 
						|
         startVal = 1 ;
 | 
						|
         endVal = 2 ;
 | 
						|
         doFlip = bitmap4flagRange( flags, map, startCon, endCon, doFlip, startVal, endVal, 0L ) ;
 | 
						|
         if ( doFlip == -2L )
 | 
						|
         {
 | 
						|
            if ( prevFlip == 0L )  /* all records not equal, so mark as such */
 | 
						|
            {
 | 
						|
               f4flagSetAll( flags ) ;
 | 
						|
               doFlip = -1L ;
 | 
						|
            }
 | 
						|
            else   /* otherwise no change since no un-equal records */
 | 
						|
               doFlip = prevFlip ;
 | 
						|
         }
 | 
						|
         cOn = (CONST4 *)l4next( &map->ne, cOn ) ;
 | 
						|
         prevFlip = doFlip ;
 | 
						|
      }
 | 
						|
      doFlip = ( doFlip == 1L ) ? -1L : 1L ;
 | 
						|
   }
 | 
						|
 | 
						|
   return doFlip ;
 | 
						|
}
 | 
						|
 | 
						|
static int bmf4OrNe( BITMAP4 *map, F4FLAG *flags, long doFlip )
 | 
						|
{
 | 
						|
   CONST4 *startCon, *endCon, *cOn ;
 | 
						|
   char startVal, endVal ;
 | 
						|
 | 
						|
   cOn = (CONST4 *)l4first( &map->ne ) ;
 | 
						|
   startCon = endCon = cOn ;
 | 
						|
   startVal = 1 ;
 | 
						|
   endVal = 2 ;
 | 
						|
   doFlip = bitmap4flagRange( flags, map, startCon, endCon, doFlip, startVal, endVal, 0L ) ;
 | 
						|
   if ( doFlip != -1 )
 | 
						|
      f4flagFlipReturns( flags ) ;
 | 
						|
   #ifdef E4ANALYZE
 | 
						|
      cOn = (CONST4 *)l4next( &map->ne, cOn ) ;
 | 
						|
      if ( cOn != 0 )
 | 
						|
      {
 | 
						|
         error4( map->log->codeBase, e4info, E83705 ) ;
 | 
						|
         return -1000 ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
   return -999 ;
 | 
						|
}
 | 
						|
 | 
						|
static long bmf4OrOt( BITMAP4 *map, F4FLAG *flags, CODE4 *codeBase )
 | 
						|
{
 | 
						|
   CONST4 *startCon, *endCon ;
 | 
						|
   char startVal, endVal ;
 | 
						|
   long doFlip, rc, prevFlip, doSkip, start, end ;
 | 
						|
   double pos1 = 0 ;
 | 
						|
   double pos2 ;
 | 
						|
   TAG4FILE *tag ;
 | 
						|
   #ifdef S4MDX
 | 
						|
      int isDesc ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   tag = map->tag ;
 | 
						|
   #ifdef S4MDX
 | 
						|
      isDesc = ( tag->header.typeCode & 8 ) ? 1 : 0 ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( tag == 0 )
 | 
						|
      {
 | 
						|
         error4( codeBase, e4parm, E93719 ) ;
 | 
						|
         return -1000 ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   start = end = doFlip = doSkip = 0L ;
 | 
						|
   if ( map->gt.len )
 | 
						|
      start = bitmap4seek( map, &map->gt, 3, 0L, 0 ) ;
 | 
						|
   else
 | 
						|
      if ( map->ge.len )
 | 
						|
         start = bitmap4seek( map, &map->ge, 1, 0L, 0 ) ;
 | 
						|
 | 
						|
   #ifdef S4MDX
 | 
						|
      if ( start > 0L )
 | 
						|
         pos1 = (double)tfile4position( tag ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( map->lt.len )
 | 
						|
      end = bitmap4seek( map, &map->lt, 0, start, 1 ) ;
 | 
						|
   else
 | 
						|
      if ( map->le.len )
 | 
						|
        end = bitmap4seek( map, &map->le, 2, start, 1 ) ;
 | 
						|
 | 
						|
   if ( end == -1L )  /* no matches */
 | 
						|
      return -999L ;
 | 
						|
 | 
						|
   #ifdef S4MDX
 | 
						|
      if ( isDesc )
 | 
						|
      {
 | 
						|
         if ( start > 0L )
 | 
						|
         {
 | 
						|
            if ( end > 0L )
 | 
						|
            {
 | 
						|
               pos2 = (double)tfile4position( tag ) ;
 | 
						|
               if ( ( pos1 - pos2 ) < 0.5 )   /* do between */
 | 
						|
               {
 | 
						|
                  if ( ( pos1 - pos2 ) < 0 )
 | 
						|
                  {
 | 
						|
                     doFlip = -1 ;
 | 
						|
                     doSkip = -1 ;
 | 
						|
                  }
 | 
						|
                  else
 | 
						|
                     doSkip = doFlip = 1L ;
 | 
						|
                  if ( tfile4recNo( tag ) != start )
 | 
						|
                  {
 | 
						|
                     rc = tfile4skip( tag, doSkip ) ;
 | 
						|
                     for( ; rc == doSkip ; )
 | 
						|
                     {
 | 
						|
                        if ( error4code( codeBase ) < 0 )
 | 
						|
                           return -1000L ;
 | 
						|
                        if ( tfile4recNo( tag ) == start )
 | 
						|
                           break ;
 | 
						|
                        f4flagSet( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
                        rc = tfile4skip( tag, doSkip ) ;
 | 
						|
                     }
 | 
						|
                  }
 | 
						|
               }
 | 
						|
               else  /* flip and do both ways */
 | 
						|
               {
 | 
						|
                  for(;;)
 | 
						|
                  {
 | 
						|
                     f4flagSet( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
                     if ( error4code( codeBase ) < 0 )
 | 
						|
                        return -1000L ;
 | 
						|
                     if ( tfile4skip( tag, -1L ) != -1L )
 | 
						|
                        break ;
 | 
						|
                  }
 | 
						|
                  if ( map->gt.len )
 | 
						|
                     start = bitmap4seek( map, &map->gt, 1, 0, 0 ) ;
 | 
						|
                  else
 | 
						|
                     if ( map->ge.len )
 | 
						|
                        start = bitmap4seek( map, &map->ge, 2, 0, 0 ) ;
 | 
						|
                  for(;;)
 | 
						|
                  {
 | 
						|
                     f4flagSet( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
                     if ( error4code( codeBase ) < 0 )
 | 
						|
                        return -1000L ;
 | 
						|
                     if ( tfile4skip( tag, 1L ) != 1L )
 | 
						|
                        break ;
 | 
						|
                  }
 | 
						|
                  doSkip = doFlip = -1L ;
 | 
						|
               }
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
               if ( pos1 > 0.5 )
 | 
						|
               {
 | 
						|
                  doFlip = -1 ;
 | 
						|
                  doSkip = 1 ;
 | 
						|
                  rc = tfile4skip( tag, doSkip ) ;
 | 
						|
               }
 | 
						|
               else
 | 
						|
               {
 | 
						|
                  doFlip = 1 ;
 | 
						|
                  doSkip = rc = -1 ;
 | 
						|
               }
 | 
						|
 | 
						|
               for( ; rc == doSkip ; )
 | 
						|
               {
 | 
						|
                  if ( error4code( codeBase ) < 0 )
 | 
						|
                     return -1000 ;
 | 
						|
                  f4flagSet( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
                  rc = tfile4skip( tag, doSkip ) ;
 | 
						|
               }
 | 
						|
            }
 | 
						|
         }
 | 
						|
         else
 | 
						|
         {
 | 
						|
            if ( end > 0L )
 | 
						|
            {
 | 
						|
               if ( (double)tfile4position( tag ) > 0.5 )
 | 
						|
               {
 | 
						|
                  doFlip = 1 ;
 | 
						|
                  doSkip = 1 ;
 | 
						|
                  rc = 1 ;
 | 
						|
               }
 | 
						|
               else
 | 
						|
               {
 | 
						|
                  doFlip = -1 ;
 | 
						|
                  doSkip = -1 ;
 | 
						|
                  rc = tfile4skip( tag, doSkip ) ;
 | 
						|
               }
 | 
						|
 | 
						|
               for( ; rc == doSkip ; )
 | 
						|
               {
 | 
						|
                  if ( error4code( codeBase ) < 0 )
 | 
						|
                     return -1000 ;
 | 
						|
                  f4flagSet( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
                  rc = tfile4skip( tag, doSkip ) ;
 | 
						|
               }
 | 
						|
            }
 | 
						|
         }
 | 
						|
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( start > 0L )
 | 
						|
   {
 | 
						|
      pos1 = (double)tfile4position( tag ) ;
 | 
						|
      if ( end > 0L )
 | 
						|
      {
 | 
						|
         pos2 = (double)tfile4position( tag ) ;
 | 
						|
         if ( ( pos2 - pos1 ) < 0.5 )   /* flip and do between */
 | 
						|
         {
 | 
						|
            doSkip = doFlip = 1L ;
 | 
						|
            if ( tfile4recNo( tag ) != start )
 | 
						|
            {
 | 
						|
               rc = tfile4skip( tag, doSkip ) ;
 | 
						|
               for( ; rc == doSkip ; )
 | 
						|
               {
 | 
						|
                  if ( error4code( codeBase ) < 0 )
 | 
						|
                     return -1000L ;
 | 
						|
                  if ( tfile4recNo( tag ) == start )
 | 
						|
                     break ;
 | 
						|
                  f4flagSet( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
                  rc = tfile4skip( tag, doSkip ) ;
 | 
						|
               }
 | 
						|
            }
 | 
						|
            doFlip = doSkip = -1L ;
 | 
						|
         }
 | 
						|
         else  /* do both ways */
 | 
						|
         {
 | 
						|
            for(;;)
 | 
						|
            {
 | 
						|
               f4flagSet( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
               if ( error4code( codeBase ) < 0 )
 | 
						|
                  return -1000L ;
 | 
						|
               if ( tfile4skip( tag, -1L ) != -1L )
 | 
						|
                  break ;
 | 
						|
            }
 | 
						|
            if ( map->gt.len )
 | 
						|
               bitmap4seek( map, &map->gt, 1, 0L, 0 ) ;
 | 
						|
            else
 | 
						|
               if ( map->ge.len )
 | 
						|
                  bitmap4seek( map, &map->ge, 2, 0L, 0 ) ;
 | 
						|
            for(;;)
 | 
						|
            {
 | 
						|
               f4flagSet( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
               if ( error4code( codeBase ) < 0 )
 | 
						|
                  return -1000L ;
 | 
						|
               if ( tfile4skip( tag, 1L ) != 1L )
 | 
						|
                  break ;
 | 
						|
            }
 | 
						|
         }
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
         if ( pos1 < 0.5 )
 | 
						|
         {
 | 
						|
            doFlip = doSkip = -1 ;
 | 
						|
            rc = tfile4skip( tag, doSkip ) ;
 | 
						|
         }
 | 
						|
         else
 | 
						|
            doFlip = doSkip = rc = 1 ;
 | 
						|
 | 
						|
         for( ; rc == doSkip ; )
 | 
						|
         {
 | 
						|
            if ( error4code( codeBase ) < 0 )
 | 
						|
               return -1000 ;
 | 
						|
            f4flagSet( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
            rc = tfile4skip( tag, doSkip ) ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
   }
 | 
						|
   else
 | 
						|
   {
 | 
						|
      if ( end > 0L )
 | 
						|
      {
 | 
						|
         if ( (double)tfile4position( tag ) > 0.5 )
 | 
						|
         {
 | 
						|
            doSkip = 1 ;
 | 
						|
            doFlip = 1 ;
 | 
						|
            rc = tfile4skip( tag, doSkip ) ;
 | 
						|
         }
 | 
						|
         else
 | 
						|
         {
 | 
						|
           doFlip = -1 ;
 | 
						|
           rc = doSkip = -1 ;
 | 
						|
         }
 | 
						|
 | 
						|
         for( ; rc == doSkip ; )
 | 
						|
         {
 | 
						|
            if ( error4code( codeBase ) < 0 )
 | 
						|
               return -1000 ;
 | 
						|
            f4flagSet( flags, (unsigned long)tfile4recNo( tag ) ) ;
 | 
						|
            rc = tfile4skip( tag, doSkip ) ;
 | 
						|
         }
 | 
						|
         doFlip = doSkip = ( doFlip == -1L ) ? 1L : -1L ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   #ifdef S4MDX
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( map->eq.len )
 | 
						|
   {
 | 
						|
      startCon = endCon = &map->eq ;
 | 
						|
      startVal = 1 ;
 | 
						|
      endVal = 2 ;
 | 
						|
      prevFlip = doFlip ;
 | 
						|
      doFlip = bitmap4flagRange( flags, map, startCon, endCon, doFlip, startVal, endVal, 0L ) ;
 | 
						|
      if ( doFlip == -2L )
 | 
						|
         doFlip = prevFlip ;
 | 
						|
   }
 | 
						|
 | 
						|
   return doFlip ;
 | 
						|
}
 | 
						|
 | 
						|
/* generate the flags for the bitmap tree */
 | 
						|
static int bitmap4flagGenerate( BITMAP4 *map, int mode, F4FLAG *flags )
 | 
						|
{
 | 
						|
   CODE4 *codeBase ;
 | 
						|
   CONST4 *cOn ;
 | 
						|
   long doFlip ;
 | 
						|
   unsigned long allocSize ;
 | 
						|
   int isFlipped ;
 | 
						|
   #ifdef S4HAS_DESCENDING
 | 
						|
      TAG4FILE *tag ;
 | 
						|
      int oldDesc ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   codeBase = map->log->codeBase ;
 | 
						|
 | 
						|
   #ifdef S4HAS_DESCENDING
 | 
						|
      tag = map->tag ;
 | 
						|
 | 
						|
      #ifdef E4PARM_LOW
 | 
						|
         if ( tag == 0 )
 | 
						|
            return error4( codeBase, e4parm, E93701 ) ;
 | 
						|
      #endif
 | 
						|
 | 
						|
      oldDesc = tag->header.descending ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( flags->flags == 0 )
 | 
						|
   {
 | 
						|
      allocSize = (unsigned long)d4recCount( map->relate->data ) + 1L ;
 | 
						|
      if ( f4flagInit( flags, codeBase, allocSize ) < 0 )
 | 
						|
      {
 | 
						|
         #ifndef S4OPTIMIZE_OFF
 | 
						|
            #ifdef S4LOW_MEMORY
 | 
						|
               /* note that memory failure could also occur if the value was very large */
 | 
						|
               if ( codeBase->hasOpt && codeBase->opt.numBuffers != 0 && codeBase->opt.bufferSize > allocSize )
 | 
						|
               {
 | 
						|
                  error4set( codeBase, 0 ) ;
 | 
						|
                  code4optSuspend( codeBase ) ;
 | 
						|
                  codeBase->hadOpt = 0 ;   /* mark to automatically restart optimization later */
 | 
						|
                  if ( codeBase->opt.numBuffers > 8 )
 | 
						|
                     codeBase->opt.numBuffers-- ;
 | 
						|
                  f4flagInit( flags, codeBase, allocSize ) ;
 | 
						|
               }
 | 
						|
            #endif
 | 
						|
         #endif
 | 
						|
      }
 | 
						|
 | 
						|
      if ( error4code( codeBase ) != 0 )
 | 
						|
      {
 | 
						|
         #ifdef S4HAS_DESCENDING
 | 
						|
            tfile4descending( tag, (const unsigned short)oldDesc ) ;
 | 
						|
         #endif
 | 
						|
         return -1 ;
 | 
						|
      }
 | 
						|
 | 
						|
      isFlipped = 0 ;
 | 
						|
      doFlip = 0L ;
 | 
						|
   }
 | 
						|
   else
 | 
						|
   {
 | 
						|
      doFlip = ( flags->isFlip == 1L ) ? -1L : 1L ;
 | 
						|
      isFlipped = 1 ;
 | 
						|
   }
 | 
						|
 | 
						|
   if ( map->noMatch == 1 )
 | 
						|
   {
 | 
						|
      if ( mode == 2 )
 | 
						|
      {
 | 
						|
         if ( isFlipped ) /* previous setting, so make all succeed */
 | 
						|
         {
 | 
						|
            f4flagSetAll( flags ) ;
 | 
						|
            flags->isFlip = 0 ;
 | 
						|
         }
 | 
						|
         else   /* none set now, so make all succeed by simple flip */
 | 
						|
            flags->isFlip = 1 ;
 | 
						|
      }
 | 
						|
      #ifdef S4HAS_DESCENDING
 | 
						|
         tfile4descending( tag, (const unsigned short)oldDesc ) ;
 | 
						|
      #endif
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   if ( mode == 1 )  /* and */
 | 
						|
   {
 | 
						|
      if ( map->eq.len )
 | 
						|
         doFlip = bmf4AndEq( map, flags, doFlip ) ;
 | 
						|
      else
 | 
						|
         doFlip = bmf4AndOt( map, flags, doFlip ) ;
 | 
						|
   }
 | 
						|
   else  /* or */
 | 
						|
   {
 | 
						|
      cOn = (CONST4 *)l4first( &map->ne ) ;
 | 
						|
      if ( cOn != 0 )
 | 
						|
         doFlip = bmf4OrNe( map, flags, doFlip ) ;
 | 
						|
      else
 | 
						|
         doFlip = bmf4OrOt( map, flags, codeBase ) ;
 | 
						|
   }
 | 
						|
 | 
						|
   #ifdef S4HAS_DESCENDING
 | 
						|
      tfile4descending( tag, (const unsigned short)oldDesc ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( doFlip == -999L )
 | 
						|
      return 0 ;
 | 
						|
 | 
						|
   if ( doFlip == -1000L )
 | 
						|
      return -1 ;
 | 
						|
 | 
						|
   if ( doFlip == -1L && !isFlipped )
 | 
						|
      f4flagFlipReturns( flags ) ;
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
/* generate the bitmaps */
 | 
						|
static F4FLAG *bitmap4generate( BITMAP4 *map )
 | 
						|
{
 | 
						|
   BITMAP4 *mapOn ;
 | 
						|
   F4FLAG *flag1, *flag2 ;
 | 
						|
 | 
						|
   if ( map->branch == 0 )
 | 
						|
   {
 | 
						|
      flag1 = (F4FLAG *)u4alloc( (long)sizeof( F4FLAG ) ) ;
 | 
						|
      if ( flag1 == 0 )  /* insufficient memory */
 | 
						|
         return 0 ;
 | 
						|
      memset( (void *)flag1, 0, sizeof( F4FLAG ) ) ;
 | 
						|
      if ( bitmap4flagGenerate( map, map->andOr, flag1 ) < 0 )
 | 
						|
      {
 | 
						|
         u4free( flag1->flags ) ;
 | 
						|
         u4free( flag1 ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
      return flag1 ;
 | 
						|
   }
 | 
						|
 | 
						|
   flag1 = flag2 = 0 ;
 | 
						|
 | 
						|
   mapOn = (BITMAP4 *)l4first( &map->children ) ;
 | 
						|
   while( mapOn != 0 )
 | 
						|
   {
 | 
						|
      flag2 = bitmap4generate( mapOn ) ;
 | 
						|
      if ( flag1 == 0 )
 | 
						|
         flag1 = flag2 ;
 | 
						|
      else
 | 
						|
      {
 | 
						|
         #ifdef E4ANALYZE
 | 
						|
            if ( map->andOr != 1 && map->andOr != 2 )
 | 
						|
            {
 | 
						|
               error4( map->log->codeBase, e4info, E83705 ) ;
 | 
						|
               return 0 ;
 | 
						|
            }
 | 
						|
         #endif
 | 
						|
         if ( map->andOr == 1 )
 | 
						|
            f4flagAnd( flag1, flag2 ) ;
 | 
						|
         else
 | 
						|
            f4flagOr( flag1, flag2 ) ;
 | 
						|
         u4free( flag2->flags ) ;
 | 
						|
         u4free( flag2 ) ;
 | 
						|
      }
 | 
						|
      mapOn = (BITMAP4 *)l4next( &map->children, mapOn ) ;
 | 
						|
   }
 | 
						|
 | 
						|
   return flag1 ;
 | 
						|
}
 | 
						|
 | 
						|
/* evaluate bitmaps out of the log */
 | 
						|
int bitmap4evaluate( L4LOGICAL *log, const int pos )
 | 
						|
{
 | 
						|
   BITMAP4 *map ;
 | 
						|
   F4FLAG *flags ;
 | 
						|
 | 
						|
   if ( error4code( log->codeBase ) < 0 )
 | 
						|
      return error4code( log->codeBase ) ;
 | 
						|
 | 
						|
   map = bitmap4init( log, pos ) ;
 | 
						|
   if ( map == 0 )
 | 
						|
      return 0 ;
 | 
						|
 | 
						|
   map = bitmap4redistribute( 0, map, 1 ) ;
 | 
						|
   if ( error4code( log->codeBase ) < 0 )
 | 
						|
      return error4code( log->codeBase ) ;
 | 
						|
   if ( map == 0 )
 | 
						|
      return 0 ;
 | 
						|
 | 
						|
   map = bitmap4redistributeBranch( 0, map ) ;
 | 
						|
   if ( map == 0 )
 | 
						|
   {
 | 
						|
      if ( error4code( log->codeBase ) == e4memory )
 | 
						|
         error4set( log->codeBase, 0 ) ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   flags = bitmap4generate( map ) ;
 | 
						|
   if ( flags != 0 )
 | 
						|
   {
 | 
						|
      memcpy( (void *)&map->relate->set, (void *)flags, sizeof( F4FLAG ) ) ;
 | 
						|
      u4free( flags ) ;
 | 
						|
   }
 | 
						|
   bitmap4free( log, map ) ;
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
#endif   /* S4INDEX_OFF */
 | 
						|
/* returns true/false as to whether or not relate could be bitmap optimized */
 | 
						|
#ifdef P4ARGS_USED
 | 
						|
   #pragma argsused
 | 
						|
#endif
 | 
						|
int S4FUNCTION relate4optimizeable( RELATE4 *relate )
 | 
						|
{
 | 
						|
   #ifdef S4INDEX_OFF
 | 
						|
      return 0 ;
 | 
						|
   #else
 | 
						|
      L4LOGICAL *log ;
 | 
						|
      BITMAP4 *map ;
 | 
						|
      RELATION4 *relation ;
 | 
						|
 | 
						|
      relation = relate->relation ;
 | 
						|
 | 
						|
      if ( relation->exprSource )
 | 
						|
      {
 | 
						|
         relation->log.expr = expr4parseLow( relate->data, relation->exprSource, 0 ) ;
 | 
						|
         if ( relation->log.expr == 0 )
 | 
						|
            return -1 ;
 | 
						|
 | 
						|
         log = &relation->log ;
 | 
						|
 | 
						|
         if ( error4code( log->codeBase ) < 0 )
 | 
						|
            return -1 ;
 | 
						|
 | 
						|
         log4buildDatabaseLists( log ) ;
 | 
						|
         map = bitmap4init( log, log->expr->infoN - 1 ) ;
 | 
						|
         if ( map == 0 )
 | 
						|
            return 0 ;
 | 
						|
         bitmap4free( log, map ) ;
 | 
						|
 | 
						|
         return 1 ;
 | 
						|
      }
 | 
						|
 | 
						|
      return 0 ;
 | 
						|
   #endif
 | 
						|
}
 | 
						|
#else
 | 
						|
int S4FUNCTION relate4optimizeable( RELATE4 *relate )
 | 
						|
{
 | 
						|
   CONNECTION4 *connection ;
 | 
						|
   CONNECTION4RELATE_OPT_INFO_IN info ;
 | 
						|
   int rc ;
 | 
						|
   CODE4 *c4 ;
 | 
						|
 | 
						|
   #ifdef E4PARM_HIGH
 | 
						|
      if ( relate == 0 )
 | 
						|
         return error4( 0, e4parm_null, E94426 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   c4 = relate->codeBase ;
 | 
						|
 | 
						|
   #ifdef E4ANALYZE
 | 
						|
      if ( relate->data == 0 )
 | 
						|
         return error4( c4, e4struct, E94426 ) ;
 | 
						|
      if ( relate->data->dataFile == 0 )
 | 
						|
         return error4( c4, e4struct, E94426 ) ;
 | 
						|
   #endif
 | 
						|
   connection = relate->data->dataFile->connection ;
 | 
						|
   #ifdef E4ANALYZE
 | 
						|
      if ( connection == 0 )
 | 
						|
         return error4( c4, e4struct, E94426 ) ;
 | 
						|
   #endif
 | 
						|
   connection4assign( connection, CON4RELATE_OPT, 0, 0 ) ;
 | 
						|
   connection4addData( connection, &info, sizeof( CONNECTION4RELATE_OPT_INFO_IN ), 0 ) ;
 | 
						|
   connection4send( connection ) ;
 | 
						|
   rc = connection4receive( connection ) ;
 | 
						|
   if ( rc < 0 )
 | 
						|
      return error4stack( c4, rc, E94426 ) ;
 | 
						|
   rc = connection4status( connection ) ;
 | 
						|
   if ( rc < 0 )
 | 
						|
      return connection4error( connection, c4, rc, E94426 ) ;
 | 
						|
 | 
						|
   rc = relate4unpack( relate->relation, relate->data->dataFile->connection ) ;
 | 
						|
   if ( rc < 0 )
 | 
						|
      return error4stack( c4, rc, E94426 ) ;
 | 
						|
   return connection4status( connection ) ;
 | 
						|
}
 | 
						|
#endif   /* S4CLIENT */
 |