Exemplo n.º 1
0
/*
 * Exact matches can use bsearch.
 */
int
blist_match(BLIST * data, const char *name)
{
    int rc = -1;
    int last = blist_count(data);
    void *check;
    ToFind dummy;

    dummy.name = name;
    check = bsearch(&dummy, data->theList, (size_t) last, data->itemSize, exact_match);
    if (check != 0) {
	rc = (int) ItemToInx(data, check);
    }
    COUNTER(total_linear, rc + 1);
    COUNTER(total_limits, last);
    COUNTER(total_calls, 1);
    return rc;
}
Exemplo n.º 2
0
/*
 * Given what may be part of the name (length in 'len'), look for a match.
 * If the result is ambiguous, do not match unless the given name exactly
 * matches one item.
 */
int
blist_pmatch(BLIST * data, const char *name, int len)
{
    int actual = (int) strlen(name);
    int rc = -1;
    int hi, lo, x0, x1, cmp;
    int last = blist_count(data);
    const char *item;
    const char *test;

    if (len < 0 || len > actual)
	len = actual;

    x1 = -1;
    hi = last - 1;
    lo = 0;
    do {
	x0 = x1;
	x1 = lo + (hi - lo) / 2;
	if (x0 == x1) {
	    if (++x1 > hi)
		break;
	}
	item = ItemOf(data, x1);
	cmp = strncmp(item, name, (size_t) len);
	if (cmp < 0) {
	    lo = (x1 == lo) ? (x1 + 1) : x1;
	} else if (cmp > 0) {
	    hi = (x1 == hi) ? (x1 - 1) : x1;
	} else {
	    rc = x1;

	    /*
	     * Check for an exact match...
	     */
	    COUNTER(total_compares, 1);
	    if (strcmp(item, name)) {
		if (x1 > lo) {
		    ToFind dummy;

		    dummy.name = name;
		    test = (const char *) bsearch(&dummy,
						  &ItemOf(data, lo),
						  (size_t) (x1 + 1 - lo),
						  (size_t) data->itemSize,
						  exact_match);
		    if (test) {
			rc = (int) ItemToInx(data, test);
			break;
		    }
		}
	    }

	    /*
	     * Now - if we have not found an exact match, check for ambiguity.
	     */
	    if (rc >= 0) {
		if (len > (int) strlen(item)) {
		    rc = -1;
		} else if (x1 < last - 1) {
		    COUNTER(total_compares, 2);
		    if (strcmp(item, name)
			&& !strncmp(ItemOf(data, x1 + 1), name, (size_t) len)) {
			rc = -1;
		    }
		}
	    }
	    break;
	}
    } while (hi >= lo);
    COUNTER(total_linear, rc + 2);
    COUNTER(total_limits, last);
    COUNTER(total_calls, 1);
    return rc;
}