/* * 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; }
int main(int argc, char **argv) { int i = 0; ext2_refcount_t refcount; size_t size; ea_key_t ea_key; ea_value_t arg; errcode_t retval; while (1) { switch (bcode_program[i++]) { case BCODE_END: exit(0); case BCODE_CREATE: size = bcode_program[i++]; retval = ea_refcount_create(size, &refcount); if (retval) { com_err("ea_refcount_create", retval, "while creating size %zu", size); exit(1); } else printf("Creating refcount with size %zu\n", size); break; case BCODE_FREE: ea_refcount_free(refcount); refcount = 0; printf("Freeing refcount\n"); break; case BCODE_STORE: ea_key = (size_t) bcode_program[i++]; arg = bcode_program[i++]; printf("Storing ea_key %llu with value %llu\n", ea_key, arg); retval = ea_refcount_store(refcount, ea_key, arg); if (retval) com_err("ea_refcount_store", retval, "while storing ea_key %llu", ea_key); break; case BCODE_FETCH: ea_key = (size_t) bcode_program[i++]; retval = ea_refcount_fetch(refcount, ea_key, &arg); if (retval) com_err("ea_refcount_fetch", retval, "while fetching ea_key %llu", ea_key); else printf("bcode_fetch(%llu) returns %llu\n", ea_key, arg); break; case BCODE_INCR: ea_key = (size_t) bcode_program[i++]; retval = ea_refcount_increment(refcount, ea_key, &arg); if (retval) com_err("ea_refcount_increment", retval, "while incrementing ea_key %llu", ea_key); else printf("bcode_increment(%llu) returns %llu\n", ea_key, arg); break; case BCODE_DECR: ea_key = (size_t) bcode_program[i++]; retval = ea_refcount_decrement(refcount, ea_key, &arg); if (retval) com_err("ea_refcount_decrement", retval, "while decrementing ea_key %llu", ea_key); else printf("bcode_decrement(%llu) returns %llu\n", ea_key, arg); break; case BCODE_VALIDATE: retval = ea_refcount_validate(refcount, stderr); if (retval) com_err("ea_refcount_validate", retval, "while validating"); else printf("Refcount validation OK.\n"); break; case BCODE_LIST: ea_refcount_intr_begin(refcount); while (1) { ea_key = ea_refcount_intr_next(refcount, &arg); if (!ea_key) break; printf("\tea_key=%llu, count=%llu\n", ea_key, arg); } break; case BCODE_COLLAPSE: refcount_collapse(refcount); break; } } }
int main(int argc, char **argv) { int i = 0; ext2_refcount_t refcount; int size, arg; blk_t blk; errcode_t retval; while (1) { switch (bcode_program[i++]) { case BCODE_END: exit(0); case BCODE_CREATE: size = bcode_program[i++]; retval = ea_refcount_create(size, &refcount); if (retval) { com_err("ea_refcount_create", retval, ""); exit(1); } else printf("Creating refcount with size %d\n", size); break; case BCODE_FREE: ea_refcount_free(refcount); refcount = 0; printf("Freeing refcount\n"); break; case BCODE_STORE: blk = (blk_t) bcode_program[i++]; arg = bcode_program[i++]; retval = ea_refcount_store(refcount, blk, arg); printf("Storing blk %u with value %d\n", blk, arg); if (retval) com_err("ea_refcount_store", retval, ""); break; case BCODE_FETCH: blk = (blk_t) bcode_program[i++]; retval = ea_refcount_fetch(refcount, blk, &arg); if (retval) com_err("ea_refcount_fetch", retval, ""); else printf("bcode_fetch(%u) returns %d\n", blk, arg); break; case BCODE_INCR: blk = (blk_t) bcode_program[i++]; retval = ea_refcount_increment(refcount, blk, &arg); if (retval) com_err("ea_refcount_increment", retval, ""); else printf("bcode_increment(%u) returns %d\n", blk, arg); break; case BCODE_DECR: blk = (blk_t) bcode_program[i++]; retval = ea_refcount_decrement(refcount, blk, &arg); if (retval) com_err("ea_refcount_decrement", retval, "while decrementing blk %u", blk); else printf("bcode_decrement(%u) returns %d\n", blk, arg); break; case BCODE_VALIDATE: retval = ea_refcount_validate(refcount, stderr); if (retval) com_err("ea_refcount_validate", retval, ""); else printf("Refcount validation OK.\n"); break; case BCODE_LIST: ea_refcount_intr_begin(refcount); while (1) { blk = ea_refcount_intr_next(refcount, &arg); if (!blk) break; printf("\tblk=%u, count=%d\n", blk, arg); } break; case BCODE_COLLAPSE: refcount_collapse(refcount); break; } } }
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; }