(trunk libT) #2547: fix tr_lowerBound()

This commit is contained in:
Charles Kerr 2009-10-31 22:16:06 +00:00
parent 085302f15f
commit 060bd2f722
2 changed files with 49 additions and 14 deletions

View File

@ -227,6 +227,44 @@ test_numbers( void )
return 0;
}
static int
compareInts( const void * va, const void * vb )
{
const int a = *(const int *)va;
const int b = *(const int*)vb;
return a - b;
}
static int
test_lowerbound( void )
{
int i;
const int A[] = { 1, 2, 3, 3, 3, 5, 8 };
const int expected_pos[] = { 0, 1, 2, 5, 5, 6, 6, 6, 7, 7 };
const int expected_exact[] = { TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE };
const int N = sizeof(A) / sizeof(A[0]);
for( i=1; i<=10; ++i )
{
tr_bool exact;
const int pos = tr_lowerBound( &i, A, N, sizeof(int), compareInts, &exact );
#if 0
fprintf( stderr, "searching for %d. ", i );
fprintf( stderr, "result: index = %d, ", pos );
if( pos != N )
fprintf( stderr, "A[%d] == %d\n", pos, A[pos] );
else
fprintf( stderr, "which is off the end.\n" );
#endif
check( pos == expected_pos[i-1] )
check( exact == expected_exact[i-1] )
}
return 0;
}
static int
test_memmem( void )
{
@ -270,6 +308,8 @@ main( void )
tr_free( in );
tr_free( out );
if( ( i = test_lowerbound( ) ) )
return i;
if( ( i = test_strstrip( ) ) )
return i;
if( ( i = test_buildpath( ) ) )

View File

@ -1108,32 +1108,27 @@ tr_lowerBound( const void * key,
{
size_t first = 0;
const char * cbase = base;
tr_bool exact = FALSE;
int c;
while( nmemb )
{
const size_t half = nmemb / 2;
const size_t middle = first + half;
const int c = compar( key, cbase + size*middle );
c = compar( key, cbase + size*middle );
if( c < 0 )
{
if( c <= 0 ) {
if( c == 0 )
exact = TRUE;
nmemb = half;
} else {
first = middle + 1;
nmemb = nmemb - half - 1;
}
else if( !c )
{
if( exact_match )
*exact_match = TRUE;
return middle;
}
else
{
nmemb = half;
}
}
if( exact_match )
*exact_match = FALSE;
*exact_match = exact;
return first;
}