home *** CD-ROM | disk | FTP | other *** search
-
- /* i4check.c (C)Copyright Sequiter Software Inc., 1987-1990. All rights reserved.
-
- Check Index checks to see if an index file is accurate.
- */
-
-
- #include "d4all.h"
- #include "p4misc.h"
-
- #include <string.h>
-
- extern INDEX *v4index ;
- extern BLOCK *v4block ;
- extern int v4lock_wait ;
-
- static unsigned char *rec_flags ;
-
- static int set_flag(long) ;
- static int check_record(void) ;
- static unsigned int test_set(long) ;
-
- #ifndef CLIPPER
- static int i4blk_ptr_chk(void) ;
- #endif
-
-
- static char old_key[260], new_key[260] ;
- static long old_rec ;
- static int do_compare ; /* Do not compare the first time */
- static int entry_num, i_ref ;
- static INDEX *i_ptr = (INDEX *) 0 ;
-
-
- static int set_flag( long r_num )
- {
- unsigned int low_val, set_val, high_val ;
-
- if ( r_num < 1) return( -1) ;
-
- low_val = (unsigned int) (r_num & 0x7) ;
- high_val = (unsigned int) (r_num >> 3) ;
-
- set_val = 1 << low_val ;
-
- rec_flags[high_val] = (unsigned char) (set_val | (unsigned int) rec_flags[high_val]) ;
-
- return( 0) ;
- }
-
- static unsigned int test_set( long r_num )
- {
- unsigned int ret_val, low_val, high_val ;
-
- low_val = (unsigned int) (r_num & 0x7) ;
- high_val = (unsigned int) (r_num >> 3) ;
-
- ret_val = (1 << low_val) & (unsigned int) rec_flags[high_val] ;
-
- return( ret_val ) ;
- }
-
-
- static int check_record()
- {
- char *ptr ;
- int key_len, rc ;
- long rec ;
-
- entry_num++ ;
-
- /* Check for Missing Key */
- if ( i4key(i_ref) == (KEY *) 0) return( -1 ) ;
-
- rec = i4key(i_ref)->rec_num ;
- if ( rec < 1 || rec > d4reccount() )
- return( -3 ) ;
-
- if ( d4go( rec ) < 0) return( -1) ;
-
- if ( test_set(rec) )
- return( -4 ) ;
- else
- set_flag( rec ) ;
-
- ptr = i4eval( i_ref ) ;
- if ( ptr == (char *) 0) return( -1 ) ;
-
- key_len = i_ptr->key_len ;
- memcpy( new_key, ptr, (size_t) key_len) ;
-
- if ( memcmp( i4key(i_ref)->value, ptr, (size_t) key_len) != 0 )
- return( -5 ) ;
-
- if ( do_compare )
- {
- if ( (rc = i4keycmp( i_ref, old_key, new_key)) > 0 )
- return( -6 ) ;
-
- if ( rc == 0 && old_rec >= rec )
- return( -6 ) ;
- }
- else
- do_compare = 1 ;
-
- old_rec = rec ;
- memcpy( old_key, new_key, (size_t) key_len ) ;
-
- return( 0 ) ;
- }
-
-
- long i4check( int index_ref )
- {
- int rc ;
- unsigned int len_flags ;
- long base_size, on_rec ;
-
- do_compare = 0 ;
- entry_num = 0 ;
- i_ref = index_ref ;
- i_ptr = v4index+ i_ref ;
-
- d4select( i_ptr->base_ref ) ;
- i4select( i_ref ) ;
- if ( (rc = d4lock(-1L, v4lock_wait)) < 0) return rc ;
- if ( (rc = i4lock(i_ref, v4lock_wait)) < 0) return rc ;
-
- base_size = d4reccount() ;
- if ( base_size < 0 ) return( -1 ) ;
-
- if ( base_size > 0x7FF00L) return( -7 ) ;
-
- len_flags = (unsigned int) ((base_size-1)/8 + 2) ;
-
- if ( d4top() < 0 ) return( -1 ) ;
-
- if ( base_size == 0L )
- if ( i4skip( i_ref, 1L ) == 0 )
- return( 0 ) ;
- else
- return( -3 ) ;
-
- rec_flags = (unsigned char *) h4alloc( (int) len_flags ) ;
- if ( rec_flags == (unsigned char *) 0 ) return( -2 ) ;
-
- rc = 1 ;
- while ( rc == 1 )
- {
- if ( (rc=check_record()) != 0 )
- {
- h4free_memory( (char *) rec_flags ) ;
- return( rc ) ;
- }
- rc = (int) i4skip( i_ref, 1L) ;
- }
- if ( rc < 0 )
- {
- h4free_memory( (char *) rec_flags ) ;
- return( -1 ) ;
- }
-
- #ifndef CLIPPER
- /* Now make sure the block key pointers match the blocks they point to.
- This needs to be true for d4seek to function perfectly.
- */
- if ( (rc = i4blk_ptr_chk()) < 0 ) return rc ;
- #endif
-
- /* Now Test for Duplication */
- for ( on_rec = 1; on_rec <= base_size; on_rec++)
- {
- if ( ! test_set( on_rec) )
- {
- h4free_memory( (char *) rec_flags ) ;
- return( on_rec ) ;
- }
- }
-
- h4free_memory( (char *) rec_flags ) ;
- return 0 ;
- }
-
- #ifndef CLIPPER
- static int i4blk_ptr_chk()
- {
- int rc, keys_skip ;
- BLOCK *block_ptr ;
- char *bot_ptr, *up_ptr ;
-
- if ( (rc = i4bottom(i_ref)) == -1) return -1 ;
- if ( rc == 3 ) return 0 ;
-
- for(;;)
- {
- block_ptr = v4block + i_ptr->block_ref ;
- keys_skip = -block_ptr->num_keys ;
- rc = (int) i4skip( i_ref, (long) keys_skip ) ;
- if ( rc == -keys_skip ) return -1 ;
- if ( rc != keys_skip ) return 0 ; /* Top of File */
-
- block_ptr = v4block + i_ptr->block_ref ;
- for(;;)
- {
- if ( block_ptr->prev < 0 )
- {
- rc = 0 ;
- return -8 ;
- }
- block_ptr = v4block + block_ptr->prev ;
-
- if ( block_ptr->key_on < block_ptr->num_keys )
- {
- bot_ptr = i4key(i_ref)->value ;
- up_ptr = block_ptr->key.value + i_ptr->group_len*block_ptr->key_on ;
- if ( memcmp( bot_ptr, up_ptr, (size_t) i_ptr->key_len) != 0 )
- {
- rc = 0 ;
- return -8 ;
- }
- break ;
- }
- }
- }
- }
- #endif
-