home *** CD-ROM | disk | FTP | other *** search
-
- /* i4skip.c & i4keycmp (c)Copyright Sequiter Software Inc., 1987
-
- Moves the index file pointer a specified number of keys.
- */
-
- #include "d4all.h"
- #include "u4error.h"
- #include "p4misc.h"
-
- #include <string.h>
-
- extern INDEX *v4index ;
- extern BLOCK *v4block ;
- extern int v4lock_wait ;
-
- i4keycmp( int index_ref, char *one, char *two )
- {
- #ifdef CLIPPER
- #ifdef LANGUAGE
- return( u4memcmp( (unsigned char *) one,
- (unsigned char *) two, (size_t) v4index[index_ref].key_len)) ;
- #else
- return( memcmp(one, two, (size_t) v4index[index_ref].key_len ) ) ;
- #endif
- #else
- INDEX *index_ptr ;
- double dif ;
-
- #ifdef PORTABLE
- double d1,d2 ;
- #endif
-
- index_ptr = v4index+index_ref ;
-
- if ( index_ptr->int_or_date )
- {
- #ifdef PORTABLE
- memcpy( &d1, (double *) one, sizeof(double) ) ;
- memcpy( &d2, (double *) two, sizeof(double) ) ;
- dif = d1 - d2 ;
- #else
- dif = *((double *)one) - *((double *)two) ;
- #endif
- if ( dif > 1.0e-13 ) return 1 ;
- if ( dif < -1.0e-13) return -1 ;
- return 0 ;
- }
- else
- #ifdef LANGUAGE
- return( u4memcmp( (unsigned char *) one, (unsigned char *) two,
- (size_t) index_ptr->key_len ) ) ;
- #else
- return( memcmp(one, two, (size_t) index_ptr->key_len ) ) ;
- #endif
- #endif
- }
-
-
- long i4skip( int index_ref, long num_skip )
- {
- INDEX *index_ptr ;
- BLOCK *block_ptr ;
- int sign, rc ;
- long num_left ;
-
- index_ptr = v4index + index_ref ;
- if ( (rc = i4lock( index_ref, v4lock_wait)) < 0 ) return -num_skip ;
-
- num_left = num_skip ;
- if ( num_skip < 0)
- sign = -1 ;
- else
- sign = 1 ;
-
- rc = 0 ;
-
- if ( index_ptr->block_ref < 0)
- rc = i4top( index_ref ) ;
- else
- {
- block_ptr = v4block+ index_ptr->block_ref ;
- if ( block_ptr->key_on >= block_ptr->num_keys )
- rc = i4bottom( index_ref ) ; /* EOF */
- #ifndef CLIPPER
- else if ( ! b4leaf(index_ref) )
- rc = i4top( index_ref ) ; /* BOF - Not a leaf block */
- #endif
- }
- if ( rc < 0) return( -num_skip ) ; /* Error */
- if ( rc == 3 ) return( 0L ) ;
-
- for(;;)
- {
- #ifdef CLIPPER
- /* First Skip Over Current Key */
- if ( num_left == 0 ) return( num_skip ) ; /* Successfully skipped */
-
- if ( b4leaf(index_ref) )
- {
- num_left -= b4skip( index_ref, num_left ) ;
- if ( num_left == 0 ) return( num_skip ) ;
-
- while (1) /* Loop needed for when (sign<0) */
- {
- rc = b4up( index_ref ) ;
- if ( rc == -2)
- {
- u4error( E_INTERNAL, "i4skip", (char *) 0 ) ;
- return( -num_skip ) ; /* Error */
- }
- block_ptr = v4block+ index_ptr->block_ref ;
- if ( rc == -1)
- {
- block_ptr->key_on += sign ;
- if ( block_ptr->key_on < 0 ) block_ptr->key_on = 0 ;
- return( num_skip - num_left ) ;
- }
- /* rc == 0 */
- if ( sign > 0 )
- {
- if ( block_ptr->key_on < block_ptr->num_keys )
- {
- num_left -- ;
- break ;
- }
- }
- else
- {
- if ( --block_ptr->key_on >= 0 )
- {
- num_left ++ ;
- break ;
- }
- }
- }
- }
- else
- {
- block_ptr = v4block+ index_ptr->block_ref ;
- if ( sign > 0 )
- if ( ++block_ptr->key_on > block_ptr->num_keys ) /* EOF */
- return( num_skip - num_left ) ;
-
- num_left -= sign ;
- for ( rc = 0; rc >= 0; rc = b4down(index_ref, -sign) ) ;
- if (rc <= -2) return( -num_skip ) ; /* Error */
- }
- #else
- /* Move to a leaf in the index tree. */
- rc = 0 ;
- while ( rc >= 0 )
- {
- rc = b4down( index_ref, -sign ) ;
- if (rc == -2) return( -num_skip ) ; /* Error */
- }
-
- num_left -= b4skip( index_ref, num_left ) ;
- if ( num_left == 0) return( num_skip ) ; /* Successfully skipped */
-
- /* now skip one to the next leaf block */
- do
- {
- rc = b4up( index_ref ) ;
- if ( rc == -2)
- {
- u4error( E_INTERNAL, "i4skip", (char *) 0 ) ;
- return( -num_skip ) ; /* Error */
- }
-
- if ( rc == -1)
- {
- if ( num_skip > 0 )
- v4block[index_ptr->block_ref].key_on ++ ; /* To indicate EOF */
- return( num_skip - num_left ) ;
- }
- } while ( b4skip( index_ref, (long) sign) != (long) sign) ;
-
- num_left -= sign ;
- #endif
- }
- }
-