static void kGitOidShorten_free(CTX ctx, kRawPtr *po) { if (po->rawptr != NULL) { git_oid_shorten_free((git_oid_shorten *)po->rawptr); po->rawptr = NULL; } }
void test_object_raw_short__oid_shortener_no_duplicates(void) { git_oid_shorten *os; int min_len; os = git_oid_shorten_new(0); cl_assert(os != NULL); git_oid_shorten_add(os, "22596363b3de40b06f981fb85d82312e8c0ed511"); git_oid_shorten_add(os, "ce08fe4884650f067bd5703b6a59a8b3b3c99a09"); git_oid_shorten_add(os, "16a0123456789abcdef4b775213c23a8bd74f5e0"); min_len = git_oid_shorten_add(os, "ce08fe4884650f067bd5703b6a59a8b3b3c99a09"); cl_assert(min_len == GIT_OID_HEXSZ + 1); git_oid_shorten_free(os); }
/* * call-seq: * Rugged.minimize_oid(oid_iterator, min_length = 7) { |short_oid| block } * Rugged.minimize_oid(oid_iterator, min_length = 7) -> min_length * * Iterate through +oid_iterator+, which should yield any number of SHA1 OIDs * (represented as 40-character hexadecimal strings), and tries to minify them. * * Minifying a set of a SHA1 strings means finding the shortest root substring * for each string that uniquely identifies it. * * If no +block+ is given, the function will return the minimal length as an * integer value: * * oids = [ * 'd8786bfc974aaaaaaaaaaaaaaaaaaaaaaaaaaaaa', * 'd8786bfc974bbbbbbbbbbbbbbbbbbbbbbbbbbbbb', * 'd8786bfc974ccccccccccccccccccccccccccccc', * '68d041ee999cb07c6496fbdd4f384095de6ca9e1', * ] * * Rugged.minimize_oids(oids) #=> 12 * * If a +block+ is given, it will be called with each OID from +iterator+ * in its minified form: * * Rugged.minimize_oid(oids) { |oid| puts oid } * * produces: * * d8786bfc974a * d8786bfc974b * d8786bfc974c * 68d041ee999c * * The optional +min_length+ argument allows you to specify a lower bound for * the minified strings; returned strings won't be shorter than the given value, * even if they would still be uniquely represented. * * Rugged.minimize_oid(oids, 18) #=> 18 */ static VALUE rb_git_minimize_oid(int argc, VALUE *argv, VALUE self) { git_oid_shorten *shrt; int length, minlen = 7; VALUE rb_enum, rb_minlen, rb_block; rb_scan_args(argc, argv, "11&", &rb_enum, &rb_minlen, &rb_block); if (!NIL_P(rb_minlen)) { Check_Type(rb_minlen, T_FIXNUM); minlen = FIX2INT(rb_minlen); } if (!rb_respond_to(rb_enum, rb_intern("each"))) rb_raise(rb_eTypeError, "Expecting an Enumerable instance"); shrt = git_oid_shorten_new(minlen); rb_iterate(rb_each, rb_enum, &minimize_cb, (VALUE)shrt); length = git_oid_shorten_add(shrt, NULL); git_oid_shorten_free(shrt); rugged_exception_check(length); if (!NIL_P(rb_block)) { VALUE yield_data[2]; yield_data[0] = rb_block; yield_data[1] = INT2FIX(length); rb_iterate(rb_each, rb_enum, &minimize_yield, (VALUE)yield_data); return Qnil; } return INT2FIX(length); }
void test_object_raw_short__oid_shortener_stresstest_git_oid_shorten(void) { #define MAX_OIDS 1000 git_oid_shorten *os; char *oids[MAX_OIDS]; char number_buffer[16]; git_oid oid; size_t i, j; int min_len = 0, found_collision; os = git_oid_shorten_new(0); cl_assert(os != NULL); /* * Insert in the shortener 1000 unique SHA1 ids */ for (i = 0; i < MAX_OIDS; ++i) { char *oid_text; sprintf(number_buffer, "%u", (unsigned int)i); git_hash_buf(&oid, number_buffer, strlen(number_buffer)); oid_text = git__malloc(GIT_OID_HEXSZ + 1); git_oid_fmt(oid_text, &oid); oid_text[GIT_OID_HEXSZ] = 0; min_len = git_oid_shorten_add(os, oid_text); cl_assert(min_len >= 0); oids[i] = oid_text; } /* * Compare the first `min_char - 1` characters of each * SHA1 OID. If the minimizer worked, we should find at * least one collision */ found_collision = 0; for (i = 0; i < MAX_OIDS; ++i) { for (j = 0; j < MAX_OIDS; ++j) { if (i != j && memcmp(oids[i], oids[j], min_len - 1) == 0) found_collision = 1; } } cl_assert(found_collision == 1); /* * Compare the first `min_char` characters of each * SHA1 OID. If the minimizer worked, every single preffix * should be unique. */ found_collision = 0; for (i = 0; i < MAX_OIDS; ++i) { for (j = 0; j < MAX_OIDS; ++j) { if (i != j && memcmp(oids[i], oids[j], min_len) == 0) found_collision = 1; } } cl_assert(found_collision == 0); /* cleanup */ for (i = 0; i < MAX_OIDS; ++i) git__free(oids[i]); git_oid_shorten_free(os); #undef MAX_OIDS }