From ede01a876d433af530c0e589c9d3ac17a93161bd Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Tue, 16 Feb 2021 14:16:31 +0100 Subject: Fixed hash API. --- docs/cmap_api.md | 8 +++++--- docs/cstr_api.md | 6 ++++-- examples/advanced.c | 2 +- stc/cmap.h | 4 ++-- stc/cstr.h | 20 ++++++++++---------- 5 files changed, 22 insertions(+), 18 deletions(-) diff --git a/docs/cmap_api.md b/docs/cmap_api.md index a9bc9b3a..471d8f58 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -87,8 +87,10 @@ cmap_X_mapped_t* cmap_X_itval(cmap_X_iter_t it); cmap_X_value_t cmap_X_value_clone(cmap_X_value_t val); void cmap_X_value_del(cmap_X_value_t* val); -uint32_t c_default_hash(const void *data, size_t len); -uint32_t c_default_hash32(const void* data, size_t len); + +uint64_t c_default_hash(const void *data, size_t len); +uint64_t c_default_hash32(const void* data, size_t ignored); +uint64_t c_default_hash64(const void* data, size_t ignored); ``` ## Types @@ -282,7 +284,7 @@ typedef struct VikingRaw { } VikingRaw; uint32_t vikingraw_hash(const VikingRaw* raw, size_t ignore) { - uint32_t hash = c_string_hash(raw->name) ^ (c_string_hash(raw->country) << 3); + uint32_t hash = c_strhash(raw->name) ^ (c_strhash(raw->country) << 3); return hash; } static inline int vikingraw_equals(const VikingRaw* rx, const VikingRaw* ry) { diff --git a/docs/cstr_api.md b/docs/cstr_api.md index d5e2f4b0..9703e4ff 100644 --- a/docs/cstr_api.md +++ b/docs/cstr_api.md @@ -96,11 +96,13 @@ Iterator methods, typically used via the general *c_foreach* macro. const char* cstr_to_raw(const cstr* x); int cstr_compare_raw(const char** x, const char** y); bool cstr_equals_raw(const char** x, const char** y); - uint32_t cstr_hash_raw(const char* const* spp, size_t ignored); + uint32_t cstr_hash_raw(const char* const* x, size_t ignored); + + char* c_strcopy(const char* src, char* dst, const char* dst_end, int termin); int c_strncasecmp(const char* s1, const char* s2, size_t n); char* c_strnfind(const char* str, const char* needle, size_t nmax); char* c_istrnfind(const char* str, const char* needle, size_t nmax); - uint32_t c_string_hash(const char* str); + uint32_t c_strhash(const char* str); ``` Helper methods, used by other container types. diff --git a/examples/advanced.c b/examples/advanced.c index a854b2bb..9b1b1275 100644 --- a/examples/advanced.c +++ b/examples/advanced.c @@ -21,7 +21,7 @@ typedef struct VikingRaw { } VikingRaw; uint64_t vikingraw_hash(const VikingRaw* raw, size_t ignore) { - uint64_t hash = c_default_hash(raw->name, strlen(raw->name)) ^ (c_default_hash(raw->country, strlen(raw->country)) >> 15); + uint64_t hash = c_strhash(raw->name) ^ (c_strhash(raw->country) >> 15); return hash; } static inline int vikingraw_equals(const VikingRaw* rx, const VikingRaw* ry) { diff --git a/stc/cmap.h b/stc/cmap.h index 45df0883..04445791 100644 --- a/stc/cmap.h +++ b/stc/cmap.h @@ -309,9 +309,9 @@ typedef struct {size_t idx; uint32_t hx;} chash_bucket_t; typedef C##_##X C##_##X##_t STC_API uint64_t c_default_hash(const void *data, size_t len); -STC_INLINE uint64_t c_default_hash32(const void* data, size_t len) +STC_INLINE uint64_t c_default_hash32(const void* data, size_t ignored) {return *(const uint32_t *)data * 2654435769u;} -STC_INLINE uint64_t c_default_hash64(const void* data, size_t len) +STC_INLINE uint64_t c_default_hash64(const void* data, size_t ignored) {return *(const uint64_t *)data * 11400714819323198485ull;} /* -------------------------- IMPLEMENTATION ------------------------- */ diff --git a/stc/cstr.h b/stc/cstr.h index 42c0648f..6131b2b0 100644 --- a/stc/cstr.h +++ b/stc/cstr.h @@ -49,10 +49,12 @@ STC_API size_t cstr_find(cstr_t s, const char* needle); STC_API size_t cstr_find_n(cstr_t s, const char* needle, size_t pos, size_t nlen); STC_API size_t cstr_ifind_n(cstr_t s, const char* needle, size_t pos, size_t nlen); -STC_API void* c_memccpy(void* dst, const void* src, int c, size_t n); +STC_API char* c_strcopy(const char* src, char* dst, const char* dst_end, int termin); STC_API int c_strncasecmp(const char* s1, const char* s2, size_t n); STC_API char* c_strnfind(const char* s, const char* needle, size_t nmax); STC_API char* c_istrnfind(const char* s, const char* needle, size_t nmax); +STC_INLINE +uint64_t c_strhash(const char* s) {return c_default_hash(s, strlen(s));} struct cstr_rep { size_t size, cap; char str[sizeof(size_t)]; }; #define _cstr_rep(self) c_container_of((self)->str, struct cstr_rep, str) @@ -218,7 +220,7 @@ cstr_iends_with(cstr_t s, const char* needle) { return n <= sz ? c_strncasecmp(s.str + sz - n, needle, n) == 0 : false; } -/* cvec/cmap API functions: */ +/* cvec/cmap adaption functions: */ #define cstr_to_raw(x) ((x)->str) #define cstr_compare_raw(x, y) strcmp(*(x), *(y)) #define cstr_equals_raw(x, y) (strcmp(*(x), *(y)) == 0) @@ -394,18 +396,16 @@ cstr_ifind_n(cstr_t s, const char* needle, size_t pos, size_t nlen) { } /* http://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord */ -STC_DEF void* -c_memccpy(void* dst, const void* src, int c, size_t n) { +STC_DEF char* +c_strcopy(const char* s, char* d, const char* d_end, int c) { enum {w = sizeof(uintptr_t)}; - #define _mc_z (~(uintptr_t)0/255) - const uint8_t* s = (const uint8_t *) src; - uint8_t *d = (uint8_t *) dst, *end = d + n; - for (uintptr_t x; d + w <= end; s += w, d += w) { + #define _sc_z (~(uintptr_t)0/255) + for (uintptr_t x; d + w <= d_end; s += w, d += w) { memcpy(&x, s, w); /* check if x contains c: */ - if (((x - _mc_z) & ~x & _mc_z*128) ^ (_mc_z*(uint8_t) c)) break; + if (((x - _sc_z) & ~x & _sc_z<<7) ^ (_sc_z*(uint8_t) c)) break; memcpy(d, &x, w); } - while (d < end) if ((*d++ = *s++) == (uint8_t) c) return d; + while (d < d_end) if ((*d++ = *s++) == (uint8_t) c) return d - 1; return NULL; } -- cgit v1.2.3