home *** CD-ROM | disk | FTP | other *** search
-
- /* Index File Block Routines
- (c)Copyright Sequiter Software Inc., 1987-1990. All rights reserved. */
-
- #include "p4misc.h"
- #include "d4all.h"
- #include "h4memory.h"
- #include "u4error.h"
-
- #include <string.h>
- #ifndef UNIX
- #include <io.h>
- #endif
-
- extern INDEX *v4index ;
- extern BLOCK *v4block ;
- extern BASE *v4base ;
- extern int v4index_free, v4last_base ;
-
- static int index_next( int ) ;
-
- int i4free( int index_ref )
- {
- INDEX *index_ptr ;
-
- index_ptr = v4index + index_ref ;
-
- /* Buffer Info. is no longer Valid */
- while ( index_ptr->block_ref >= 0 )
- {
- if ( v4block[index_ptr->block_ref].wrt )
- if ( b4write( index_ref, index_ptr->block_ref ) < 0 ) return -1 ;
- index_ptr->block_ref = h4free((char **) &v4block,index_ptr->block_ref);
- }
- while ( index_ptr->block_last >= 0 )
- {
- if ( v4block[index_ptr->block_last].wrt )
- if ( b4write( index_ref, index_ptr->block_last) < 0 ) return -1 ;
- index_ptr->block_last = h4free((char **) &v4block,index_ptr->block_last);
- }
- index_ptr->block_first = -1 ;
- index_ptr->block_num = 0 ;
-
- return 0 ;
- }
-
- static int index_next( int i_ref )
- {
- int i_on, base_on ;
-
- i_on = v4index[i_ref].prev ;
- if ( i_on < 0 )
- {
- for ( base_on = v4base[v4index[i_ref].base_ref].prev ;;
- base_on = v4base[base_on].prev)
- {
- if ( base_on < 0 ) base_on = v4last_base ;
-
- i_on = v4base[base_on].index_ref ;
- if ( i_on >= 0 ) return( i_on ) ;
- }
- }
-
- return ( i_on ) ;
- }
-
- b4get( int index_ref )
- {
- MEMORY *mem_ptr ;
- INDEX *index_ptr ;
- int index_on, block_on ;
-
- mem_ptr = (MEMORY *) v4block - 1 ;
- index_ptr = v4index+ index_ref ;
-
- if ( mem_ptr->first_free >= mem_ptr->num_unit )
- {
- if ( v4index_free < 0) v4index_free = index_ref ;
-
- index_on = v4index_free ;
-
- if ( v4index[index_on].block_num <= 0 )
- for ( index_on = index_next(v4index_free);
- v4index[index_on].block_num <= 0 && index_on != v4index_free;
- index_on = index_next(index_on) ) ;
-
- v4index_free = index_on ;
-
- if ( v4index[v4index_free].block_num > 0 )
- {
- /* Free saved buffer memory */
- block_on = v4index[v4index_free].block_first ;
- if ( block_on < 0 )
- u4error( E_INTERNAL, "b4get", (char *) 0 ) ;
-
- if ( v4block[block_on].wrt ) b4write( v4index_free, block_on ) ;
- v4index[v4index_free].block_first = h4free( (char **) &v4block, block_on ) ;
- if ( v4index[v4index_free].block_first < 0 )
- v4index[v4index_free].block_last = -1 ;
- v4index[v4index_free].block_num-- ;
-
- if ( v4index[v4index_free].block_num < v4index[v4index_free].block_max )
- v4index_free = index_next(v4index_free) ;
- }
- }
-
- index_ptr->block_ref = h4get( (char **) &v4block, index_ptr->block_ref ) ;
- if ( index_ptr->block_ref < 0 ) return -1 ;
-
- return( index_ptr->block_ref ) ;
- }
-
-
- #ifdef CLIPPER
-
- static void b4insert(int, KEY *, int ) ;
-
- static void b4insert(int index_ref, KEY *key_ptr, int position )
- {
- BLOCK *block_ptr ;
- int swap_val ;
-
- block_ptr = v4block + v4index[index_ref].block_ref ;
-
- swap_val = block_ptr->pointers[block_ptr->num_keys+1] ;
- if ( swap_val+ v4index[index_ref].group_len >= BLOCK_SIZE)
- u4error( E_INTERNAL, "b4insert", (char *) 0) ;
-
- memmove( block_ptr->pointers + position +1,
- block_ptr->pointers + position,
- (size_t) (sizeof(short)* (block_ptr->num_keys +1 -position)) ) ;
- block_ptr->pointers[position] = swap_val ;
-
- memmove( (char *)&block_ptr->num_keys + swap_val, (char *) key_ptr,
- (size_t) v4index[index_ref].group_len ) ;
- block_ptr->num_keys++ ;
- block_ptr->wrt = 1 ;
- }
-
- /* b4add.c
-
- Adds the 'key' to the current memory block. Position of 'key_on' is
- assumed to point to the key in the block just greater than the
- key being added.
-
- Parameters
-
- Name Type Purpose
-
- index_ref int Specified the index file.
- key_ptr KEY * A pointer to the key to be added.
-
-
- Function Return
-
- 0 - Normal Return
- -1 - Error
- */
-
- b4add( int index_ref, KEY *key_ptr )
- {
- INDEX *index_ptr ;
- BLOCK *block_ptr, *low_block_ptr ;
- KEY *save_key_ptr, *half_key_ptr ;
-
- char save_key_data[MAX_KEY_SIZE+8] ;
- int i, swap_val, rc, i_half_key, insert_position, i_block, ref ;
- short *from, *to ;
- long save_file_block ;
-
-
- index_ptr = v4index + index_ref ;
- if ( index_ptr->block_ref < 0 ) return( -1 ) ;
-
- block_ptr = v4block + index_ptr->block_ref ;
-
- if ( block_ptr->num_keys < index_ptr->keys_max )
- {
- b4insert(index_ref, key_ptr, block_ptr->key_on) ;
- return 0 ;
- }
-
- save_key_ptr = (KEY *) save_key_data ;
-
- /* Create the Middle Key, Fill in the key to be added */
- if ( block_ptr->key_on == index_ptr->keys_half )
- memcpy( save_key_ptr, key_ptr, (size_t) index_ptr->group_len ) ;
- else
- {
- insert_position = block_ptr->key_on ;
- i_half_key = index_ptr->keys_half ;
-
- if ( block_ptr->key_on < index_ptr->keys_half )
- i_half_key-- ;
- else
- insert_position-- ;
-
- memcpy( save_key_ptr, ((char *)&block_ptr->num_keys) +
- block_ptr->pointers[i_half_key],(size_t) index_ptr->group_len);
- /* Remove the Half Way Key */
- block_ptr->key_on = i_half_key ;
- b4remove(index_ref) ;
-
- b4insert(index_ref, key_ptr, insert_position) ;
- }
-
- /* Split the block */
- if ( b4get( index_ref ) < 0 ) return -1 ;
- low_block_ptr = v4block + index_ptr->block_ref ;
- low_block_ptr->wrt = 1 ;
-
- /* 'block_ptr' may not be accurate because of 'b4get' call. */
- block_ptr = v4block + low_block_ptr->prev ;
- block_ptr->wrt = 1 ;
-
- /* Copy old block data to new block */
- memcpy( (char *)low_block_ptr + 2*sizeof(int),
- (char *)block_ptr + 2*sizeof(int), sizeof(BLOCK)-2*sizeof(int));
-
- low_block_ptr->num_keys = index_ptr->keys_half ;
-
- /* Add to the end of the file */
- if ( index_ptr->eof == 0L )
- {
- /* Add to the End */
- if ( index_ptr->virtual_eof == 0L )
- index_ptr->virtual_eof = lseek( index_ptr->file_hand, 0L, 2) ;
-
- low_block_ptr->file_block = index_ptr->virtual_eof ;
- index_ptr->virtual_eof += BLOCK_SIZE ;
- }
- else
- {
- low_block_ptr->file_block = index_ptr->eof ;
-
- /* Find new EOF */
- lseek( index_ptr->file_hand, index_ptr->eof, 0) ;
- rc = read( index_ptr->file_hand, (char *) &index_ptr->eof,
- (unsigned int) sizeof(index_ptr->eof) ) ;
- if ( rc < 0 )
- {
- u4error( E_READ, index_ptr->name, (char *) 0 ) ;
- return( -1 ) ;
- }
- }
-
- save_file_block = save_key_ptr->file_block ;
- save_key_ptr->file_block = low_block_ptr->file_block ;
-
- low_block_ptr->key_on = index_ptr->keys_half ;
- half_key_ptr = i4key(index_ref) ;
- half_key_ptr->file_block = save_file_block ;
-
- if (b4up( index_ref ) < 0) u4error( E_INTERNAL, "b4add 2", (char *) 0 ) ;
-
- /* Modify 'block_ptr' (with the 'high' keys) */
- if ( block_ptr->num_keys > index_ptr->keys_max )
- u4error( E_INTERNAL, "b4add 3", (char *) 0 ) ;
-
- to = block_ptr->pointers ;
- from = to + index_ptr->keys_half ;
- for ( i= index_ptr->keys_half; i<= block_ptr->num_keys; i++ )
- {
- swap_val= *to ;
- *to++ = *from ;
- *from++ = swap_val ;
- }
-
- block_ptr->num_keys = index_ptr->keys_half ;
- if ( (rc = b4up(index_ref)) == -2 ) return -1 ;
-
- if ( rc >= 0)
- {
- /* Add the reference to the new block to the block just up */
- rc = b4add( index_ref, save_key_ptr) ;
- if ( rc < 0 ) return -1 ;
- return 0 ;
- }
-
- /* We are on the root block and a recursive call will not work.
- Do the following:
- 1. Create a new root block
- 2. Add block pointers to the new root block pointing to both
- the new block and the old block.
- */
-
- save_file_block = block_ptr->file_block ;
-
- /* Get a new root block, flip the positions, and free the previous root block */
- ref = b4get( index_ref ) ;
- index_ptr->block_ref = h4remove( (char **) &v4block, ref ) ;
- h4add( (char **) &v4block, index_ptr->block_ref, ref, 1 ) ;
- if ( b4up(index_ref) < 0 ) u4error( E_INTERNAL, "b4add", (char *) 0 ) ;
-
- block_ptr = v4block + ref ;
-
- i_block = index_ptr->keys_max*2 + 4 ;
- for (i=0; i<= index_ptr->keys_max; i++, i_block+= index_ptr->group_len)
- block_ptr->pointers[i] = i_block ;
-
- block_ptr->num_keys = 0 ;
-
- /* Specify New Root; Increment EOF value */
- if ( index_ptr->eof == 0L )
- {
- if ( index_ptr->virtual_eof == 0L )
- index_ptr->virtual_eof = lseek( index_ptr->file_hand, 0L, 2) ;
-
- /* Add to the End */
- index_ptr->root = block_ptr->file_block = index_ptr->virtual_eof ;
- index_ptr->virtual_eof += BLOCK_SIZE ;
- }
- else
- {
- index_ptr->root = block_ptr->file_block = index_ptr->eof ;
- /* Find new EOF */
- lseek( index_ptr->file_hand, index_ptr->eof, 0 ) ;
- rc = read( index_ptr->file_hand, (char *) &index_ptr->eof,
- (unsigned int) sizeof(index_ptr->eof) ) ;
- if ( rc < 0 )
- {
- u4error( E_READ, index_ptr->name, (char *) 0 ) ;
- return( -1 ) ;
- }
- }
- b4insert( index_ref, save_key_ptr, 0 ) ;
- save_key_ptr->file_block = save_file_block ;
- b4insert( index_ref, save_key_ptr, 1 ) ;
- block_ptr->num_keys = 1 ;
- block_ptr->wrt = 1 ;
-
- return 0 ;
- }
-
- #else /* dBASE */
-
- b4add( int index_ref, KEY *key_ptr )
- {
- INDEX *index_ptr ;
- BLOCK *block_ptr, *new_block_ptr, *root_block_ptr ;
- KEY new_end_key ;
-
- char *from, *to ;
- int num_reduce, block_on ;
-
- index_ptr = v4index + index_ref ;
- if ( index_ptr->block_ref < 0 ) return( -1 ) ;
-
- block_ptr = v4block + index_ptr->block_ref ;
-
- /* Is there room in the current block ? */
- if ( block_ptr->num_keys >= index_ptr->keys_max )
- {
- /* No, the block is full. */
-
- /* Start Creating the new block */
- if ( b4get( index_ref ) < 0 ) return -1 ;
- /* Warning: Optimizing compiler likes to put 'index_ptr->block_ref'
- into a register. */
- new_block_ptr = v4block + v4index[index_ref].block_ref ;
- new_block_ptr->wrt = 1 ;
-
- /* 'block_ptr' may not be accurate because of 'b4get' call. */
- block_ptr = v4block + new_block_ptr->prev ;
- block_ptr->wrt = 1 ;
-
- /* Copy old block data to new block */
- memcpy( (char *)new_block_ptr + 2*sizeof(int),
- (char *)block_ptr + 2*sizeof(int), sizeof(BLOCK)-2*sizeof(int));
-
- /* Reduce the old block data to 1/2 its size */
- num_reduce = block_ptr->num_keys / 2 ;
- block_ptr->num_keys -= num_reduce ;
- block_ptr->key_on -= num_reduce ;
-
- /* The old block data end key should be preserved */
- to = (char *) &block_ptr->key ;
- from = to + num_reduce * index_ptr->group_len ;
- memmove( to, from, (size_t) (to+BLOCK_SIZE - from) ) ;
-
- /* New block data will be the rest */
- new_block_ptr->num_keys -= block_ptr->num_keys ;
-
- /* The new block data is added to the end */
- new_block_ptr->file_block = index_ptr->eof ;
- index_ptr->eof++ ;
-
- /* Build a key to point to the new block;
- this is the last key of the new block */
- memmove( (char *) &new_end_key,
- (char *) &new_block_ptr->key +
- (new_block_ptr->num_keys-1) * index_ptr->group_len,
- index_ptr->group_len ) ;
-
- new_end_key.rec_num = 0 ;
- new_end_key.file_block = new_block_ptr->file_block ;
-
- /* Determine which block to add the key to */
- if ( new_block_ptr->key_on < new_block_ptr->num_keys )
- {
- if ( new_block_ptr->key.file_block > 0 )
- new_block_ptr->num_keys -- ; /* Do not count the last block ptr */
-
- /* Add the key to the new block and free it */
- b4add( index_ref, key_ptr) ;
- b4up( index_ref ) ;
- }
- else
- {
- if ( new_block_ptr->key.file_block > 0 )
- new_block_ptr->num_keys -- ; /* Do not count the last block ptr */
-
- /* Free the new block */
- b4up( index_ref ) ;
-
- /* Add the key to the old block */
- b4add( index_ref, key_ptr ) ;
- }
-
- /* Check to see if the block is the root block */
- if ( b4up( index_ref) >= 0)
- {
- /* Add the reference to the new block to the block just up */
- b4add( index_ref, &new_end_key) ;
- }
- else
- {
- /* We are on the root block and a recursive call will not work.
- Do the following:
- 1. Create a new root block
- 2. Add block pointers to the root block pointing to both
- the new block and the old block.
- */
-
- /* Add a new root block */
- if ( b4get( index_ref ) < 0 ) return -1 ;
-
- /* Flip the positions */
- block_on = index_ptr->block_ref ;
- index_ptr->block_ref = h4remove( (char **) &v4block, block_on ) ;
- h4add( (char **) &v4block, index_ptr->block_ref, block_on, 1 ) ;
-
- root_block_ptr = v4block + block_on ;
- root_block_ptr->wrt = 1 ;
- block_ptr = v4block + index_ptr->block_ref ;
- block_ptr->wrt = 1 ;
-
- /* Specify New Root; Increment EOF value */
- index_ptr->root = root_block_ptr->file_block = index_ptr->eof++ ;
- root_block_ptr->num_keys = 1 ;
-
- /* Add the new key to the new root block */
- memmove( (char *) &root_block_ptr->key,
- (char *) &new_end_key, (size_t) index_ptr->group_len ) ;
-
- /* Add Pointer to the old root block */
- new_end_key.file_block = block_ptr->file_block ;
- new_end_key.rec_num = 0 ;
-
- memmove( (char *) &root_block_ptr->key + index_ptr->group_len,
- (char *) &new_end_key, 2*sizeof(long) ) ;
-
- b4up( index_ref ) ;
- }
- }
- else
- {
- /* There is Room in the Current Block */
- block_ptr->num_keys ++ ;
- block_ptr->wrt = 1 ;
-
- /* Make Room at Current Position */
- from = (char *) i4key( index_ref ) ;
- to = from + index_ptr->group_len ;
- memmove( to, from, (size_t) ((char *) &block_ptr->num_keys +BLOCK_SIZE - to) ) ;
-
- /* Insert the Current Key */
- memmove( from, (char *) key_ptr, (size_t) index_ptr->group_len ) ;
- }
- return( 0) ;
- }
-
- #endif
-
-
-
- /* b4leaf.c
-
- Returns TRUE iff the current block is a leaf in the B+ tree
- */
-
- b4leaf( int index_ref )
- {
- BLOCK *block_ptr ;
-
- #ifdef CLIPPER
- KEY *key_ptr ;
- block_ptr = v4block+ v4index[index_ref].block_ref ;
- key_ptr= (KEY *) (((char *)&block_ptr->num_keys)+ block_ptr->pointers[0]);
- return( key_ptr->file_block == 0L ) ;
- #else
- block_ptr = v4block+ v4index[index_ref].block_ref ;
- return( block_ptr->key.file_block == 0L ) ;
- #endif
- }
-
-
- /* b4down.c
-
- Reads the Specified Block into Memory.
-
- Returns
- -2 error reading
- -1 cannot move down
- >=0 block reference number
-
- */
-
- b4down( int index_ref, int direction )
- {
- INDEX *index_ptr ;
- BLOCK *block_ptr ;
- long file_block ;
- int block_on, block_new, from_disk ;
- KEY *key_ptr ;
-
- from_disk = 1 ;
-
- index_ptr = v4index + index_ref ;
- if ( index_ptr->block_ref < 0)
- file_block = index_ptr->root ; /* read the root block */
- else
- {
- key_ptr = i4key(index_ref) ;
- if ( key_ptr == (KEY *) 0 ) return -1 ; /* No Records in Index File */
-
- file_block = key_ptr->file_block ;
- if ( file_block <= 0 )
- return( -1 ) ; /* We are on a leaf and we cannot go down further ! */
- }
-
- /* Search for the block in memory */
- for( block_on= index_ptr->block_last; block_on>= 0; block_on= block_ptr->prev)
- {
- block_ptr = v4block+ block_on ;
- if ( block_ptr->file_block == file_block )
- {
- /* Found, remove from one chain and add to another */
- block_new = h4remove( (char **) &v4block, block_on);
- index_ptr->block_num-- ;
- if ( block_on == index_ptr->block_last )
- index_ptr->block_last = block_new ;
- if ( index_ptr->block_first == block_on )
- index_ptr->block_first = block_new ;
-
- index_ptr->block_ref =
- h4add( (char **) &v4block, index_ptr->block_ref, block_on, 0 ) ;
-
- from_disk = 0 ;
- block_ptr = v4block+ index_ptr->block_ref ;
- break ;
- }
- }
-
- if ( from_disk )
- {
- /* Was not located, allocate memory for the new block */
- if ( b4get( index_ref ) < 0 ) return -3 ;
- block_ptr = v4block + index_ptr->block_ref ;
-
- #ifdef CLIPPER
- lseek( index_ptr->file_hand, file_block, 0 ) ;
- if ( read( index_ptr->file_hand, (char *) &block_ptr->num_keys, BLOCK_SIZE )
- != BLOCK_SIZE )
- #else
- lseek( index_ptr->file_hand, (long) BLOCK_SIZE * file_block, 0 ) ;
- if ( read( index_ptr->file_hand, (char *) &block_ptr->num_keys, BLOCK_SIZE )
- != BLOCK_SIZE )
- #endif
- {
- u4error( E_READ, index_ptr->name, (char *) 0 ) ;
- return( -2 ) ;
- }
- block_ptr->file_block = file_block ;
- }
-
- if (direction < 0)
- block_ptr->key_on = 0 ;
- else
- {
- block_ptr->key_on = block_ptr->num_keys ;
- if ( b4leaf(index_ref) )
- block_ptr->key_on -- ; /* On a leaf block in the tree */
- }
-
- return( index_ptr->block_ref ) ;
- }
-
-
- /* i4key.c
-
- Returns a (KEY *) pointer
- */
-
- KEY * i4key( int index_ref )
- {
- INDEX *index_ptr ;
- BLOCK *block_ptr ;
- char *ptr ;
-
- index_ptr = v4index + index_ref ;
-
- if ( index_ptr->block_ref >= 0 )
- {
- block_ptr = v4block + index_ptr->block_ref ;
-
- if ( block_ptr->key_on >= 0 && block_ptr->key_on <= block_ptr->num_keys)
- {
- #ifdef CLIPPER
- ptr = ((char *) &block_ptr->num_keys) + block_ptr->pointers[block_ptr->key_on] ;
- #else
- ptr = ((char *) &block_ptr->key) + index_ptr->group_len*block_ptr->key_on ;
- #endif
- return( (KEY *) ptr ) ;
- }
- }
- return( (KEY *) 0 ) ;
- }
-
- /* b4remove.c */
- #ifdef CLIPPER
- b4remove( int index_ref )
- {
- int num_copy, old_ptr ;
- short *pointers, *from, *to ;
- BLOCK *block_ptr ;
- INDEX *index_ptr ;
-
- index_ptr = v4index + index_ref ;
- if ( index_ptr->block_ref < 0) return( -1 ) ;
-
- block_ptr = v4block + index_ptr->block_ref ;
- block_ptr->num_keys-- ;
- block_ptr->wrt = 1 ;
-
- if ( block_ptr->key_on < 0 ||
- block_ptr->key_on > index_ptr->keys_max ||
- block_ptr->num_keys < 0 )
- u4error( E_INTERNAL, "b4remove", (char *) 0 ) ;
-
- pointers = block_ptr->pointers ;
-
- old_ptr = pointers[block_ptr->key_on] ;
- num_copy = index_ptr->keys_max - block_ptr->key_on ;
- to = pointers + block_ptr->key_on ;
- from = to + 1 ;
-
- memmove( (char *) to, (char *) from, (size_t) num_copy*sizeof(short) ) ;
- pointers[index_ptr->keys_max] = old_ptr ;
-
- if ( ((KEY *)((char *)&block_ptr->num_keys + old_ptr))->file_block == 0 )
- return( block_ptr->num_keys ) ;
- else
- return( block_ptr->num_keys + 1 ) ;
- }
- #else
- b4remove( int index_ref )
- {
- int to_offset, num_copy ;
- char *to, *from ;
- BLOCK *block_ptr ;
- INDEX *index_ptr ;
-
- index_ptr = v4index + index_ref ;
- block_ptr = v4block + index_ptr->block_ref ;
- block_ptr->wrt = 1 ;
-
- if ( index_ptr->block_ref < 0) return( -1 ) ;
-
- if ( block_ptr->key_on < index_ptr->keys_max )
- {
- to_offset = index_ptr->group_len*block_ptr->key_on ;
- num_copy = 508 - to_offset - index_ptr->group_len ;
- to = (char *) &block_ptr->key.file_block + to_offset ;
- from = to + index_ptr->group_len ;
- memmove( to, from, (size_t) num_copy ) ;
- }
-
- block_ptr->num_keys -= 1 ;
- if ( block_ptr->num_keys < 0 ) return( 0 ) ;
- if ( block_ptr->key.file_block != 0 )
- return( block_ptr->num_keys + 1 ) ;
- else
- return( block_ptr->num_keys ) ;
- }
- #endif
-
- /* b4search.c
-
- Locates a key string in the current block using a binary search.
- Sets key_on in current the current block.
-
- Returns
-
- Function Return
- 0 - Complete Match
- 1 - Inexact Match
- 2 - After the specified key
- 3 - After the Block
- */
-
- b4search( int index_ref, char *search_string )
- {
- INDEX *index_ptr ;
- BLOCK *block_ptr ;
- KEY *key_ptr ;
- int search_len, key_len, key_lower, key_upper, key_on, rc ;
-
- #ifndef CLIPPER
- int group_len ;
- #endif
-
- index_ptr = v4index+ index_ref ;
-
- /* Make sure a block exists !! */
- if ( index_ptr->block_ref < 0 )
- {
- /* Read the Top Block */
- if ( b4down( index_ref, -1 ) < 0) return( -1) ;
- }
- block_ptr = v4block + index_ptr->block_ref ;
-
-
- /* Prepare for the search */
-
- key_len = index_ptr->key_len ;
-
- #ifdef CLIPPER
- search_len = (int) strlen( search_string ) ;
- if ( search_len > key_len ) search_len = key_len ;
- #else
- /* For character searches, we can have a partial search */
- if ( index_ptr->int_or_date )
- search_len = key_len ;
- else
- {
- search_len = (int) strlen( search_string ) ;
- if ( search_len > key_len ) search_len = key_len ;
- }
- group_len = index_ptr->group_len ;
- #endif
-
- /* key_on must be between key_lower and key_upper */
- key_lower = -1 ;
- key_upper = block_ptr->num_keys ;
-
- if ( key_upper == 0 )
- {
- block_ptr->key_on = block_ptr->num_keys ;
- return( 3 ) ;
- }
-
- /* Repeat until the key is found in the block */
-
- for(;;)
- {
- key_on = (key_upper + key_lower) / 2 ;
- #ifdef CLIPPER
- key_ptr = (KEY *) (((char *)&block_ptr->num_keys) + block_ptr->pointers[key_on] ) ;
- #ifdef LANGUAGE
- rc = u4memcmp( search_string, key_ptr->value, (size_t) search_len ) ;
- #else
- rc = memcmp( search_string, key_ptr->value, (size_t) search_len ) ;
- #endif
- #else
- key_ptr = (KEY *) (((char *)&block_ptr->key) + key_on * group_len) ;
- if ( index_ptr->int_or_date )
- rc = i4keycmp( index_ref, search_string, key_ptr->value ) ;
- else
- #ifdef LANGUAGE
- rc = u4memcmp( (unsigned char *) search_string,
- (unsigned char *) key_ptr->value, (size_t) search_len ) ;
- #else
- rc = memcmp( search_string, key_ptr->value, (size_t) search_len ) ;
- #endif
- #endif
-
- if ( rc == 0 )
- {
- if ( key_on <= key_lower+1 )
- {
- block_ptr->key_on = key_on ;
- if ( key_len == search_len )
- return( 0) ; /* Complete Match */
- else
- return( 1) ; /* Partial Match */
- }
-
- /* Perhaps there is Another Match (we want the first match) */
- key_upper = key_on + 1 ;
- continue ;
- }
- else
- {
- if ( rc < 0 )
- key_upper = key_on ;
- else
- key_lower = key_on ;
- }
-
- if ( key_lower >= (key_upper-1) )
- {
- /* There is no Exact Match */
- if ( key_lower >= block_ptr->num_keys -1 )
- {
- block_ptr->key_on = block_ptr->num_keys ;
- return( 3 ) ;
- }
-
- /* Located inside the block */
- block_ptr->key_on = key_upper ;
- return( 2) ;
- }
- }
- }
-
- /* b4skip.c
-
- Skips keys in the current block memory unit of the specified index file.
- */
-
- long b4skip( int index_ref, long n )
- {
- INDEX *index_ptr ;
- BLOCK *block_ptr ;
- long num_left ;
-
- index_ptr = v4index + index_ref ;
- if ( index_ptr->block_ref < 0 ) return( -n ) ;
-
- block_ptr = v4block + index_ptr->block_ref ;
-
- if ( n > 0 )
- {
- num_left = (long) (block_ptr->num_keys - block_ptr->key_on) ;
- if ( b4leaf(index_ref) )
- if ( num_left != 0 )
- num_left -- ;
- }
- else
- num_left = (long) -block_ptr->key_on ;
-
- if ( ( n <= 0 ) ? (num_left <= n) : (num_left >= n) )
- {
- block_ptr->key_on += (int) n ;
- return( n ) ;
- }
- else
- {
- block_ptr->key_on += (int) num_left ;
- return( num_left ) ;
- }
- }
-
-
- /* b4up.c
-
- Frees the Current Block.
-
- Returns
- -2 nothing on list
- -1 on root block already
- >=0 block reference number
-
- */
-
- b4up( int index_ref )
- {
- INDEX *index_ptr ;
- int block_ref ;
-
- index_ptr = v4index + index_ref ;
-
- if ( index_ptr->block_ref < 0)
- return( -2 ) ;
-
- if ( v4block[ index_ptr->block_ref].prev < 0 )
- return( -1 ) ;
-
- block_ref = index_ptr->block_ref ;
- index_ptr->block_ref = h4remove( (char **) &v4block, block_ref ) ;
- index_ptr->block_last= h4add( (char **) &v4block, index_ptr->block_last, block_ref, 0) ;
- if ( index_ptr->block_first < 0 )
- index_ptr->block_first = index_ptr->block_last ;
- index_ptr->block_num++ ;
-
- return( index_ptr->block_ref ) ;
- }
-
-
- /* b4write.c
-
- Writes the current block memory unit of the specified index file.
- */
-
- b4write( int index_ref, int block_ref )
- {
- INDEX *index_ptr ;
- BLOCK *block_ptr ;
- int rc ;
-
- index_ptr = v4index + index_ref ;
- block_ptr = v4block + block_ref ;
- block_ptr->wrt = 0 ;
-
- #ifdef CLIPPER
- lseek( index_ptr->file_hand, (long) block_ptr->file_block, 0 ) ;
- rc = write( index_ptr->file_hand, (char *) &block_ptr->num_keys, BLOCK_SIZE) ;
- #else
- lseek( index_ptr->file_hand, (long)BLOCK_SIZE* block_ptr->file_block, 0);
- rc = write( index_ptr->file_hand, (char *) &block_ptr->num_keys, BLOCK_SIZE);
- #endif
- if ( rc != BLOCK_SIZE )
- {
- u4error( E_WRITE, index_ptr->name, (char *) 0 ) ;
- return( -1 ) ;
- }
-
- return( 0) ;
- }
-