diff --git a/src/include/khash.h b/src/include/khash.h index 823757bf1..80711c3d6 100644 --- a/src/include/khash.h +++ b/src/include/khash.h @@ -217,6 +217,22 @@ static const double __ac_HASH_UPPER = 0.77; h->size = h->n_occupied = 0; \ } \ } \ + SCOPE khint_t kh_hash_##name(khkey_t key) { \ + return __hash_func(key); \ + } \ + SCOPE khint_t kh_get_##name##_with_hash(const kh_##name##_t *h, khkey_t key, khint_t hash) { \ + if (h->n_buckets) { \ + khint_t k = hash, i, last, mask, step = 0; \ + mask = h->n_buckets - 1; \ + i = k & mask; \ + last = i; \ + while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \ + i = (i + (++step)) & mask; \ + if (i == last) return h->n_buckets; \ + } \ + return __ac_iseither(h->flags, i)? h->n_buckets : i; \ + } else return 0; \ + } \ SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \ { \ if (h->n_buckets) { \ @@ -462,6 +478,24 @@ static kh_inline khint_t __ac_Wang_hash(khint_t key) */ #define kh_put(name, h, k, r) kh_put_##name(h, k, r) +/*! @function + @abstract Hash a key. + @param name Name of the hash table [symbol] + @param key Key [type of keys] + @return Hash value [khint_t] + */ +#define kh_hash(name, key) kh_hash_##name(key) + +/*! @function + @abstract Retrieve a key from the hash table with a given hash value. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param k Key [type of keys] + @param hash Hash value [khint_t] + @return Iterator to the found element, or kh_end(h) if the element is absent [khint_t] + */ +#define kh_get_with_hash(name, h, k, hash) kh_get_##name##_with_hash(h, k, hash) + /*! @function @abstract Retrieve a key from the hash table. @param name Name of the hash table [symbol] diff --git a/src/librarian/library.c b/src/librarian/library.c index e21e648cc..34bb0b79d 100644 --- a/src/librarian/library.c +++ b/src/librarian/library.c @@ -836,9 +836,10 @@ static int getSymbolInDataMaps(library_t*lib, const char* name, int noweak, uint } static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size, int* weak) { + const khint_t hash = kh_hash(symbolmap, name); void* symbol; // check in mysymbolmap - khint_t k = kh_get(symbolmap, lib->w.mysymbolmap, name); + khint_t k = kh_get_with_hash(symbolmap, lib->w.mysymbolmap, name, hash); if (k!=kh_end(lib->w.mysymbolmap)) { symbol1_t *s = &kh_value(lib->w.mysymbolmap, k); if(!s->resolved) { @@ -866,7 +867,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui return 1; } // check in stsymbolmap (return struct...) - k = kh_get(symbolmap, lib->w.stsymbolmap, name); + k = kh_get_with_hash(symbolmap, lib->w.stsymbolmap, name, hash); if (k!=kh_end(lib->w.stsymbolmap)) { symbol1_t *s = &kh_value(lib->w.stsymbolmap, k); if(!s->resolved) { @@ -894,7 +895,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui return 1; } // check in symbolmap - k = kh_get(symbolmap, lib->w.symbolmap, name); + k = kh_get_with_hash(symbolmap, lib->w.symbolmap, name, hash); if (k!=kh_end(lib->w.symbolmap)) { symbol1_t *s = &kh_value(lib->w.symbolmap, k); if(!s->resolved) { @@ -931,7 +932,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui } if(!noweak) { // check in wmysymbolmap - khint_t k = kh_get(symbolmap, lib->w.wmysymbolmap, name); + khint_t k = kh_get_with_hash(symbolmap, lib->w.wmysymbolmap, name, hash); if (k!=kh_end(lib->w.wmysymbolmap)) { symbol1_t *s = &kh_value(lib->w.wmysymbolmap, k); if(!s->resolved) { @@ -958,7 +959,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui *weak = 1; return 1; } - k = kh_get(symbolmap, lib->w.wsymbolmap, name); + k = kh_get_with_hash(symbolmap, lib->w.wsymbolmap, name, hash); if (k!=kh_end(lib->w.wsymbolmap)) { symbol1_t *s = &kh_value(lib->w.wsymbolmap, k); if(!s->resolved) { @@ -995,7 +996,9 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui } } // check in symbol2map - k = kh_get(symbol2map, lib->w.symbol2map, name); + // + // NOTE: symbol2map & symbolmap share the same hash function, so we can use the same hash + k = kh_get_with_hash(symbol2map, lib->w.symbol2map, name, hash); if (k!=kh_end(lib->w.symbol2map)) { symbol2_t *s = &kh_value(lib->w.symbol2map, k); if(!noweak || !s->weak)