summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2022-11-03 13:28:45 +0100
committerTyge Løvset <[email protected]>2022-11-03 13:28:45 +0100
commitd1d8a9f389155c223db92d060b8fbccda58e2e53 (patch)
tree718fac6edbf34056c188fadfec63f9c15514a32c
parenta913e030b5db2e0d0a49234a86fa39930b4ed6e9 (diff)
downloadSTC-modified-d1d8a9f389155c223db92d060b8fbccda58e2e53.tar.gz
STC-modified-d1d8a9f389155c223db92d060b8fbccda58e2e53.zip
Made cmap i_max_load_factor a compile time template parameter instead of runtime. Enables cmap to be NULL initialized. Currently only cvec/cdeq and csmap cannot be NULL initialized, but eventually they will.
-rw-r--r--benchmarks/misc/rust_cmap.c2
-rw-r--r--benchmarks/picobench/picobench_cmap.cpp8
-rw-r--r--benchmarks/shootout_hashmaps.cpp4
-rw-r--r--docs/cmap_api.md2
-rw-r--r--docs/cset_api.md2
-rw-r--r--include/stc/cmap.h18
-rw-r--r--include/stc/forward.h1
7 files changed, 18 insertions, 19 deletions
diff --git a/benchmarks/misc/rust_cmap.c b/benchmarks/misc/rust_cmap.c
index 0750b182..83b7dd19 100644
--- a/benchmarks/misc/rust_cmap.c
+++ b/benchmarks/misc/rust_cmap.c
@@ -3,6 +3,7 @@
#define i_key uint64_t
#define i_val uint64_t
#define i_tag u64
+#define i_max_load_factor 0.8f
#include <stc/cmap.h>
uint64_t romu_rotl(uint64_t val, uint32_t r) {
@@ -27,7 +28,6 @@ int main()
const size_t n = 50000000,
mask = (1 << 25) - 1,
ms = CLOCKS_PER_SEC/1000;
- cmap_u64_max_load_factor(&m, 0.8);
cmap_u64_reserve(&m, n);
printf("STC cmap n = %" c_ZU ", mask = 0x%" PRIxMAX "\n", n, mask);
diff --git a/benchmarks/picobench/picobench_cmap.cpp b/benchmarks/picobench/picobench_cmap.cpp
index 7d114d30..3ffba5b9 100644
--- a/benchmarks/picobench/picobench_cmap.cpp
+++ b/benchmarks/picobench/picobench_cmap.cpp
@@ -33,15 +33,18 @@ DEFMAP(map_s, <std::string, std::string>);
#define i_key int32_t
#define i_val int32_t
#define i_tag i
+#define i_max_load_factor float(MaxLoadFactor100) / 100.0f
#include <stc/cmap.h>
#define i_key uint64_t
#define i_val uint64_t
#define i_tag x
+#define i_max_load_factor float(MaxLoadFactor100) / 100.0f
#include <stc/cmap.h>
#define i_key_str
#define i_val_str
+#define i_max_load_factor float(MaxLoadFactor100) / 100.0f
#include <stc/cmap.h>
PICOBENCH_SUITE("Map1");
@@ -69,7 +72,6 @@ static void ins_and_erase_i(picobench::state& s)
static void ins_and_erase_cmap_i(picobench::state& s)
{
cmap_i map = cmap_i_init();
- cmap_i_max_load_factor(&map, (int)MaxLoadFactor100 / 100.0);
csrandom(seed);
picobench::scope scope(s);
@@ -89,7 +91,6 @@ static void ins_and_erase_cmap_i(picobench::state& s)
static void ins_and_erase_cmap_x(picobench::state& s)
{
cmap_x map = cmap_x_init();
- cmap_x_max_load_factor(&map, (int)MaxLoadFactor100 / 100.0);
csrandom(seed);
picobench::scope scope(s);
@@ -136,7 +137,6 @@ static void ins_and_access_cmap_i(picobench::state& s)
uint64_t mask = (1ull << s.arg()) - 1;
size_t result = 0;
cmap_i map = cmap_i_init();
- cmap_i_max_load_factor(&map, (int)MaxLoadFactor100 / 100.0);
csrandom(seed);
picobench::scope scope(s);
@@ -189,7 +189,6 @@ static void ins_and_access_cmap_s(picobench::state& s)
char* buf = cstr_data(&str);
size_t result = 0;
cmap_str map = cmap_str_init();
- cmap_str_max_load_factor(&map, (int)MaxLoadFactor100 / 100.0);
csrandom(seed);
picobench::scope scope(s);
@@ -249,7 +248,6 @@ static void iterate_x(picobench::state& s)
static void iterate_cmap_x(picobench::state& s)
{
cmap_x map = cmap_x_init();
- cmap_x_max_load_factor(&map, (int)MaxLoadFactor100 / 100.0);
uint64_t K = (1ull << s.arg()) - 1;
picobench::scope scope(s);
diff --git a/benchmarks/shootout_hashmaps.cpp b/benchmarks/shootout_hashmaps.cpp
index d662ed60..d29149e2 100644
--- a/benchmarks/shootout_hashmaps.cpp
+++ b/benchmarks/shootout_hashmaps.cpp
@@ -36,13 +36,13 @@ KHASH_MAP_INIT_INT64(ii, IValue)
#define i_val IValue
#define i_size uint32_t // optional, enables 2x expand
#define i_tag ii
+#define i_max_load_factor MAX_LOAD_FACTOR / 100.0f
#include <stc/cmap.h>
#define SEED(s) rng = stc64_new(s)
#define RAND(N) (stc64_rand(&rng) & (((uint64_t)1 << N) - 1))
-#define CMAP_SETUP(X, Key, Value) cmap_##X map = cmap_##X##_init(); \
- cmap_##X##_max_load_factor(&map, MAX_LOAD_FACTOR/100.0f)
+#define CMAP_SETUP(X, Key, Value) cmap_##X map = cmap_##X##_init()
#define CMAP_PUT(X, key, val) cmap_##X##_insert_or_assign(&map, key, val).ref->second
#define CMAP_EMPLACE(X, key, val) cmap_##X##_insert(&map, key, val).ref->second
#define CMAP_ERASE(X, key) cmap_##X##_erase(&map, key)
diff --git a/docs/cmap_api.md b/docs/cmap_api.md
index 4b6ca4bc..802bfa00 100644
--- a/docs/cmap_api.md
+++ b/docs/cmap_api.md
@@ -51,7 +51,7 @@ cmap_X cmap_X_clone(cmap_x map);
void cmap_X_clear(cmap_X* self);
void cmap_X_copy(cmap_X* self, const cmap_X* other);
-void cmap_X_max_load_factor(cmap_X* self, float max_load); // default: 0.85
+float cmap_X_max_load_factor(const cmap_X* self); // default: 0.85f
bool cmap_X_reserve(cmap_X* self, size_t size);
void cmap_X_shrink_to_fit(cmap_X* self);
void cmap_X_swap(cmap_X* a, cmap_X* b);
diff --git a/docs/cset_api.md b/docs/cset_api.md
index b2e7d0c8..07eada22 100644
--- a/docs/cset_api.md
+++ b/docs/cset_api.md
@@ -29,7 +29,7 @@ cset_X cset_X_clone(cset_x set);
void cset_X_clear(cset_X* self);
void cset_X_copy(cset_X* self, const cset_X* other);
-void cset_X_max_load_factor(cset_X* self, float max_load); // default: 0.85
+float cset_X_max_load_factor(const cset_X* self); // default: 0.85
bool cset_X_reserve(cset_X* self, size_t size);
void cset_X_shrink_to_fit(cset_X* self);
void cset_X_swap(cset_X* a, cset_X* b);
diff --git a/include/stc/cmap.h b/include/stc/cmap.h
index 908466d2..95dfadae 100644
--- a/include/stc/cmap.h
+++ b/include/stc/cmap.h
@@ -53,7 +53,6 @@ int main(void) {
#include "forward.h"
#include <stdlib.h>
#include <string.h>
-#define _cmap_inits {.max_load_factor=0.85f}
typedef struct { size_t idx; uint8_t hx; } chash_bucket_t;
#endif // CMAP_H_INCLUDED
@@ -71,6 +70,9 @@ typedef struct { size_t idx; uint8_t hx; } chash_bucket_t;
#define _i_keyref(vp) (&(vp)->first)
#endif
#define _i_ishash
+#ifndef i_max_load_factor
+ #define i_max_load_factor 0.85f
+#endif
#include "template.h"
#if !c_option(c_declared)
_cx_deftypes(_c_chash_types, _cx_self, i_key, i_val, i_size, _i_MAP_ONLY, _i_SET_ONLY);
@@ -99,14 +101,14 @@ STC_API chash_bucket_t _cx_memb(_bucket_)(const _cx_self* self, const _cx_rawke
STC_API _cx_result _cx_memb(_insert_entry_)(_cx_self* self, _cx_rawkey rkey);
STC_API void _cx_memb(_erase_entry)(_cx_self* self, _cx_value* val);
-STC_INLINE _cx_self _cx_memb(_init)(void) { return c_init(_cx_self)_cmap_inits; }
+STC_INLINE _cx_self _cx_memb(_init)(void) { return c_init(_cx_self){0}; }
STC_INLINE void _cx_memb(_shrink_to_fit)(_cx_self* self) { _cx_memb(_reserve)(self, self->size); }
-STC_INLINE void _cx_memb(_max_load_factor)(_cx_self* self, float ml) {self->max_load_factor = ml; }
+STC_INLINE float _cx_memb(_max_load_factor)(const _cx_self* self) { return i_max_load_factor; }
STC_INLINE bool _cx_memb(_empty)(const _cx_self* map) { return !map->size; }
STC_INLINE size_t _cx_memb(_size)(const _cx_self* map) { return map->size; }
STC_INLINE size_t _cx_memb(_bucket_count)(_cx_self* map) { return map->bucket_count; }
STC_INLINE size_t _cx_memb(_capacity)(const _cx_self* map)
- { return (size_t)(map->bucket_count*map->max_load_factor); }
+ { return (size_t)(map->bucket_count * (i_max_load_factor)); }
STC_INLINE void _cx_memb(_swap)(_cx_self *map1, _cx_self *map2) {c_swap(_cx_self, *map1, *map2); }
STC_INLINE bool _cx_memb(_contains)(const _cx_self* self, _cx_rawkey rkey)
{ return self->size && self->_hashx[_cx_memb(_bucket_)(self, &rkey).idx]; }
@@ -273,7 +275,7 @@ STC_INLINE uint64_t next_power_of_2(uint64_t n) {
STC_DEF _cx_self
_cx_memb(_with_capacity)(const size_t cap) {
- _cx_self h = _cmap_inits;
+ _cx_self h = {0};
_cx_memb(_reserve)(&h, cap);
return h;
}
@@ -347,7 +349,7 @@ _cx_memb(_bucket_)(const _cx_self* self, const _cx_rawkey* rkeyptr) {
STC_DEF _cx_result
_cx_memb(_insert_entry_)(_cx_self* self, _cx_rawkey rkey) {
bool nomem = false;
- if (self->size + 2 > (i_size)(self->bucket_count*self->max_load_factor))
+ if (self->size + 2 > (i_size)(self->bucket_count * (i_max_load_factor)))
nomem = !_cx_memb(_reserve)(self, self->size*3/2);
chash_bucket_t b = _cx_memb(_bucket_)(self, &rkey);
_cx_result res = {&self->table[b.idx], !self->_hashx[b.idx], nomem};
@@ -381,14 +383,13 @@ _cx_memb(_reserve)(_cx_self* self, const size_t _newcap) {
const i_size _oldbuckets = self->bucket_count;
if (_newcap != self->size && _newcap <= _oldbuckets)
return true;
- i_size _nbuckets = (i_size)(_newcap / self->max_load_factor) + 4;
+ i_size _nbuckets = (i_size)(_newcap / (i_max_load_factor)) + 4;
#if _i_expandby == 2
_nbuckets = (i_size)next_power_of_2(_nbuckets);
#else
_nbuckets |= 1;
#endif
_cx_self m = {
- self->max_load_factor,
c_alloc_n(_cx_value, _nbuckets),
(uint8_t *) c_calloc(_nbuckets + 1, 1),
self->size, (i_size)_nbuckets,
@@ -433,6 +434,7 @@ _cx_memb(_erase_entry)(_cx_self* self, _cx_value* _val) {
}
#endif // i_implement
+#undef i_max_load_factor
#undef _i_isset
#undef _i_ismap
#undef _i_ishash
diff --git a/include/stc/forward.h b/include/stc/forward.h
index e1202588..e78f1dd7 100644
--- a/include/stc/forward.h
+++ b/include/stc/forward.h
@@ -129,7 +129,6 @@ typedef union {
} SELF##_iter; \
\
typedef struct { \
- float max_load_factor; \
SELF##_value* table; \
uint8_t* _hashx; \
SELF##_size_t size, bucket_count; \