home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c160 / 1.ddi / SOURCE / I4CHECK.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-22  |  5.2 KB  |  227 lines

  1.  
  2. /* i4check.c   (C)Copyright Sequiter Software Inc., 1987-1990.  All rights reserved.
  3.  
  4.    Check Index checks to see if an index file is accurate.
  5. */
  6.  
  7.  
  8. #include "d4all.h"
  9. #include "p4misc.h"
  10.  
  11. #include <string.h>
  12.  
  13. extern  INDEX  *v4index ;
  14. extern  BLOCK  *v4block ;
  15. extern  int     v4lock_wait ;
  16.  
  17. static unsigned char  *rec_flags ;
  18.  
  19. static  int  set_flag(long) ;
  20. static  int  check_record(void) ;
  21. static  unsigned int  test_set(long) ;
  22.  
  23. #ifndef CLIPPER
  24. static int  i4blk_ptr_chk(void) ;
  25. #endif
  26.  
  27.  
  28. static  char  old_key[260], new_key[260] ;
  29. static  long  old_rec ;
  30. static  int   do_compare ;  /* Do not compare the first time */
  31. static  int   entry_num, i_ref  ;
  32. static  INDEX  *i_ptr =  (INDEX *) 0 ;
  33.  
  34.  
  35. static int  set_flag( long r_num )
  36. {
  37.    unsigned int  low_val, set_val, high_val  ;
  38.  
  39.    if ( r_num < 1) return( -1) ;
  40.  
  41.    low_val  =  (unsigned int) (r_num & 0x7) ;
  42.    high_val =  (unsigned int) (r_num >> 3) ;
  43.  
  44.    set_val  =  1 << low_val ;
  45.  
  46.    rec_flags[high_val] = (unsigned char)  (set_val | (unsigned int) rec_flags[high_val]) ;
  47.  
  48.    return( 0) ;
  49. }
  50.  
  51. static unsigned int  test_set( long r_num )
  52. {
  53.    unsigned int  ret_val, low_val, high_val  ;
  54.  
  55.    low_val  =  (unsigned int) (r_num & 0x7) ;
  56.    high_val =  (unsigned int) (r_num >> 3) ;
  57.  
  58.    ret_val =  (1 << low_val) &  (unsigned int) rec_flags[high_val]  ;
  59.  
  60.    return( ret_val )  ;
  61. }
  62.  
  63.  
  64. static int  check_record()
  65. {
  66.    char *ptr ;
  67.    int   key_len, rc ;
  68.    long   rec ;
  69.  
  70.    entry_num++ ;
  71.  
  72.    /* Check for Missing Key */
  73.    if ( i4key(i_ref) == (KEY *) 0)  return( -1 ) ;
  74.  
  75.    rec =  i4key(i_ref)->rec_num ;
  76.    if ( rec < 1 ||      rec > d4reccount() )
  77.       return( -3 ) ;
  78.  
  79.    if ( d4go( rec ) < 0)  return( -1) ;
  80.  
  81.    if ( test_set(rec) )
  82.       return( -4 ) ;
  83.    else
  84.       set_flag( rec ) ;
  85.  
  86.    ptr =  i4eval( i_ref ) ;
  87.    if ( ptr == (char *) 0)  return( -1 ) ;
  88.  
  89.    key_len =  i_ptr->key_len ;
  90.    memcpy( new_key, ptr,  (size_t) key_len) ;
  91.  
  92.    if ( memcmp( i4key(i_ref)->value, ptr, (size_t) key_len) != 0 )
  93.       return( -5 ) ;
  94.  
  95.    if ( do_compare )
  96.    {
  97.       if ( (rc = i4keycmp( i_ref, old_key, new_key)) > 0 ) 
  98.          return( -6 ) ;
  99.  
  100.       if ( rc == 0 && old_rec >= rec )
  101.          return( -6 ) ;
  102.    }
  103.    else
  104.       do_compare =  1 ;
  105.  
  106.    old_rec =  rec ;
  107.    memcpy( old_key, new_key, (size_t) key_len ) ;
  108.  
  109.    return( 0 ) ;
  110. }
  111.  
  112.  
  113. long  i4check( int index_ref )
  114. {
  115.    int           rc ;
  116.    unsigned int  len_flags ;
  117.    long          base_size, on_rec ;
  118.  
  119.    do_compare = 0 ;
  120.    entry_num  = 0 ;
  121.    i_ref =  index_ref ;
  122.    i_ptr =  v4index+ i_ref ;
  123.  
  124.    d4select( i_ptr->base_ref ) ;
  125.    i4select( i_ref ) ;
  126.    if ( (rc = d4lock(-1L, v4lock_wait)) < 0)  return rc ;
  127.    if ( (rc = i4lock(i_ref, v4lock_wait)) < 0)  return rc ;
  128.  
  129.    base_size =  d4reccount() ;
  130.    if ( base_size < 0 )  return( -1 ) ;
  131.  
  132.    if ( base_size > 0x7FF00L)  return( -7 ) ;
  133.  
  134.    len_flags =  (unsigned int) ((base_size-1)/8 + 2) ;
  135.  
  136.    if ( d4top() < 0 )  return( -1 ) ;
  137.  
  138.    if ( base_size == 0L )
  139.       if ( i4skip( i_ref, 1L ) == 0 )
  140.      return( 0 ) ;
  141.       else
  142.      return( -3 ) ;
  143.  
  144.    rec_flags =  (unsigned char *)  h4alloc( (int) len_flags ) ;
  145.    if ( rec_flags == (unsigned char *) 0 )   return( -2 ) ;
  146.  
  147.    rc = 1 ;
  148.    while ( rc == 1 )
  149.    {
  150.       if ( (rc=check_record()) != 0 )
  151.       {
  152.          h4free_memory( (char *) rec_flags ) ;
  153.          return( rc ) ;
  154.       }
  155.       rc =  (int) i4skip( i_ref, 1L) ;
  156.    }
  157.    if ( rc < 0 )  
  158.    {
  159.       h4free_memory( (char *) rec_flags ) ;
  160.       return( -1 ) ;
  161.    }
  162.  
  163.    #ifndef CLIPPER
  164.       /* Now make sure the block key pointers match the blocks they point to.
  165.          This needs to be true for d4seek to function perfectly.
  166.       */
  167.       if ( (rc = i4blk_ptr_chk()) < 0 )  return rc ;
  168.    #endif
  169.  
  170.    /* Now Test for Duplication */
  171.    for ( on_rec = 1;  on_rec <= base_size; on_rec++)
  172.    {
  173.       if ( ! test_set( on_rec) )  
  174.       {
  175.          h4free_memory( (char *) rec_flags ) ;
  176.          return( on_rec ) ;
  177.       }
  178.    }
  179.  
  180.    h4free_memory( (char *) rec_flags ) ;
  181.    return 0 ;
  182. }
  183.  
  184. #ifndef CLIPPER
  185.    static int  i4blk_ptr_chk()
  186.    {
  187.       int    rc, keys_skip ;
  188.       BLOCK *block_ptr ;
  189.       char  *bot_ptr, *up_ptr ;
  190.  
  191.       if ( (rc = i4bottom(i_ref)) == -1)  return -1 ;
  192.       if ( rc == 3 )  return 0 ;
  193.  
  194.       for(;;)
  195.       {
  196.          block_ptr =  v4block + i_ptr->block_ref ;
  197.          keys_skip = -block_ptr->num_keys ;
  198.          rc =  (int) i4skip( i_ref, (long) keys_skip ) ;
  199.          if ( rc == -keys_skip )  return -1 ;
  200.          if ( rc !=  keys_skip )  return  0 ;  /* Top of File */
  201.  
  202.          block_ptr =  v4block + i_ptr->block_ref ;
  203.          for(;;)
  204.          {
  205.             if ( block_ptr->prev < 0 )
  206.            {
  207.            rc = 0 ;
  208.            return -8 ;
  209.         }
  210.             block_ptr =  v4block + block_ptr->prev ;
  211.  
  212.             if ( block_ptr->key_on < block_ptr->num_keys )
  213.             {
  214.                bot_ptr =  i4key(i_ref)->value ;
  215.                up_ptr  =  block_ptr->key.value + i_ptr->group_len*block_ptr->key_on ;
  216.            if ( memcmp( bot_ptr, up_ptr, (size_t) i_ptr->key_len) != 0 )
  217.            {
  218.               rc = 0 ;
  219.               return -8 ;
  220.            }
  221.            break ;
  222.         }
  223.        }
  224.       }
  225.    }
  226. #endif
  227.