/* * call-seq: * bv.next_from(from) -> bit_num * * Returns the next set bit in the bit-vector scanning from low order to * high order and starting at +from+. The scan is inclusive so if * +from+ is equal to 10 and +bv[10]+ is set it will * return the number 10. If the bit-vector has been negated than you should * use the +#next_unset_from+ method. */ VALUE frt_bv_next_from(VALUE self, VALUE rfrom) { BitVector *bv; int from = FIX2INT(rfrom); GET_BV(bv, self); if (from < 0) { from = 0; } return INT2FIX(bv_scan_next_from(bv, from)); }
/** * Stress test BitVector Scanning as well as bv_set_fast. This test has been * run successfully with BV_DENSE_SCAN_SIZE set to 20000000 and BV_SCAN_INC * set to 97. When running this test with high numbers, be sure use -q on the * command line or the test will take a very long time. */ static void test_bv_scan_stress(TestCase *tc, void *data) { int i; BitVector *bv = bv_new_capa(BV_SCAN_SIZE); BitVector *not_bv; (void)data; /* suppress unused argument warning */ for (i = BV_SCAN_INC; i < BV_SCAN_SIZE; i += BV_SCAN_INC) { bv_set_fast(bv, i); Aiequal(bv_get(bv, i), 1); Aiequal(bv_get(bv, i-1), 0); Aiequal(bv_get(bv, i+1), 0); } not_bv = bv_not(bv); for (i = BV_SCAN_INC; i < BV_SCAN_SIZE; i += BV_SCAN_INC) { Aiequal(i, bv_scan_next_from(bv, i - BV_SCAN_INC / 2)); Aiequal(i, bv_scan_next_unset_from(not_bv, i - BV_SCAN_INC / 2)); } Aiequal(-1, bv_scan_next_from(bv, i - BV_SCAN_INC / 2)); Aiequal(-1, bv_scan_next_unset_from(not_bv, i - BV_SCAN_INC / 2)); /* test scan_next_from where size is actually greater than the highest set * bit */ bv_unset(bv, bv->size); bv_set(not_bv, not_bv->size); bv_scan_reset(bv); bv_scan_reset(not_bv); for (i = BV_SCAN_INC; i < BV_SCAN_SIZE; i += BV_SCAN_INC) { Aiequal(i, bv_scan_next_from(bv, i - BV_SCAN_INC / 2)); Aiequal(i, bv_scan_next_unset_from(not_bv, i - BV_SCAN_INC / 2)); } Aiequal(-1, bv_scan_next_from(bv, i - BV_SCAN_INC / 2)); Aiequal(-1, bv_scan_next_unset_from(not_bv, i - BV_SCAN_INC / 2)); bv_scan_reset(bv); bv_scan_reset(not_bv); for (i = BV_SCAN_INC; i < BV_SCAN_SIZE; i += BV_SCAN_INC) { Aiequal(i, bv_scan_next(bv)); Aiequal(i, bv_scan_next_unset(not_bv)); } Aiequal(-1, bv_scan_next(bv)); Aiequal(-1, bv_scan_next_unset(not_bv)); bv_clear(bv); bv_destroy(not_bv); for (i = 0; i < BV_DENSE_SCAN_SIZE; i++) { bv_set(bv, i); } not_bv = bv_not(bv); for (i = 0; i < BV_DENSE_SCAN_SIZE; i++) { Aiequal(i, bv_scan_next_from(bv, i)); Aiequal(i, bv_scan_next_unset_from(not_bv, i)); } Aiequal(-1, bv_scan_next_from(bv, i)); Aiequal(-1, bv_scan_next_unset_from(not_bv, i)); bv_scan_reset(bv); bv_scan_reset(not_bv); for (i = 0; i < BV_DENSE_SCAN_SIZE; i++) { Aiequal(i, bv_scan_next(bv)); Aiequal(i, bv_scan_next_unset(not_bv)); } Aiequal(-1, bv_scan_next(bv)); Aiequal(-1, bv_scan_next_unset(not_bv)); bv_destroy(bv); bv_destroy(not_bv); }