Skip to content

Commit

Permalink
mktree: add directory-file conflict hashmap
Browse files Browse the repository at this point in the history
Create a hashmap member of a 'struct tree_entry_array' that contains all of
the (de-duplicated) provided tree entries, indexed by the hash of their path
with *no* trailing slash. This hashmap will be used in a later commit to
avoid adding a file to an existing tree that has the same path as a
directory, or vice versa.

Signed-off-by: Victoria Dye <[email protected]>
  • Loading branch information
vdye committed Jun 19, 2024
1 parent 56f28ef commit 6f6d78a
Showing 1 changed file with 38 additions and 0 deletions.
38 changes: 38 additions & 0 deletions builtin/mktree.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include "object-store-ll.h"

struct tree_entry {
struct hashmap_entry ent;

/* Internal */
size_t order;

Expand All @@ -33,8 +35,33 @@ static inline size_t df_path_len(size_t pathlen, unsigned int mode)
struct tree_entry_array {
size_t nr, alloc;
struct tree_entry **entries;

struct hashmap df_name_hash;
};

static int df_name_hash_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
const void *keydata UNUSED)
{
const struct tree_entry *e1, *e2;
size_t e1_len, e2_len;

e1 = container_of(eptr, const struct tree_entry, ent);
e2 = container_of(entry_or_key, const struct tree_entry, ent);

e1_len = df_path_len(e1->len, e1->mode);
e2_len = df_path_len(e2->len, e2->mode);

return e1_len != e2_len ||
name_compare(e1->name, e1_len, e2->name, e2_len);
}

static void tree_entry_array_init(struct tree_entry_array *arr)
{
hashmap_init(&arr->df_name_hash, df_name_hash_cmp, NULL, 0);
}

static void tree_entry_array_push(struct tree_entry_array *arr, struct tree_entry *ent)
{
ALLOC_GROW(arr->entries, arr->nr + 1, arr->alloc);
Expand All @@ -48,6 +75,7 @@ static void tree_entry_array_clear(struct tree_entry_array *arr, int free_entrie
FREE_AND_NULL(arr->entries[i]);
}
arr->nr = 0;
hashmap_clear(&arr->df_name_hash);
}

static void tree_entry_array_release(struct tree_entry_array *arr, int free_entries)
Expand Down Expand Up @@ -137,6 +165,14 @@ static void sort_and_dedup_tree_entry_array(struct tree_entry_array *arr)
/* Sort again to order the entries for tree insertion */
ignore_mode = 0;
QSORT_S(arr->entries, arr->nr, ent_compare, &ignore_mode);

/* Finally, initialize the directory-file conflict hash map */
for (size_t i = 0; i < count; i++) {
struct tree_entry *curr = arr->entries[i];
hashmap_entry_init(&curr->ent,
memhash(curr->name, df_path_len(curr->len, curr->mode)));
hashmap_put(&arr->df_name_hash, &curr->ent);
}
}

struct tree_entry_iterator {
Expand Down Expand Up @@ -311,6 +347,8 @@ int cmd_mktree(int ac, const char **av, const char *prefix)

ac = parse_options(ac, av, prefix, option, mktree_usage, 0);

tree_entry_array_init(&arr);

do {
ret = read_index_info(nul_term_line, mktree_line, &mktree_line_data, &line);
if (ret < 0)
Expand Down

0 comments on commit 6f6d78a

Please sign in to comment.