Merge branch 'cc/bisect'
authorJunio C Hamano <gitster@pobox.com>
Thu, 2 Jul 2009 02:41:04 +0000 (19:41 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 2 Jul 2009 02:41:04 +0000 (19:41 -0700)
* cc/bisect:
Documentation: remove warning saying that "git bisect skip" may slow bisection
bisect: use a PRNG with a bias when skipping away from untestable commits

1  2 
bisect.c
diff --combined bisect.c
index dbeb28752adce639d8729fa7cbb003fc31bd240f,095b55eba6a1cd41907c3b3e9619e614af9a0acb..52220df751aaacec08792c01ad83f2a1b27aae5f
+++ b/bisect.c
@@@ -454,7 -454,7 +454,7 @@@ static int read_bisect_refs(void
        return for_each_ref_in("refs/bisect/", register_ref, NULL);
  }
  
 -void read_bisect_paths(struct argv_array *array)
 +static void read_bisect_paths(struct argv_array *array)
  {
        struct strbuf str = STRBUF_INIT;
        const char *filename = git_path("BISECT_NAMES");
@@@ -585,16 -585,49 +585,49 @@@ struct commit_list *filter_skipped(stru
        return filtered;
  }
  
- static struct commit_list *apply_skip_ratio(struct commit_list *list,
-                                           int count,
-                                           int skip_num, int skip_denom)
+ #define PRN_MODULO 32768
+ /*
+  * This is a pseudo random number generator based on "man 3 rand".
+  * It is not used properly because the seed is the argument and it
+  * is increased by one between each call, but that should not matter
+  * for this application.
+  */
+ int get_prn(int count) {
+       count = count * 1103515245 + 12345;
+       return ((unsigned)(count/65536) % PRN_MODULO);
+ }
+ /*
+  * Custom integer square root from
+  * http://en.wikipedia.org/wiki/Integer_square_root
+  */
+ static int sqrti(int val)
+ {
+       float d, x = val;
+       if (val == 0)
+               return 0;
+       do {
+               float y = (x + (float)val / x) / 2;
+               d = (y > x) ? y - x : x - y;
+               x = y;
+       } while (d >= 0.5);
+       return (int)x;
+ }
+ static struct commit_list *skip_away(struct commit_list *list, int count)
  {
-       int index, i;
        struct commit_list *cur, *previous;
+       int prn, index, i;
+       prn = get_prn(count);
+       index = (count * prn / PRN_MODULO) * sqrti(prn) / sqrti(PRN_MODULO);
  
        cur = list;
        previous = NULL;
-       index = count * skip_num / skip_denom;
  
        for (i = 0; cur; cur = cur->next, i++) {
                if (i == index) {
@@@ -614,7 -647,6 +647,6 @@@ static struct commit_list *managed_skip
                                           struct commit_list **tried)
  {
        int count, skipped_first;
-       int skip_num, skip_denom;
  
        *tried = NULL;
  
        if (!skipped_first)
                return list;
  
-       /* Use alternatively 1/5, 2/5 and 3/5 as skip ratio. */
-       skip_num = count % 3 + 1;
-       skip_denom = 5;
-       return apply_skip_ratio(list, count, skip_num, skip_denom);
+       return skip_away(list, count);
  }
  
  static void bisect_rev_setup(struct rev_info *revs, const char *prefix,
@@@ -780,7 -808,7 +808,7 @@@ static void handle_bad_merge_base(void
        exit(1);
  }
  
 -void handle_skipped_merge_base(const unsigned char *mb)
 +static void handle_skipped_merge_base(const unsigned char *mb)
  {
        char *mb_hex = sha1_to_hex(mb);
        char *bad_hex = sha1_to_hex(current_bad_sha1);