Merge branch 'master' of https://github.com/P-p-H-d/mlib
This commit is contained in:
commit
c9c5768022
16 files changed
+405
-40
No files matched your search
+15
-1
@@ -6,7 +6,7 @@ N=4
|
||||
|
||||
all: benchmark bench-plain
|
||||
|
||||
benchmark: bench-mlib bench-mlib-mempool bench-stl bench-klib bench-qt bench-glib bench-libdynamic
|
||||
benchmark: bench-mlib bench-mlib-mempool bench-stl bench-klib bench-qt bench-glib bench-libdynamic bench-sparsepp
|
||||
|
||||
bench-mlib:
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) bench-mlib.c -o bench-mlib.exe
|
||||
@@ -86,6 +86,16 @@ bench-libdynamic0:
|
||||
@./bench-libdynamic.exe 41
|
||||
@./bench-libdynamic.exe 50
|
||||
|
||||
# SPARSEPP shall point to the directory where the headers are
|
||||
bench-sparsepp:
|
||||
if test -n "$${SPARSEPP}" ; then make bench-sparsepp0 ; else echo "Nothing to be done." ; fi
|
||||
|
||||
bench-sparsepp0:
|
||||
$(CXX) $(CFLAGS) $(CPPFLAGS) -I "$${SPARSEPP}" -I "$${SPARSEPP}/.." bench-sparsepp.cpp -o bench-sparsepp.exe
|
||||
@./bench-sparsepp.exe 41
|
||||
@./bench-sparsepp.exe 42
|
||||
@./bench-sparsepp.exe 43
|
||||
|
||||
bench-plain:
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) bench-plain-c.c -o bench-plain-c.exe
|
||||
@./bench-plain-c.exe
|
||||
@@ -94,6 +104,10 @@ bench-mempool:
|
||||
$(CXX) $(CFLAGS) $(CPPFLAGS) pool.cc `pkg-config --libs --cflags glib-2.0` -lboost_system -o bench-mempool.exe
|
||||
@./bench-mempool.exe
|
||||
|
||||
bench-maxdict:
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) max-dict.c -o bench-max-dict.exe
|
||||
@./bench-max-dict.exe
|
||||
|
||||
############################################################################
|
||||
|
||||
clean:
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
#define NDEBUG
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <sparsepp/spp.h>
|
||||
|
||||
using spp::sparse_hash_map;
|
||||
using namespace std;
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
static void
|
||||
test_dict2(unsigned long n)
|
||||
{
|
||||
sparse_hash_map<unsigned long, unsigned long> dict;
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
dict[rand_get()] = rand_get();
|
||||
}
|
||||
rand_init();
|
||||
unsigned int s = 0;
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
sparse_hash_map<unsigned long, unsigned long>::iterator it = dict.find(rand_get());
|
||||
if (it != dict.end())
|
||||
s += it->second;
|
||||
}
|
||||
g_result = s;
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
struct char_array_s {
|
||||
char a[256];
|
||||
char_array_s () { a[0] = 0 ; }
|
||||
char_array_s ( const char_array_s & other) { strcpy(a, other.a); }
|
||||
bool operator==(const char_array_s &other) const { return strcmp(a, other.a) == 0; }
|
||||
};
|
||||
|
||||
namespace std {
|
||||
template <> struct hash<char_array_s> {
|
||||
std::size_t operator()(const char_array_s &k) const {
|
||||
size_t hash = 0;
|
||||
const char *s = k.a;
|
||||
while (*s) hash = hash * 31421 + (*s++) + 6927;
|
||||
return hash;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
static void
|
||||
test_dict_big(unsigned long n)
|
||||
{
|
||||
sparse_hash_map<char_array_s, char_array_s> dict;
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
char_array_s s1, s2;
|
||||
sprintf(s1.a, "%u", rand_get());
|
||||
sprintf(s2.a, "%u", rand_get());
|
||||
dict[s1] = s2;
|
||||
}
|
||||
rand_init();
|
||||
unsigned int s = 0;
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
char_array_s s1;
|
||||
sprintf(s1.a, "%u", rand_get());
|
||||
sparse_hash_map<char_array_s, char_array_s>::iterator it = dict.find(s1);
|
||||
if (it != dict.end())
|
||||
s ++;
|
||||
}
|
||||
g_result = s;
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
static void
|
||||
test_dict_str(unsigned long n)
|
||||
{
|
||||
sparse_hash_map<string, string> dict;
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
string s1 = static_cast<ostringstream*>( &(ostringstream() << rand_get()) )->str();
|
||||
string s2 = static_cast<ostringstream*>( &(ostringstream() << rand_get()) )->str();
|
||||
dict[s1] = s2;
|
||||
}
|
||||
rand_init();
|
||||
unsigned int s = 0;
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
string s1 = static_cast<ostringstream*>( &(ostringstream() << rand_get()) )->str();
|
||||
sparse_hash_map<string, string>::iterator it = dict.find(s1);
|
||||
if (it != dict.end())
|
||||
s ++;
|
||||
}
|
||||
g_result = s;
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
int n = (argc > 1) ? atoi(argv[1]) : 0;
|
||||
if (n == 42)
|
||||
test_function("Dict(u)time", 1000000, test_dict2);
|
||||
if (n == 41)
|
||||
test_function("DictB time", 1000000, test_dict_big);
|
||||
if (n == 43)
|
||||
test_function("DictS(u) time", 1000000, test_dict_str);
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* MLIB - TEST module
|
||||
*
|
||||
* Copyright (c) 2017, Patrick Pelissier
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* + Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* + Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include "m-dict.h"
|
||||
|
||||
static inline bool oor_equal_p(int64_t k, unsigned char n)
|
||||
{
|
||||
return k == (int)-n-1;
|
||||
}
|
||||
static inline void oor_set(int64_t *k, unsigned char n)
|
||||
{
|
||||
*k = (int)-n-1;
|
||||
}
|
||||
|
||||
DICT_OA_DEF2(int64, int64_t, M_OPEXTEND(M_DEFAULT_OPLIST, OOR_EQUAL(oor_equal_p), OOR_SET(oor_set M_IPTR)), int64_t, M_DEFAULT_OPLIST)
|
||||
|
||||
static int64_t get_rand(void)
|
||||
{
|
||||
int64_t n;
|
||||
do {
|
||||
n = (rand() * RAND_MAX + rand()) * RAND_MAX + rand();
|
||||
} while (n == -1 || n == -2);
|
||||
return n;
|
||||
}
|
||||
|
||||
// Let's push value into the dict until the system abandons!
|
||||
static void find_max(void)
|
||||
{
|
||||
dict_int64_t dict;
|
||||
dict_int64_init(dict);
|
||||
size_t n = 0;
|
||||
while (true) {
|
||||
dict_int64_set_at (dict, get_rand(), get_rand());
|
||||
n++;
|
||||
if ((n & ((1<<20)-1)) == 0) {
|
||||
printf ("n=%lu\n", n);
|
||||
}
|
||||
}
|
||||
dict_int64_clear(dict);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
find_max();
|
||||
}
|
||||
@@ -6,11 +6,11 @@
|
||||
ARRAY_DEF(mpz, mpz_t, M_CLASSIC_OPLIST(mpz))
|
||||
ALGO_DEF(array_mpz, ARRAY_OPLIST(mpz, M_CLASSIC_OPLIST(mpz)))
|
||||
|
||||
static inline void my_mpz_inc(mpz_t d, const mpz_t a){
|
||||
mpz_add(d, d, a);
|
||||
static inline void my_mpz_inc(mpz_t *d, const mpz_t a){
|
||||
mpz_add(*d, *d, a);
|
||||
}
|
||||
static inline void my_mpz_sqr(mpz_t d, const mpz_t a){
|
||||
mpz_mul(d, a, a);
|
||||
static inline void my_mpz_sqr(mpz_t *d, const mpz_t a){
|
||||
mpz_mul(*d, a, a);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
|
||||
@@ -32,15 +32,18 @@
|
||||
|
||||
#include "m-core.h"
|
||||
|
||||
/* Define different kind of algorithms named 'name' over the container which oplist is 'cont_oplist'
|
||||
USAGE: ALGO_DEF(afloat, LIST_OPLIST(float)) */
|
||||
/* Define different kind of algorithms named 'name' over the container
|
||||
which oplist is 'cont_oplist'
|
||||
USAGE:
|
||||
ALGO_DEF(algogName, containerOplist) */
|
||||
#define ALGO_DEF(name, cont_oplist) \
|
||||
ALGOI_DEF(name, M_GET_TYPE cont_oplist, cont_oplist, \
|
||||
M_GET_SUBTYPE cont_oplist, M_GET_OPLIST cont_oplist, M_GET_IT_TYPE cont_oplist)
|
||||
|
||||
|
||||
/* Map a function or a macro to all elements of a container.
|
||||
USAGE: ALGO_MAP(container, containerOplist, func[, extra arguments of function]) */
|
||||
USAGE:
|
||||
ALGO_MAP(container, containerOplist, func[, extra arguments of function]) */
|
||||
#define ALGO_MAP(container, cont_oplist, ...) \
|
||||
M_IF_NARGS_EQ1(__VA_ARGS__) \
|
||||
(ALGOI_MAP(container, cont_oplist, __VA_ARGS__), \
|
||||
@@ -48,7 +51,9 @@
|
||||
|
||||
|
||||
/* Extract a subset of a container to fill in another container.
|
||||
USAGE: ALGO_EXTRACT(containerDest, containerDestOplist, containerSrc, containerSrcOplist, func[, extra arguments of function]) */
|
||||
USAGE:
|
||||
ALGO_EXTRACT(contDst, contDstOplist, contSrc, contSrcOplist, func
|
||||
[, extra arguments of function]) */
|
||||
// TODO: without 'func' parameter, extract all.
|
||||
#define ALGO_EXTRACT(contD, contDop, contS, contSop, ...) \
|
||||
M_IF_NARGS_EQ1(__VA_ARGS__) \
|
||||
@@ -57,7 +62,9 @@
|
||||
|
||||
|
||||
/* Perform a Reduce operation over a container.
|
||||
USAGE: ALGO_REDUCE(destVar, container, containerOplist, reduceFunc[, mapFunc[, extraParameters of map function]]) */
|
||||
USAGE:
|
||||
ALGO_REDUCE(dstVar, container, contOplist, reduceFunc
|
||||
[, mapFunc[, extraParameters of map function]]) */
|
||||
#define ALGO_REDUCE(dest, cont, contOp, ...) \
|
||||
M_IF_NARGS_EQ1(__VA_ARGS__) \
|
||||
(ALGOI_REDUCE(dest, cont, contOp, __VA_ARGS__), \
|
||||
@@ -67,7 +74,8 @@
|
||||
|
||||
|
||||
/* Initialize & set a container with a variable array list.
|
||||
USAGE: ALGO_INIT_VA(container, containerOplist, param1[, param2[, ...]]) */
|
||||
USAGE:
|
||||
ALGO_INIT_VA(container, containerOplist, param1[, param2[, ...]]) */
|
||||
#define ALGO_INIT_VA(dest, contOp, ...) do { \
|
||||
M_GET_INIT contOp (dest); \
|
||||
M_MAP2(ALGOI_INIT_VA_FUNC, (dest, M_GET_PUSH contOp, ) , __VA_ARGS__); \
|
||||
@@ -95,6 +103,7 @@
|
||||
return !M_GET_IT_END_P cont_oplist (it); \
|
||||
} \
|
||||
\
|
||||
/* NOTE: If PREVIOUS & IT_LAST exist, then go backwards */ \
|
||||
M_IF(M_AND(M_TEST_METHOD_P(PREVIOUS, cont_oplist), M_TEST_METHOD_P(IT_LAST, cont_oplist))) \
|
||||
( \
|
||||
static inline void M_C(name, _find_last) (it_t it, container_t l, const type_t data) \
|
||||
@@ -120,7 +129,7 @@
|
||||
M_GET_IT_SET cont_oplist (it, it2) ; \
|
||||
} \
|
||||
} \
|
||||
) \
|
||||
) /* End of alternative of _find_last */ \
|
||||
\
|
||||
static inline size_t M_C(name, _count) (container_t l, const type_t data) \
|
||||
{ \
|
||||
@@ -145,12 +154,12 @@
|
||||
\
|
||||
static inline void M_C(name, _reduce) (type_t *dest, \
|
||||
container_t l, \
|
||||
void (*f)(type_t, type_t const) ) \
|
||||
void (*f)(type_t *, type_t const) ) \
|
||||
{ \
|
||||
bool initDone = false; \
|
||||
for M_EACH(item, l, cont_oplist) { \
|
||||
if (initDone) \
|
||||
f(*dest, *item); \
|
||||
f(dest, *item); \
|
||||
else { \
|
||||
M_GET_SET type_oplist (*dest, *item); \
|
||||
initDone = true; \
|
||||
@@ -160,18 +169,18 @@
|
||||
\
|
||||
static inline void M_C(name, _map_reduce) (type_t *dest, \
|
||||
container_t l, \
|
||||
void (*r)(type_t, type_t const), \
|
||||
void (*m)(type_t, type_t const) ) \
|
||||
void (*r)(type_t*, type_t const), \
|
||||
void (*m)(type_t*, type_t const) ) \
|
||||
{ \
|
||||
bool initDone = false; \
|
||||
type_t tmp; \
|
||||
M_GET_INIT type_oplist (tmp); \
|
||||
for M_EACH(item, l, cont_oplist) { \
|
||||
if (initDone) { \
|
||||
m(tmp, *item); \
|
||||
r(*dest, tmp); \
|
||||
m(&tmp, *item); \
|
||||
r(dest, tmp); \
|
||||
} else { \
|
||||
m(*dest, *item); \
|
||||
m(dest, *item); \
|
||||
initDone = true; \
|
||||
} \
|
||||
} \
|
||||
@@ -179,7 +188,7 @@
|
||||
} \
|
||||
\
|
||||
M_IF_METHOD(CMP, type_oplist)( \
|
||||
static inline type_t *M_C(name, _min) (/*const*/ container_t l) \
|
||||
static inline type_t *M_C(name, _min) (const container_t l) \
|
||||
{ \
|
||||
type_t *min = NULL; \
|
||||
for M_EACH(cref, l, cont_oplist) { \
|
||||
@@ -190,7 +199,7 @@
|
||||
return min; \
|
||||
} \
|
||||
\
|
||||
static inline type_t *M_C(name, _max) (/*const*/ container_t l) \
|
||||
static inline type_t *M_C(name, _max) (const container_t l) \
|
||||
{ \
|
||||
type_t *max = NULL; \
|
||||
for M_EACH(cref, l, cont_oplist) { \
|
||||
@@ -202,7 +211,7 @@
|
||||
} \
|
||||
\
|
||||
static inline void M_C(name, _minmax) (type_t **min_p, type_t **max_p, \
|
||||
/*const*/ container_t l) \
|
||||
const container_t l) \
|
||||
{ \
|
||||
type_t *min = NULL; \
|
||||
type_t *max = NULL; \
|
||||
@@ -218,7 +227,7 @@
|
||||
*max_p = max; \
|
||||
} \
|
||||
\
|
||||
static inline bool M_C(name, _sort_p)(container_t l) \
|
||||
static inline bool M_C(name, _sort_p)(const container_t l) \
|
||||
{ \
|
||||
it_t it1; \
|
||||
it_t it2; \
|
||||
@@ -462,7 +471,7 @@
|
||||
#define ALGOI_REDUCE_OR(a,b) ((a) |= (b))
|
||||
#define ALGOI_REDUCE_SUM(a,b) ((a) += (b))
|
||||
|
||||
/* Get function pointer.
|
||||
/* Return the method associated to a reduce operation.
|
||||
It returns the special function handler if function is and, or, sum or add.
|
||||
Otherwise it returns the original function */
|
||||
#define ALGOI_REDUCE_FUNC(reduceFunc) \
|
||||
|
||||
+13
-4
@@ -87,8 +87,9 @@ M_C3(buffer_, name, _init)(buffer_t v, size_t size) \
|
||||
return; \
|
||||
} \
|
||||
if (!BUFFERI_POLICY_P((policy), BUFFER_PUSH_INIT_POP_MOVE)) { \
|
||||
for(size_t i = 0; i < size; i++) \
|
||||
for(size_t i = 0; i < size; i++) { \
|
||||
M_GET_INIT oplist(v->data[i]); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
@@ -96,8 +97,9 @@ M_C3(buffer_, name, _init)(buffer_t v, size_t size) \
|
||||
M_C3(bufferi_, name, _clear_obj)(buffer_t v) \
|
||||
{ \
|
||||
if (!BUFFERI_POLICY_P((policy), BUFFER_PUSH_INIT_POP_MOVE)) { \
|
||||
for(size_t i = 0; i < BUFFERI_SIZE(m_size); i++) \
|
||||
for(size_t i = 0; i < BUFFERI_SIZE(m_size); i++) { \
|
||||
M_GET_CLEAR oplist(v->data[i]); \
|
||||
} \
|
||||
} else { \
|
||||
size_t i = BUFFERI_POLICY_P((policy), BUFFER_STACK) ? 0 : v->idx_cons; \
|
||||
while (i != v->idx_prod) { \
|
||||
@@ -140,19 +142,26 @@ M_C3(buffer_, name, _init)(buffer_t v, size_t size) \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_C3(buffer_, name, _empty_p)(buffer_t v) \
|
||||
M_C3(buffer_, name, _empty_p)(const buffer_t v) \
|
||||
{ \
|
||||
assert(v->number <= BUFFERI_SIZE(m_size)); \
|
||||
return v->number == 0; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_C3(buffer_, name, _full_p)(buffer_t v) \
|
||||
M_C3(buffer_, name, _full_p)(const buffer_t v) \
|
||||
{ \
|
||||
assert(v->number <= BUFFERI_SIZE(m_size)); \
|
||||
return v->number == BUFFERI_SIZE(m_size); \
|
||||
} \
|
||||
\
|
||||
static inline size_t \
|
||||
M_C3(buffer_, name, _size)(const buffer_t v) \
|
||||
{ \
|
||||
assert(v->number <= BUFFERI_SIZE(m_size)); \
|
||||
return v->number; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_C3(buffer_, name, _push)(buffer_t v, type const data) \
|
||||
{ \
|
||||
|
||||
@@ -667,6 +667,22 @@ static inline uint32_t m_core_rotl32a (uint32_t x, uint32_t n)
|
||||
return (x<<n) | (x>>(32-n));
|
||||
}
|
||||
|
||||
/* Round to the next highest power of 2.
|
||||
See https://web.archive.org/web/20160703165415/https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
|
||||
*/
|
||||
static inline uint64_t m_core_roundpow2(uint64_t v)
|
||||
{
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
v |= v >> 32;
|
||||
v++;
|
||||
return v;
|
||||
}
|
||||
|
||||
/* Implement FNV1A Jesteress Hash (very similar to FNV1A Meiyan Hash)
|
||||
See http://www.sanmayce.com/Fastest_Hash/ and
|
||||
https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1a_hash
|
||||
@@ -1063,8 +1079,8 @@ m_core_hash (const void *str, size_t length)
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define M_MEMORY_FULL(size) do { \
|
||||
fprintf(stderr, "ERROR: Can not allocate memory (%lu bytes).\n", \
|
||||
(unsigned long) size); \
|
||||
fprintf(stderr, "ERROR(M*LIB): Can not allocate memory in function %s of file %s:%d (%lu bytes).\n", \
|
||||
__func__, __FILE__, __LINE__, (unsigned long) size); \
|
||||
abort(); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
@@ -693,7 +693,7 @@ typedef enum {
|
||||
) \
|
||||
\
|
||||
static inline void \
|
||||
M_C3(dicti_,name,_resize_up)(dict_t h, size_t newSize) \
|
||||
M_C3(dicti_,name,_resize_up)(dict_t h, size_t newSize, bool updateLimit) \
|
||||
{ \
|
||||
size_t oldSize = h->mask+1; \
|
||||
assert (newSize >= oldSize); \
|
||||
@@ -713,6 +713,8 @@ typedef enum {
|
||||
\
|
||||
/* Then let's rehash all the entries in their **exact** position. \
|
||||
If we can't, let's put them in the 'tmp' array. \
|
||||
It has been measured that the size of this 'tmp' array is \
|
||||
around 6% of the size of updated dictionnary. \
|
||||
NOTE: This should be much cache friendly than typical hash code */ \
|
||||
M_C3(array_dicti_,name,_t) tmp; \
|
||||
M_C3(array_dicti_,name,_init)(tmp); \
|
||||
@@ -758,10 +760,11 @@ typedef enum {
|
||||
M_C3(array_dicti_,name,_clear) (tmp); \
|
||||
h->mask = newSize-1; \
|
||||
h->count_delete = h->count; \
|
||||
M_C3(dicti_,name,_limit)(h, newSize); \
|
||||
if (updateLimit == true) { \
|
||||
M_C3(dicti_,name,_limit)(h, newSize); \
|
||||
} \
|
||||
h->data = data; \
|
||||
M_IF_DEBUG (assert (M_C3(dicti_,name,_control_after_resize)(h));) \
|
||||
assert (h->lower_limit < h->count && h->count < h->upper_limit); \
|
||||
DICTI_OA_CONTRACT(h); \
|
||||
} \
|
||||
\
|
||||
@@ -807,7 +810,7 @@ typedef enum {
|
||||
if (M_UNLIKELY (dict->count_delete >= dict->upper_limit)) { \
|
||||
size_t newSize = dict->mask+1; \
|
||||
if (dict->count > (dict->mask / 2)) newSize += newSize; \
|
||||
M_C3(dicti_,name,_resize_up)(dict, newSize); \
|
||||
M_C3(dicti_,name,_resize_up)(dict, newSize, true); \
|
||||
} \
|
||||
DICTI_OA_CONTRACT(dict); \
|
||||
} \
|
||||
@@ -1155,6 +1158,21 @@ typedef enum {
|
||||
return &it->dict->data[i]; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
M_C3(dict_,name,_reserve)(dict_t dict, size_t capacity) \
|
||||
{ \
|
||||
DICTI_OA_CONTRACT(dict); \
|
||||
size_t size; \
|
||||
/* Get the size which will allow to fit this capacity */ \
|
||||
size = m_core_roundpow2 (capacity * (1.0 / coeff_up)); \
|
||||
assert (M_POWEROF2_P(size)); \
|
||||
if (size > dict->mask+1) { \
|
||||
dict->upper_limit = (size_t) (size * coeff_up) - 1; \
|
||||
M_C3(dicti_,name,_resize_up)(dict, size, false); \
|
||||
} \
|
||||
DICTI_OA_CONTRACT(dict); \
|
||||
} \
|
||||
\
|
||||
DICTI_DEF2_FUNC_ADDITIONAL(name, key_type, key_oplist, value_type, value_oplist, 0, dict_t, dict_it_t)
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -257,7 +257,7 @@ typedef struct ilist_head_s {
|
||||
M_C3(ilist_, name, _last_p)(const list_it_t it) \
|
||||
{ \
|
||||
assert (it != NULL); \
|
||||
return it->next == it->head; \
|
||||
return it->next == it->head || it->current == it->head; \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
|
||||
+11
-2
@@ -195,7 +195,7 @@
|
||||
{ \
|
||||
SHAREDI_CONTRACT(dest); \
|
||||
SHAREDI_CONTRACT(shared); \
|
||||
assert (dest != shared); \
|
||||
assert (dest != shared); \
|
||||
M_C3(shared_, name, _clear)(dest); \
|
||||
M_C3(shared_, name, _init_move)(dest, shared); \
|
||||
} \
|
||||
@@ -206,11 +206,20 @@
|
||||
{ \
|
||||
SHAREDI_CONTRACT(p1); \
|
||||
SHAREDI_CONTRACT(p2); \
|
||||
M_SWAP (struct M_C3(shared_, name, _s)*, *p1, *p2); \
|
||||
M_SWAP (struct M_C3(shared_, name, _s)*, *p1, *p2); \
|
||||
SHAREDI_CONTRACT(p1); \
|
||||
SHAREDI_CONTRACT(p2); \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
M_C3(shared_, name, _equal_p)(const M_C3(shared_, name, _t) p1, \
|
||||
const M_C3(shared_, name, _t) p2) \
|
||||
{ \
|
||||
SHAREDI_CONTRACT(p1); \
|
||||
SHAREDI_CONTRACT(p2); \
|
||||
return *p1 == *p2; \
|
||||
} \
|
||||
\
|
||||
static inline const type * \
|
||||
M_C3(shared_, name, _cref)(const M_C3(shared_, name, _t) shared) \
|
||||
{ \
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#undef LIST_CONTRACT
|
||||
#undef DICTI_CONTRACT
|
||||
#undef DICTI_OA_CONTRACT
|
||||
#undef SHAREDI_CONTRACT
|
||||
#else
|
||||
/* For normal builds, empty macros which does nothing */
|
||||
#define START_COVERAGE
|
||||
|
||||
+22
-1
@@ -23,6 +23,18 @@ static void g_f(int n)
|
||||
g_count++;
|
||||
}
|
||||
|
||||
static void func_map(int *d, int n)
|
||||
{
|
||||
assert (g_min <= n && n <= g_max);
|
||||
g_count++;
|
||||
*d = n * n;
|
||||
}
|
||||
|
||||
static void func_reduce(int *d, int n)
|
||||
{
|
||||
*d += n;
|
||||
}
|
||||
|
||||
static void test_list(void)
|
||||
{
|
||||
list_int_t l;
|
||||
@@ -107,7 +119,16 @@ static void test_array(void)
|
||||
algo_array_map(l, g_f);
|
||||
assert(g_count == 101);
|
||||
|
||||
// FIXME: reduce functions don't have the right prototype to work with integers as the 1st argument is an int instead of a int*
|
||||
int n;
|
||||
algo_array_reduce(&n, l, func_reduce);
|
||||
assert(n == 100*99/2+17);
|
||||
|
||||
g_min = 0;
|
||||
g_max = 99;
|
||||
g_count = 0;
|
||||
algo_array_map_reduce(&n, l, func_reduce, func_map);
|
||||
assert(g_count == 101);
|
||||
assert(n == (328350 + 17*17));
|
||||
|
||||
int *min, *max;
|
||||
assert (*algo_array_min(l) == 0);
|
||||
|
||||
@@ -22,8 +22,11 @@
|
||||
*/
|
||||
#include "m-buffer.h"
|
||||
|
||||
#include "coverage.h"
|
||||
START_COVERAGE
|
||||
// Define a fixed queue of unsigned int
|
||||
BUFFER_DEF(uint, unsigned int, 10, BUFFER_QUEUE|BUFFER_BLOCKING)
|
||||
END_COVERAGE
|
||||
|
||||
// Define a variable stack of float
|
||||
BUFFER_DEF(floats, float, 0, BUFFER_STACK|BUFFER_BLOCKING)
|
||||
@@ -71,6 +74,33 @@ static void test_global(void)
|
||||
m_thread_join(idx_p[i]);
|
||||
m_thread_join(idx_c[i]);
|
||||
}
|
||||
assert (buffer_uint_empty_p(g_buff));
|
||||
assert (!buffer_uint_full_p(g_buff));
|
||||
assert (buffer_uint_size(g_buff) == 0);
|
||||
|
||||
buffer_uint_clean(g_buff);
|
||||
assert (buffer_uint_empty_p(g_buff));
|
||||
assert (!buffer_uint_full_p(g_buff));
|
||||
assert (buffer_uint_size(g_buff) == 0);
|
||||
|
||||
for(unsigned int i = 0; i < 5;i++)
|
||||
buffer_uint_push(g_buff, i);
|
||||
|
||||
assert (!buffer_uint_empty_p(g_buff));
|
||||
assert (!buffer_uint_full_p(g_buff));
|
||||
assert (buffer_uint_size(g_buff) == 5);
|
||||
|
||||
for(unsigned int i = 0; i < 5;i++)
|
||||
buffer_uint_push(g_buff, i);
|
||||
|
||||
assert (!buffer_uint_empty_p(g_buff));
|
||||
assert (buffer_uint_full_p(g_buff));
|
||||
assert (buffer_uint_size(g_buff) == 10);
|
||||
|
||||
buffer_uint_clean(g_buff);
|
||||
assert (buffer_uint_empty_p(g_buff));
|
||||
assert (!buffer_uint_full_p(g_buff));
|
||||
assert (buffer_uint_size(g_buff) == 0);
|
||||
|
||||
buffer_uint_clear(g_buff);
|
||||
}
|
||||
|
||||
@@ -369,6 +369,15 @@ static void test_it_oa(void)
|
||||
assert (!dict_oa_int_it_equal_p(it2, it));
|
||||
dict_oa_int_next(it2);
|
||||
assert (dict_oa_int_it_equal_p(it2, it));
|
||||
|
||||
s = 0;
|
||||
for(dict_oa_int_it_last(it, d1); !dict_oa_int_end_p(it); dict_oa_int_previous(it)) {
|
||||
dict_pair_oa_int_t *pair = dict_oa_int_ref(it);
|
||||
assert (pair->key >= 0 && pair->key < 200);
|
||||
assert (pair->value == pair->key + 1);
|
||||
s++;
|
||||
}
|
||||
assert (s == 100);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,24 @@ static void test(void)
|
||||
assert (n == item->n);
|
||||
n++;
|
||||
}
|
||||
assert (n == 4);
|
||||
ilist_it_tname_t it1, it2;
|
||||
ilist_tname_it_last(it1, list);
|
||||
assert (!ilist_tname_end_p(it1));
|
||||
assert (ilist_tname_last_p(it1));
|
||||
ilist_tname_it_end(it2, list);
|
||||
assert (ilist_tname_end_p(it2));
|
||||
assert (ilist_tname_last_p(it2));
|
||||
assert (!ilist_tname_it_equal_p(it1, it2));
|
||||
for(ilist_tname_it_set(it2, it1) ; !ilist_tname_end_p(it2) ; ilist_tname_previous(it2)) {
|
||||
const test_t *item = ilist_tname_cref(it2);
|
||||
n--;
|
||||
assert (n == item->n);
|
||||
}
|
||||
assert (n == 1);
|
||||
ilist_tname_it_set(it2, it1);
|
||||
assert (ilist_tname_it_equal_p(it1, it2));
|
||||
|
||||
for M_EACH(item, list, ILIST_OPLIST(tname)) {
|
||||
if (item->n == 2)
|
||||
ilist_tname_unlink(item);
|
||||
|
||||
+17
-2
@@ -28,8 +28,8 @@
|
||||
#include "coverage.h"
|
||||
START_COVERAGE
|
||||
SHARED_PTR_DEF(int, int)
|
||||
SHARED_PTR_DEF(mpz, mpz_t, M_CLASSIC_OPLIST(mpz))
|
||||
END_COVERAGE
|
||||
SHARED_PTR_DEF(mpz, mpz_t, M_CLASSIC_OPLIST(mpz))
|
||||
|
||||
static int f(const shared_int_t p)
|
||||
{
|
||||
@@ -87,7 +87,22 @@ int main(void)
|
||||
|
||||
shared_int_init_new(p1);
|
||||
assert(!shared_int_NULL_p(p1));
|
||||
*shared_int_ref(p1) = 1;
|
||||
shared_int_init_new(p2);
|
||||
assert(!shared_int_NULL_p(p2));
|
||||
*shared_int_ref(p2) = 2;
|
||||
assert(!shared_int_equal_p(p1, p2));
|
||||
assert (*shared_int_cref(p1) == 1);
|
||||
assert (*shared_int_cref(p2) == 2);
|
||||
shared_int_swap(p1, p2);
|
||||
assert (*shared_int_cref(p1) == 2);
|
||||
assert (*shared_int_cref(p2) == 1);
|
||||
shared_int_set(p1, p2);
|
||||
assert(shared_int_equal_p(p1, p2));
|
||||
assert (*shared_int_cref(p1) == 1);
|
||||
assert (*shared_int_cref(p2) == 1);
|
||||
shared_int_clear(p1);
|
||||
|
||||
shared_int_clear(p2);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
Reference in new issue
Block a user