Beispiel #1
0
/*
 * get_refcount_el() --- given an block number, try to find refcount
 * 	information in the sorted list.  If the create flag is set,
 * 	and we can't find an entry, create one in the sorted list.
 */
static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
					      ea_key_t ea_key, int create)
{
	int	low, high, mid;

	if (!refcount || !refcount->list)
		return 0;
retry:
	low = 0;
	high = (int) refcount->count-1;
	if (create && ((refcount->count == 0) ||
		       (ea_key > refcount->list[high].ea_key))) {
		if (refcount->count >= refcount->size)
			refcount_collapse(refcount);

		return insert_refcount_el(refcount, ea_key,
					  (unsigned) refcount->count);
	}
	if (refcount->count == 0)
		return 0;

	if (refcount->cursor >= refcount->count)
		refcount->cursor = 0;
	if (ea_key == refcount->list[refcount->cursor].ea_key)
		return &refcount->list[refcount->cursor++];
#ifdef DEBUG
	printf("Non-cursor get_refcount_el: %u\n", ea_key);
#endif
	while (low <= high) {
		mid = (low+high)/2;
		if (ea_key == refcount->list[mid].ea_key) {
			refcount->cursor = mid+1;
			return &refcount->list[mid];
		}
		if (ea_key < refcount->list[mid].ea_key)
			high = mid-1;
		else
			low = mid+1;
	}
	/*
	 * If we need to create a new entry, it should be right at
	 * low (where high will be left at low-1).
	 */
	if (create) {
		if (refcount->count >= refcount->size) {
			refcount_collapse(refcount);
			if (refcount->count < refcount->size)
				goto retry;
		}
		return insert_refcount_el(refcount, ea_key, low);
	}
	return 0;
}
static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
					      blk_t blk, int create)
{
	float	range;
	int	low, high, mid;
	blk_t	lowval, highval;

	if (!refcount || !refcount->list)
		return 0;
retry:
	low = 0;
	high = (int) refcount->count-1;
	if (create && ((refcount->count == 0) ||
		       (blk > refcount->list[high].ea_blk))) {
		if (refcount->count >= refcount->size)
			refcount_collapse(refcount);

		return insert_refcount_el(refcount, blk,
					  (unsigned) refcount->count);
	}
	if (refcount->count == 0)
		return 0;
	
	if (refcount->cursor >= refcount->count)
		refcount->cursor = 0;
	if (blk == refcount->list[refcount->cursor].ea_blk)
		return &refcount->list[refcount->cursor++];
#ifdef DEBUG
	printf("Non-cursor get_refcount_el: %u\n", blk);
#endif
	while (low <= high) {
#if 0
		mid = (low+high)/2;
#else
		if (low == high)
			mid = low;
		else {
			/* Interpolate for efficiency */
			lowval = refcount->list[low].ea_blk;
			highval = refcount->list[high].ea_blk;

			if (blk < lowval)
				range = 0;
			else if (blk > highval)
				range = 1;
			else 
				range = ((float) (blk - lowval)) /
					(highval - lowval);
			mid = low + ((int) (range * (high-low)));
		}
#endif
		if (blk == refcount->list[mid].ea_blk) {
			refcount->cursor = mid+1;
			return &refcount->list[mid];
		}
		if (blk < refcount->list[mid].ea_blk)
			high = mid-1;
		else
			low = mid+1;
	}
	/*
	 * If we need to create a new entry, it should be right at
	 * low (where high will be left at low-1).
	 */
	if (create) {
		if (refcount->count >= refcount->size) {
			refcount_collapse(refcount);
			if (refcount->count < refcount->size)
				goto retry;
		}
		return insert_refcount_el(refcount, blk, low);
	}
	return 0;
}