summaryrefslogtreecommitdiff
path: root/name-hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'name-hash.c')
-rw-r--r--name-hash.c79
1 files changed, 41 insertions, 38 deletions
diff --git a/name-hash.c b/name-hash.c
index 0e10f3eab8..623ca6923a 100644
--- a/name-hash.c
+++ b/name-hash.c
@@ -7,6 +7,7 @@
*/
#define NO_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
+#include "thread-utils.h"
struct dir_entry {
struct hashmap_entry ent;
@@ -17,10 +18,14 @@ struct dir_entry {
};
static int dir_entry_cmp(const void *unused_cmp_data,
- const struct dir_entry *e1,
- const struct dir_entry *e2,
- const char *name)
+ const void *entry,
+ const void *entry_or_key,
+ const void *keydata)
{
+ const struct dir_entry *e1 = entry;
+ const struct dir_entry *e2 = entry_or_key;
+ const char *name = keydata;
+
return e1->namelen != e2->namelen || strncasecmp(e1->name,
name ? name : e2->name, e1->namelen);
}
@@ -110,10 +115,12 @@ static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)
}
static int cache_entry_cmp(const void *unused_cmp_data,
- const struct cache_entry *ce1,
- const struct cache_entry *ce2,
+ const void *entry,
+ const void *entry_or_key,
const void *remove)
{
+ const struct cache_entry *ce1 = entry;
+ const struct cache_entry *ce2 = entry_or_key;
/*
* For remove_name_hash, find the exact entry (pointer equality); for
* index_file_exists, find all entries with matching hash code and
@@ -125,22 +132,6 @@ static int cache_entry_cmp(const void *unused_cmp_data,
static int lazy_try_threaded = 1;
static int lazy_nr_dir_threads;
-#ifdef NO_PTHREADS
-
-static inline int lookup_lazy_params(struct index_state *istate)
-{
- return 0;
-}
-
-static inline void threaded_lazy_init_name_hash(
- struct index_state *istate)
-{
-}
-
-#else
-
-#include "thread-utils.h"
-
/*
* Set a minimum number of cache_entries that we will handle per
* thread and use that to decide how many threads to run (upto
@@ -503,6 +494,7 @@ static inline void lazy_update_dir_ref_counts(
static void threaded_lazy_init_name_hash(
struct index_state *istate)
{
+ int err;
int nr_each;
int k_start;
int t;
@@ -510,6 +502,9 @@ static void threaded_lazy_init_name_hash(
struct lazy_dir_thread_data *td_dir;
struct lazy_name_thread_data *td_name;
+ if (!HAVE_THREADS)
+ return;
+
k_start = 0;
nr_each = DIV_ROUND_UP(istate->cache_nr, lazy_nr_dir_threads);
@@ -532,8 +527,9 @@ static void threaded_lazy_init_name_hash(
if (k_start > istate->cache_nr)
k_start = istate->cache_nr;
td_dir_t->k_end = k_start;
- if (pthread_create(&td_dir_t->pthread, NULL, lazy_dir_thread_proc, td_dir_t))
- die("unable to create lazy_dir_thread");
+ err = pthread_create(&td_dir_t->pthread, NULL, lazy_dir_thread_proc, td_dir_t);
+ if (err)
+ die(_("unable to create lazy_dir thread: %s"), strerror(err));
}
for (t = 0; t < lazy_nr_dir_threads; t++) {
struct lazy_dir_thread_data *td_dir_t = td_dir + t;
@@ -553,13 +549,15 @@ static void threaded_lazy_init_name_hash(
*/
td_name->istate = istate;
td_name->lazy_entries = lazy_entries;
- if (pthread_create(&td_name->pthread, NULL, lazy_name_thread_proc, td_name))
- die("unable to create lazy_name_thread");
+ err = pthread_create(&td_name->pthread, NULL, lazy_name_thread_proc, td_name);
+ if (err)
+ die(_("unable to create lazy_name thread: %s"), strerror(err));
lazy_update_dir_ref_counts(istate, lazy_entries);
- if (pthread_join(td_name->pthread, NULL))
- die("unable to join lazy_name_thread");
+ err = pthread_join(td_name->pthread, NULL);
+ if (err)
+ die(_("unable to join lazy_name thread: %s"), strerror(err));
cleanup_dir_mutex();
@@ -568,21 +566,25 @@ static void threaded_lazy_init_name_hash(
free(lazy_entries);
}
-#endif
-
static void lazy_init_name_hash(struct index_state *istate)
{
+
if (istate->name_hash_initialized)
return;
- hashmap_init(&istate->name_hash, (hashmap_cmp_fn) cache_entry_cmp,
- NULL, istate->cache_nr);
- hashmap_init(&istate->dir_hash, (hashmap_cmp_fn) dir_entry_cmp,
- NULL, istate->cache_nr);
+ trace_performance_enter();
+ hashmap_init(&istate->name_hash, cache_entry_cmp, NULL, istate->cache_nr);
+ hashmap_init(&istate->dir_hash, dir_entry_cmp, NULL, istate->cache_nr);
if (lookup_lazy_params(istate)) {
- hashmap_disallow_rehash(&istate->dir_hash, 1);
+ /*
+ * Disable item counting and automatic rehashing because
+ * we do per-chain (mod n) locking rather than whole hashmap
+ * locking and we need to prevent the table-size from changing
+ * and bucket items from being redistributed.
+ */
+ hashmap_disable_item_counting(&istate->dir_hash);
threaded_lazy_init_name_hash(istate);
- hashmap_disallow_rehash(&istate->dir_hash, 0);
+ hashmap_enable_item_counting(&istate->dir_hash);
} else {
int nr;
for (nr = 0; nr < istate->cache_nr; nr++)
@@ -590,6 +592,7 @@ static void lazy_init_name_hash(struct index_state *istate)
}
istate->name_hash_initialized = 1;
+ trace_performance_leave("initialize name hash");
}
/*
@@ -686,12 +689,12 @@ void adjust_dirname_case(struct index_state *istate, char *name)
if (*ptr == '/') {
struct dir_entry *dir;
- ptr++;
- dir = find_dir_entry(istate, name, ptr - name + 1);
+ dir = find_dir_entry(istate, name, ptr - name);
if (dir) {
memcpy((void *)startPtr, dir->name + (startPtr - name), ptr - startPtr);
- startPtr = ptr;
+ startPtr = ptr + 1;
}
+ ptr++;
}
}
}