diff options
-rw-r--r-- | include/git2/odb.h | 35 | ||||
-rw-r--r-- | src/odb.c | 51 | ||||
-rw-r--r-- | tests/odb/mixed.c | 95 |
3 files changed, 89 insertions, 92 deletions
diff --git a/include/git2/odb.h b/include/git2/odb.h index 010b9c1a4..b3ed2706c 100644 --- a/include/git2/odb.h +++ b/include/git2/odb.h @@ -174,6 +174,27 @@ GIT_EXTERN(int) git_odb_exists_prefix( git_oid *out, git_odb *db, const git_oid *short_id, size_t len); /** + * The information about object IDs to query in `git_odb_expand_ids`, + * which will be populated upon return. + */ +typedef struct git_odb_expand_id { + /** The object ID to expand */ + git_oid id; + + /** + * The length of the object ID (in nibbles, or packets of 4 bits; the + * number of hex characters) + * */ + unsigned short length; + + /** + * The (optional) type of the object to search for; leave as `0` or set + * to `GIT_OBJ_ANY` to query for any object matching the ID. + */ + git_otype type; +} git_odb_expand_id; + +/** * Determine if one or more objects can be found in the object database * by their abbreviated object ID and type. The given array will be * updated in place: for each abbreviated ID that is unique in the @@ -187,20 +208,14 @@ GIT_EXTERN(int) git_odb_exists_prefix( * not found (which is unlike other object database operations.) * * @param db The database to be searched for the given objects. - * @param ids An array of object IDs to search for - * @param id_lengths The corresponding length of each entry in the `ids` - * array - * @param types The corresponding type of each entry in the `ids` array - * (or null to lookup an object of any type) - * @param cnt The length of the `ids`, `id_lengths` and `types` arrays + * @param ids An array of short object IDs to search for + * @param count The length of the `ids` array * @return 0 on success or an error code on failure */ GIT_EXTERN(int) git_odb_expand_ids( git_odb *db, - git_oid *ids, - size_t *id_lengths, - git_otype *types, - size_t cnt); + git_odb_expand_id *ids, + size_t count); /** * Refresh the object database to load newly added files. @@ -744,64 +744,51 @@ int git_odb_exists_prefix( int git_odb_expand_ids( git_odb *db, - git_oid *ids, - size_t *id_lengths, - git_otype *types, - size_t cnt) + git_odb_expand_id *ids, + size_t count) { size_t len, i; int error; - assert(db && ids && id_lengths); + assert(db && ids); - for (i = 0; i < cnt; i++) { + for (i = 0; i < count; i++) { + git_odb_expand_id *query = &ids[i]; git_oid *actual_id = NULL, tmp; + git_otype query_type = (query->type == GIT_OBJ_ANY) ? 0 : query->type; git_otype actual_type = 0; /* if we were given a full object ID, simply look it up */ - if (id_lengths[i] >= GIT_OID_HEXSZ) { - error = git_odb_read_header(&len, &actual_type, db, &ids[i]); + if (query->length >= GIT_OID_HEXSZ) { + error = git_odb_read_header(&len, &actual_type, db, &query->id); } /* otherwise, resolve the short id to full, then (optionally) * read the header. */ - else if (id_lengths[i] >= GIT_OID_MINPREFIXLEN) { + else if (query->length >= GIT_OID_MINPREFIXLEN) { error = odb_exists_prefix_1(&tmp, - db, &ids[i], id_lengths[i], false); + db, &query->id, query->length, false); if (!error) { actual_id = &tmp; - - if (types) - error = git_odb_read_header(&len, &actual_type, db, &tmp); - else - actual_type = GIT_OBJ_ANY; + error = git_odb_read_header(&len, &actual_type, db, &tmp); } } if (error < 0 && error != GIT_ENOTFOUND && error != GIT_EAMBIGUOUS) break; - error = 0; - - if (types && types[i] != GIT_OBJ_ANY && types[i] != actual_type) - actual_type = 0; - - if (!actual_type) { - memset(&ids[i], 0, sizeof(git_oid)); - id_lengths[i] = 0; - - if (types) - types[i] = 0; - } else { + if (error == 0 && (query_type == actual_type || !query_type)) { if (actual_id) - git_oid_cpy(&ids[i], actual_id); + git_oid_cpy(&query->id, actual_id); - id_lengths[i] = GIT_OID_HEXSZ; - - if (types) - types[i] = actual_type; + query->length = GIT_OID_HEXSZ; + query->type = actual_type; + } else { + memset(&query->id, 0, sizeof(git_oid)); + query->length = 0; + query->type = 0; } } diff --git a/tests/odb/mixed.c b/tests/odb/mixed.c index 57364e4e6..0e728b8fe 100644 --- a/tests/odb/mixed.c +++ b/tests/odb/mixed.c @@ -146,35 +146,31 @@ struct expand_id_test_data expand_id_test_data[] = { }; static void setup_prefix_query( - git_oid **out_ids, - size_t **out_lengths, - git_otype **out_types, + git_odb_expand_id **out_ids, size_t *out_num) { - git_oid *ids; - git_otype *types; - size_t num, *lengths, i; + git_odb_expand_id *ids; + size_t num, i; num = ARRAY_SIZE(expand_id_test_data); - cl_assert((ids = git__calloc(num, sizeof(git_oid)))); - cl_assert((lengths = git__calloc(num, sizeof(size_t)))); - cl_assert((types = git__calloc(num, sizeof(git_otype)))); + cl_assert((ids = git__calloc(num, sizeof(git_odb_expand_id)))); for (i = 0; i < num; i++) { - lengths[i] = strlen(expand_id_test_data[i].lookup_id); - git_oid_fromstrn(&ids[i], expand_id_test_data[i].lookup_id, lengths[i]); - types[i] = expand_id_test_data[i].expected_type; + git_odb_expand_id *id = &ids[i]; + + size_t len = strlen(expand_id_test_data[i].lookup_id); + + git_oid_fromstrn(&id->id, expand_id_test_data[i].lookup_id, len); + id->length = (unsigned short)len; + id->type = expand_id_test_data[i].expected_type; } *out_ids = ids; - *out_lengths = lengths; - *out_types = types; *out_num = num; } -static void assert_found_objects( - git_oid *ids, size_t *lengths, git_otype *types) +static void assert_found_objects(git_odb_expand_id *ids) { size_t num, i; @@ -191,16 +187,13 @@ static void assert_found_objects( expected_type = expand_id_test_data[i].expected_type; } - cl_assert_equal_i(expected_len, lengths[i]); - cl_assert_equal_oid(&expected_id, &ids[i]); - - if (types) - cl_assert_equal_i(expected_type, types[i]); + cl_assert_equal_oid(&expected_id, &ids[i].id); + cl_assert_equal_i(expected_len, ids[i].length); + cl_assert_equal_i(expected_type, ids[i].type); } } -static void assert_notfound_objects( - git_oid *ids, size_t *lengths, git_otype *types) +static void assert_notfound_objects(git_odb_expand_id *ids) { git_oid expected_id = {{0}}; size_t num, i; @@ -208,54 +201,56 @@ static void assert_notfound_objects( num = ARRAY_SIZE(expand_id_test_data); for (i = 0; i < num; i++) { - cl_assert_equal_i(0, lengths[i]); - cl_assert_equal_oid(&expected_id, &ids[i]); - - if (types) - cl_assert_equal_i(0, types[i]); + cl_assert_equal_oid(&expected_id, &ids[i].id); + cl_assert_equal_i(0, ids[i].length); + cl_assert_equal_i(0, ids[i].type); } } void test_odb_mixed__expand_ids(void) { - git_oid *ids; - size_t i, num, *lengths; - git_otype *types; + git_odb_expand_id *ids; + size_t i, num; /* test looking for the actual (correct) types */ - setup_prefix_query(&ids, &lengths, &types, &num); - cl_git_pass(git_odb_expand_ids(_odb, ids, lengths, types, num)); - assert_found_objects(ids, lengths, types); - git__free(ids); git__free(lengths); git__free(types); + setup_prefix_query(&ids, &num); + cl_git_pass(git_odb_expand_ids(_odb, ids, num)); + assert_found_objects(ids); + git__free(ids); + + /* test looking for an explicit `type == 0` */ - /* test looking for no specified types (types array == NULL) */ + setup_prefix_query(&ids, &num); + + for (i = 0; i < num; i++) + ids[i].type = 0; - setup_prefix_query(&ids, &lengths, &types, &num); - cl_git_pass(git_odb_expand_ids(_odb, ids, lengths, NULL, num)); - assert_found_objects(ids, lengths, NULL); - git__free(ids); git__free(lengths); git__free(types); + cl_git_pass(git_odb_expand_ids(_odb, ids, num)); + assert_found_objects(ids); + git__free(ids); /* test looking for an explicit GIT_OBJ_ANY */ - setup_prefix_query(&ids, &lengths, &types, &num); + setup_prefix_query(&ids, &num); for (i = 0; i < num; i++) - types[i] = GIT_OBJ_ANY; + ids[i].type = GIT_OBJ_ANY; - cl_git_pass(git_odb_expand_ids(_odb, ids, lengths, types, num)); - assert_found_objects(ids, lengths, types); - git__free(ids); git__free(lengths); git__free(types); + cl_git_pass(git_odb_expand_ids(_odb, ids, num)); + assert_found_objects(ids); + git__free(ids); /* test looking for the completely wrong type */ - setup_prefix_query(&ids, &lengths, &types, &num); + setup_prefix_query(&ids, &num); for (i = 0; i < num; i++) - types[i] = (types[i] == GIT_OBJ_BLOB) ? GIT_OBJ_TREE : GIT_OBJ_BLOB; + ids[i].type = (ids[i].type == GIT_OBJ_BLOB) ? + GIT_OBJ_TREE : GIT_OBJ_BLOB; - cl_git_pass(git_odb_expand_ids(_odb, ids, lengths, types, num)); - assert_notfound_objects(ids, lengths, types); - git__free(ids); git__free(lengths); git__free(types); + cl_git_pass(git_odb_expand_ids(_odb, ids, num)); + assert_notfound_objects(ids); + git__free(ids); } |