/* * 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; }