merge: use type safe oid-keyed hashmaps

This commit is contained in:
Edward Thomson
2024-09-29 18:15:48 +01:00
parent 9a7d920f73
commit c7294317ca

View File

@@ -32,7 +32,6 @@
#include "commit.h"
#include "oidarray.h"
#include "merge_driver.h"
#include "oidmap.h"
#include "array.h"
#include "git2/types.h"
@@ -1144,24 +1143,28 @@ typedef struct {
size_t first_entry;
} deletes_by_oid_queue;
static void deletes_by_oid_free(git_oidmap *map) {
GIT_HASHMAP_SETUP(git_merge_deletes_oidmap, const git_oid *, deletes_by_oid_queue *, git_oid_hash32, git_oid_equal);
static void deletes_by_oid_dispose(git_merge_deletes_oidmap *map)
{
git_hashmap_iter_t iter = GIT_HASHMAP_ITER_INIT;
deletes_by_oid_queue *queue;
if (!map)
return;
git_oidmap_foreach_value(map, queue, {
while (git_merge_deletes_oidmap_iterate(&iter, NULL, &queue, map) == 0)
git_array_clear(queue->arr);
});
git_oidmap_free(map);
git_merge_deletes_oidmap_dispose(map);
}
static int deletes_by_oid_enqueue(git_oidmap *map, git_pool *pool, const git_oid *id, size_t idx)
static int deletes_by_oid_enqueue(git_merge_deletes_oidmap *map, git_pool *pool, const git_oid *id, size_t idx)
{
deletes_by_oid_queue *queue;
size_t *array_entry;
if ((queue = git_oidmap_get(map, id)) == NULL) {
if (git_merge_deletes_oidmap_get(&queue, map, id) != 0) {
queue = git_pool_malloc(pool, sizeof(deletes_by_oid_queue));
GIT_ERROR_CHECK_ALLOC(queue);
@@ -1169,7 +1172,7 @@ static int deletes_by_oid_enqueue(git_oidmap *map, git_pool *pool, const git_oid
queue->next_pos = 0;
queue->first_entry = idx;
if (git_oidmap_set(map, id, queue) < 0)
if (git_merge_deletes_oidmap_put(map, id, queue) < 0)
return -1;
} else {
array_entry = git_array_alloc(queue->arr);
@@ -1180,13 +1183,14 @@ static int deletes_by_oid_enqueue(git_oidmap *map, git_pool *pool, const git_oid
return 0;
}
static int deletes_by_oid_dequeue(size_t *idx, git_oidmap *map, const git_oid *id)
static int deletes_by_oid_dequeue(size_t *idx, git_merge_deletes_oidmap *map, const git_oid *id)
{
deletes_by_oid_queue *queue;
size_t *array_entry;
int error;
if ((queue = git_oidmap_get(map, id)) == NULL)
return GIT_ENOTFOUND;
if ((error = git_merge_deletes_oidmap_get(&queue, map, id)) != 0)
return error;
if (queue->next_pos == 0) {
*idx = queue->first_entry;
@@ -1209,15 +1213,10 @@ static int merge_diff_mark_similarity_exact(
{
size_t i, j;
git_merge_diff *conflict_src, *conflict_tgt;
git_oidmap *ours_deletes_by_oid = NULL, *theirs_deletes_by_oid = NULL;
git_merge_deletes_oidmap ours_deletes_by_oid = GIT_HASHMAP_INIT,
theirs_deletes_by_oid = GIT_HASHMAP_INIT;
int error = 0;
if (git_oidmap_new(&ours_deletes_by_oid) < 0 ||
git_oidmap_new(&theirs_deletes_by_oid) < 0) {
error = -1;
goto done;
}
/* Build a map of object ids to conflicts */
git_vector_foreach(&diff_list->conflicts, i, conflict_src) {
/* Items can be the source of a rename iff they have an item in the
@@ -1233,13 +1232,13 @@ static int merge_diff_mark_similarity_exact(
continue;
if (!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_src->our_entry)) {
error = deletes_by_oid_enqueue(ours_deletes_by_oid, &diff_list->pool, &conflict_src->ancestor_entry.id, i);
error = deletes_by_oid_enqueue(&ours_deletes_by_oid, &diff_list->pool, &conflict_src->ancestor_entry.id, i);
if (error < 0)
goto done;
}
if (!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_src->their_entry)) {
error = deletes_by_oid_enqueue(theirs_deletes_by_oid, &diff_list->pool, &conflict_src->ancestor_entry.id, i);
error = deletes_by_oid_enqueue(&theirs_deletes_by_oid, &diff_list->pool, &conflict_src->ancestor_entry.id, i);
if (error < 0)
goto done;
}
@@ -1250,7 +1249,7 @@ static int merge_diff_mark_similarity_exact(
continue;
if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_tgt->our_entry)) {
if (deletes_by_oid_dequeue(&i, ours_deletes_by_oid, &conflict_tgt->our_entry.id) == 0) {
if (deletes_by_oid_dequeue(&i, &ours_deletes_by_oid, &conflict_tgt->our_entry.id) == 0) {
similarity_ours[i].similarity = 100;
similarity_ours[i].other_idx = j;
@@ -1260,7 +1259,7 @@ static int merge_diff_mark_similarity_exact(
}
if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_tgt->their_entry)) {
if (deletes_by_oid_dequeue(&i, theirs_deletes_by_oid, &conflict_tgt->their_entry.id) == 0) {
if (deletes_by_oid_dequeue(&i, &theirs_deletes_by_oid, &conflict_tgt->their_entry.id) == 0) {
similarity_theirs[i].similarity = 100;
similarity_theirs[i].other_idx = j;
@@ -1271,8 +1270,8 @@ static int merge_diff_mark_similarity_exact(
}
done:
deletes_by_oid_free(ours_deletes_by_oid);
deletes_by_oid_free(theirs_deletes_by_oid);
deletes_by_oid_dispose(&ours_deletes_by_oid);
deletes_by_oid_dispose(&theirs_deletes_by_oid);
return error;
}