summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authortylo <[email protected]>2020-03-09 16:13:23 +0100
committertylo <[email protected]>2020-03-09 16:13:23 +0100
commit7ef38a5f3dbf7fbda4137ca3f341e9b962362fab (patch)
tree90749ddd7d243fe2f2a29d25be2e6ec0a016b012
parent9a0186979a3ad014352b5b129687df98f060133e (diff)
downloadSTC-modified-7ef38a5f3dbf7fbda4137ca3f341e9b962362fab.tar.gz
STC-modified-7ef38a5f3dbf7fbda4137ca3f341e9b962362fab.zip
Added a few features.
-rw-r--r--cdef.h4
-rw-r--r--cmap.h43
-rw-r--r--cmap_test.c5
-rw-r--r--cstring.h15
4 files changed, 33 insertions, 34 deletions
diff --git a/cdef.h b/cdef.h
index f655fe5a..7a2e5521 100644
--- a/cdef.h
+++ b/cdef.h
@@ -37,14 +37,14 @@
// #define foo_1(X) foo_2(X, 100)
// #define foo_2(X, Y) X + Y
+#define _cdef_max_alloca (1000)
#define _cdef_swap(T, x, y) { T __t = x; x = y; y = __t; }
#define cdef_initRaw(x) (x)
#define cdef_getRaw(x) (x)
static inline void cdef_destroy(void* value) {}
-#define cforeach(...) cdef_MACRO_OVERLOAD(cforeach, __VA_ARGS__)
-#define cforeach_3(it, ctag, con) \
+#define cforeach(it, ctag, con) \
for (ctag##_iter_t it = ctag##_begin(con); it.item != ctag##_end(con).item; it = ctag##_next(it))
static inline uint32_t
diff --git a/cmap.h b/cmap.h
index 1ba48c61..fbd8c3ed 100644
--- a/cmap.h
+++ b/cmap.h
@@ -25,9 +25,10 @@
#include "cvector.h"
-#define cmap_initializer {cvector_initializer, 0}
+#define cmap_initializer {cvector_initializer, 0, 80, 167}
#define cmap_size(cm) ((size_t) (cm)._size)
-#define cmap_capacity(cm) cvector_capacity((cm)._vec)
+#define cmap_buckets(cm) cvector_capacity((cm)._vec)
+#define cmap_maxLoadFactor(cm) ((cm).maxLoadPercentage / 100.0)
// CMapEntry:
@@ -57,7 +58,7 @@ typedef struct CMapEntry_##tag CMapEntry_##tag
declare_CMap_4(tag, Key, Value, cdef_destroy)
#define declare_CMap_4(tag, Key, Value, valueDestroy) \
- declare_CMap_10(tag, Key, Value, valueDestroy, Key, cdef_getRaw, memcmp, cdef_murmurHash, cdef_initRaw, cdef_destroy)
+ declare_CMap_10(tag, Key, Value, valueDestroy, Key, cdef_initRaw, cdef_getRaw, memcmp, cdef_murmurHash, cdef_destroy)
// CMap<CString, Value>:
@@ -67,17 +68,19 @@ typedef struct CMapEntry_##tag CMapEntry_##tag
declare_CMap_StringKey_3(tag, Value, cdef_destroy)
#define declare_CMap_StringKey_3(tag, Value, valueDestroy) \
- declare_CMap_10(tag, CString, Value, valueDestroy, const char*, cstring_getRaw, cstring_compare, cstring_hash, cstring_make, cstring_destroy)
+ declare_CMap_10(tag, CString, Value, valueDestroy, const char*, cstring_make, cstring_getRaw, cstring_compare, cstring_hash, cstring_destroy)
// CMap full:
-#define declare_CMap_10(tag, Key, Value, valueDestroy, KeyRaw, keyGetRaw, keyCompare, keyHasher, keyInit, keyDestroy) \
+#define declare_CMap_10(tag, Key, Value, valueDestroy, KeyRaw, keyInitRaw, keyGetRaw, keyCompare, keyHasher, keyDestroy) \
declare_CMapEntry(tag, Key, Value, keyDestroy, valueDestroy); \
declare_CVector_3(map_##tag, CMapEntry_##tag, cmapentry_##tag##_destroy); \
\
typedef struct CMap_##tag { \
CVector_map_##tag _vec; \
size_t _size; \
+ uint16_t maxLoadPercentage; \
+ uint16_t expandPercentage; \
} CMap_##tag; \
\
typedef struct cmap_##tag##_iter_t { \
@@ -90,7 +93,7 @@ static inline CMap_##tag cmap_##tag##_init(void) { \
} \
\
static inline void cmap_##tag##_destroy(CMap_##tag* self) { \
- if (self->_size) { \
+ if (cmap_size(*self)) { \
size_t cap = _cvector_capacity(self->_vec); \
CMapEntry_##tag* e = self->_vec.data, *end = e + cap; \
for (; e != end; ++e) if (e->state == CMapEntry_INUSE) cmapentry_##tag##_destroy(e); \
@@ -98,6 +101,8 @@ static inline void cmap_##tag##_destroy(CMap_##tag* self) { \
cvector_map_##tag##_destroy(&self->_vec); \
} \
\
+static inline size_t cmap_##tag##_reserve(CMap_##tag* self, size_t size); /* predeclared */ \
+ \
static inline void cmap_##tag##_clear(CMap_##tag* self) { \
CMap_##tag cm = cmap_initializer; \
cmap_##tag##_destroy(self); \
@@ -109,6 +114,12 @@ static inline void cmap_##tag##_swap(CMap_##tag* a, CMap_##tag* b) { \
_cdef_swap(size_t, a->_size, b->_size); \
} \
\
+static inline void cmap_##tag##_setMaxLoadFactor(CMap_##tag* self, float loadFactor) { \
+ self->maxLoadPercentage = (uint16_t) (loadFactor * 100.99); \
+ if (cmap_size(*self) > cmap_buckets(*self) * loadFactor) \
+ cmap_##tag##_reserve(self, 7 + cmap_size(*self) / self->maxLoadPercentage); \
+} \
+ \
static inline size_t cmap_##tag##_bucket(CMap_##tag cm, KeyRaw rawKey) { \
size_t cap = cvector_capacity(cm._vec); \
size_t idx = keyHasher(&rawKey, sizeof(Key)) % cap; \
@@ -125,23 +136,21 @@ static inline size_t cmap_##tag##_bucket(CMap_##tag cm, KeyRaw rawKey) { \
} \
\
static inline CMapEntry_##tag* cmap_##tag##_get(CMap_##tag cm, KeyRaw rawKey) { \
- if (cm._size == 0) return NULL; \
+ if (cmap_size(cm) == 0) return NULL; \
size_t idx = cmap_##tag##_bucket(cm, rawKey); \
return cm._vec.data[idx].state == CMapEntry_INUSE ? &cm._vec.data[idx] : NULL; \
} \
\
-static inline size_t cmap_##tag##_reserve(CMap_##tag* self, size_t size); /* predeclared */ \
- \
static inline CMapEntry_##tag* cmap_##tag##_put(CMap_##tag* self, KeyRaw rawKey, Value value) { \
size_t cap = cvector_capacity(self->_vec); \
- if (self->_size >= cap * 4 / 5) \
- cap = cmap_##tag##_reserve(self, cap * 5 / 3); \
+ if (cmap_size(*self) >= cap * self->maxLoadPercentage / 100) \
+ cap = cmap_##tag##_reserve(self, cap * self->expandPercentage / 100); \
size_t idx = cmap_##tag##_bucket(*self, rawKey); \
CMapEntry_##tag* e = &self->_vec.data[idx]; \
e->value = value; \
e->changed = (e->state == CMapEntry_INUSE); \
if (e->state != CMapEntry_INUSE) { \
- e->key = keyInit(rawKey); \
+ e->key = keyInitRaw(rawKey); \
e->state = CMapEntry_INUSE; \
++self->_size; \
} \
@@ -162,20 +171,20 @@ static inline size_t cmap_##tag##_reserve(CMap_##tag* self, size_t size) { \
return newcap; \
} \
\
-static inline int cmap_##tag##_erase(CMap_##tag* self, KeyRaw rawKey) { \
+static inline bool cmap_##tag##_erase(CMap_##tag* self, KeyRaw rawKey) { \
CMapEntry_##tag* e = cmap_##tag##_get(*self, rawKey); \
if (e) { \
cmapentry_##tag##_destroy(e); \
e->state = CMapEntry_REMOVED; \
--self->_size; \
- return 1; \
+ return true; \
} \
- return 0; \
+ return false; \
} \
\
static inline cmap_##tag##_iter_t cmap_##tag##_begin(CMap_##tag map) { \
cmap_##tag##_iter_t null = {NULL, NULL}; \
- if (map._size == 0) return null; \
+ if (cmap_size(map) == 0) return null; \
CMapEntry_##tag* e = map._vec.data, *end = e + _cvector_capacity(map._vec); \
while (e != end && e->state != CMapEntry_INUSE) ++e; \
cmap_##tag##_iter_t it = {e, end}; return it; \
@@ -187,7 +196,7 @@ static inline cmap_##tag##_iter_t cmap_##tag##_next(cmap_##tag##_iter_t it) { \
} \
\
static inline cmap_##tag##_iter_t cmap_##tag##_end(CMap_##tag map) { \
- CMapEntry_##tag* end = (map._size == 0) ? NULL : map._vec.data + _cvector_capacity(map._vec); \
+ CMapEntry_##tag* end = (cmap_size(map) == 0) ? NULL : map._vec.data + _cvector_capacity(map._vec); \
cmap_##tag##_iter_t it = {end, end}; \
return it; \
} \
diff --git a/cmap_test.c b/cmap_test.c
index fcb138b7..ca773fdb 100644
--- a/cmap_test.c
+++ b/cmap_test.c
@@ -91,9 +91,6 @@ int main()
stringSpeed(20000);
- CString tmp = cstring_makeTemp("I will automatically be destroyed when going out of scope");
- printf("tmp: %s\n", tmp.str);
-
CString cs = cstring_make("one-nine-three-seven-five");
printf("%s.\n", cs.str);
cstring_insert(&cs, 3, "-two");
@@ -119,7 +116,7 @@ int main()
num = cmap_si_get(words, "funny");
if (num) printf("%s: %d\n", num->key.str, num->value);
- printf("words size: %zd, capacity %zd\n", cmap_size(words), cmap_capacity(words));
+ printf("words size: %llu, capacity %llu\n", cmap_size(words), cmap_buckets(words));
cmap_si_clear(&words);
CVector_s strv = cvector_initializer;
diff --git a/cstring.h b/cstring.h
index a31d5455..b396f9e3 100644
--- a/cstring.h
+++ b/cstring.h
@@ -43,17 +43,8 @@ static size_t _cstring_null_rep[] = {0, 0, 0};
#define cstring_size(cs) ((size_t) _cstring_rep(cs)[0])
#define cstring_capacity(cs) ((size_t) _cstring_rep(cs)[1])
#define cstring_npos ((size_t) -1)
-#define cstring_makeTemp(str) _cstring_makeTemp(str, (size_t *) alloca(2 * sizeof(size_t) + strlen(str) + 1))
-static inline CString _cstring_makeTemp(const char* str, size_t *rep) {
- CString cs = {(char *) (rep + 2)};
- strcpy(cs.str, str);
- rep[0] = strlen(str);
- rep[1] = 0; // no cap -> no destroy. OK
- return cs;
-}
-
static inline void cstring_reserve(CString* self, size_t cap) {
size_t len = cstring_size(*self), oldcap = cstring_capacity(*self);
if (cap > oldcap) {
@@ -147,9 +138,10 @@ static inline void _cstring_internalMove(CString* self, size_t pos1, size_t pos2
}
static inline void cstring_insertN(CString* self, size_t pos, const char* str, size_t n) {
- char* xstr = (char *) memcpy(alloca(n), str, n);
+ char* xstr = (char *) memcpy(n > _cdef_max_alloca ? malloc(n) : alloca(n), str, n);
_cstring_internalMove(self, pos, pos + n);
memcpy(&self->str[pos], xstr, n);
+ if (n > _cdef_max_alloca) free(xstr);
}
static inline void cstring_insert(CString* self, size_t pos, const char* str) {
@@ -169,9 +161,10 @@ static inline size_t cstring_findN(CString cs, size_t pos, const char* needle, s
static inline size_t cstring_replaceN(CString* self, size_t pos, const char* s1, size_t n1, const char* s2, size_t n2) {
size_t pos2 = cstring_findN(*self, pos, s1, n1);
if (pos2 == cstring_npos) return cstring_npos;
- char* xs2 = (char *) memcpy(alloca(n2), s2, n2);
+ char* xs2 = (char *) memcpy(n2 > _cdef_max_alloca ? malloc(n2) : alloca(n2), s2, n2);
_cstring_internalMove(self, pos2 + n1, pos2 + n2);
memcpy(&self->str[pos2], xs2, n2);
+ if (n2 > _cdef_max_alloca) free(xs2);
return pos2;
}