Skip to content

Commit

Permalink
The always-inline symbols should be weak too.
Browse files Browse the repository at this point in the history
  • Loading branch information
sheredom committed Mar 19, 2023
1 parent c7a642f commit 9744b1a
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 21 deletions.
46 changes: 25 additions & 21 deletions hashmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,16 +275,6 @@ HASHMAP_ALWAYS_INLINE hashmap_uint32_t hashmap_clz(const hashmap_uint32_t x);
#define HASHMAP_NULL 0
#endif

hashmap_uint32_t hashmap_clz(const hashmap_uint32_t x) {
#if defined(_MSC_VER)
unsigned long result;
_BitScanReverse(&result, x);
return 31 - HASHMAP_CAST(hashmap_uint32_t, result);
#else
return HASHMAP_CAST(hashmap_uint32_t, __builtin_clz(x));
#endif
}

int hashmap_create(const hashmap_uint32_t initial_capacity,
struct hashmap_s *const out_hashmap) {
struct hashmap_create_options_s options;
Expand Down Expand Up @@ -480,11 +470,13 @@ void hashmap_destroy(struct hashmap_s *const m) {
memset(m, 0, sizeof(struct hashmap_s));
}

hashmap_uint32_t hashmap_num_entries(const struct hashmap_s *const m) {
HASHMAP_ALWAYS_INLINE hashmap_uint32_t
hashmap_num_entries(const struct hashmap_s *const m) {
return m->size;
}

hashmap_uint32_t hashmap_capacity(const struct hashmap_s *const m) {
HASHMAP_ALWAYS_INLINE hashmap_uint32_t
hashmap_capacity(const struct hashmap_s *const m) {
return 1u << m->log2_capacity;
}

Expand Down Expand Up @@ -590,20 +582,22 @@ hashmap_uint32_t hashmap_crc32_hasher(const hashmap_uint32_t seed,
return crc32val;
}

hashmap_uint32_t hashmap_hash_helper_int_helper(const struct hashmap_s *const m,
const void *const k,
const hashmap_uint32_t l) {
HASHMAP_ALWAYS_INLINE hashmap_uint32_t
hashmap_hash_helper_int_helper(const struct hashmap_s *const m,
const void *const k, const hashmap_uint32_t l) {
return (m->hasher(~0u, k, l) * 2654435769u) >> (32u - m->log2_capacity);
}

int hashmap_match_helper(const struct hashmap_element_s *const element,
const void *const key, const hashmap_uint32_t len) {
HASHMAP_ALWAYS_INLINE int
hashmap_match_helper(const struct hashmap_element_s *const element,
const void *const key, const hashmap_uint32_t len) {
return (element->key_len == len) && (0 == memcmp(element->key, key, len));
}

int hashmap_hash_helper(const struct hashmap_s *const m, const void *const key,
const hashmap_uint32_t len,
hashmap_uint32_t *const out_index) {
HASHMAP_ALWAYS_INLINE int
hashmap_hash_helper(const struct hashmap_s *const m, const void *const key,
const hashmap_uint32_t len,
hashmap_uint32_t *const out_index) {
hashmap_uint32_t curr;
hashmap_uint32_t i;
hashmap_uint32_t first_free;
Expand Down Expand Up @@ -653,7 +647,7 @@ int hashmap_rehash_iterator(void *const new_hash,
/*
* Doubles the size of the hashmap, and rehashes all the elements
*/
int hashmap_rehash_helper(struct hashmap_s *const m) {
HASHMAP_ALWAYS_INLINE int hashmap_rehash_helper(struct hashmap_s *const m) {
struct hashmap_create_options_s options;
struct hashmap_s new_m;
int flag;
Expand Down Expand Up @@ -688,6 +682,16 @@ int hashmap_rehash_helper(struct hashmap_s *const m) {
return 0;
}

HASHMAP_ALWAYS_INLINE hashmap_uint32_t hashmap_clz(const hashmap_uint32_t x) {
#if defined(_MSC_VER)
unsigned long result;
_BitScanReverse(&result, x);
return 31 - HASHMAP_CAST(hashmap_uint32_t, result);
#else
return HASHMAP_CAST(hashmap_uint32_t, __builtin_clz(x));
#endif
}

#if defined(_MSC_VER)
#pragma warning(pop)
#endif
Expand Down
46 changes: 46 additions & 0 deletions test/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,51 @@
// For more information, please refer to <http://unlicense.org/>

#include "utest.h"
#include "hashmap.h"

UTEST_MAIN()

UTEST(main, one_byte) {
unsigned char data[256];
int i;
struct hashmap_s hashmap;

for (i = 0; i < 256; i++) {
data[i] = (unsigned char)i;
}

ASSERT_EQ(0, hashmap_create(1, &hashmap));

for (i = 0; i < 256; i++) {
ASSERT_EQ(0, hashmap_put(&hashmap, &data[i], 1, NULL));
}

ASSERT_EQ(hashmap_num_entries(&hashmap), 256u);
ASSERT_LE(hashmap_capacity(&hashmap), 2048u);

hashmap_destroy(&hashmap);
}

UTEST(main, two_bytes) {
unsigned short *data;
int i;
struct hashmap_s hashmap;

data = (unsigned short *)malloc(sizeof(unsigned short) * 16384);

for (i = 0; i < 16384; i++) {
data[i] = (unsigned short)i;
}

ASSERT_EQ(0, hashmap_create(1, &hashmap));

for (i = 0; i < 16384; i++) {
ASSERT_EQ(0, hashmap_put(&hashmap, &data[i], 2, NULL));
}

ASSERT_EQ(hashmap_num_entries(&hashmap), 16384u);
ASSERT_LE(hashmap_capacity(&hashmap), 65536u);

hashmap_destroy(&hashmap);
free(data);
}

0 comments on commit 9744b1a

Please sign in to comment.