From 1c7ea86ceba62d48d24c7cc6c51666c86ed57c24 Mon Sep 17 00:00:00 2001 From: Gabriel Eiseman Date: Sun, 11 Feb 2024 03:35:18 -0500 Subject: [PATCH] Fix vec_pivot_m3, minor fixes for vecs of 0-size types Improve some doc comments and includes --- include/crater/hash.h | 2 +- src/lib/crater/prand.c | 1 + src/lib/crater/vec.c | 24 +++++++++++++++--------- src/test/dlog_t64.c | 2 +- src/test/minmax_heap.c | 1 - src/test/pandigital_primes.c | 1 - src/test/pointcloud.c | 2 +- src/test/vec_bsearch.c | 1 - src/test/vec_oom.c | 8 ++++++-- src/test/wc.c | 1 - 10 files changed, 25 insertions(+), 18 deletions(-) diff --git a/include/crater/hash.h b/include/crater/hash.h index 517188d..149a601 100644 --- a/include/crater/hash.h +++ b/include/crater/hash.h @@ -209,7 +209,7 @@ inline static void *cr8r_hash_next(cr8r_hashtbl_t *self, const cr8r_hashtbl_ft * if(self->table_b){ if(cur){ b = (cur - self->table_b)/ft->base.size; - if(b++ >= self->len_b){ + if(b++ >= self->len_b){// also goes to SEARCH_A if "b < 0" due to unsigned overflow wrapping goto SEARCH_A; } } diff --git a/src/lib/crater/prand.c b/src/lib/crater/prand.c index e7d40a1..fcde9fc 100644 --- a/src/lib/crater/prand.c +++ b/src/lib/crater/prand.c @@ -489,6 +489,7 @@ cr8r_prng *cr8r_prng_init_splitmix(uint64_t seed){ return res; } +// need to create anonymous struct to statically allocate fla static struct{ uint64_t state_size; uint32_t (*get_u32)(void*); diff --git a/src/lib/crater/vec.c b/src/lib/crater/vec.c index 72c0830..8e40dd1 100644 --- a/src/lib/crater/vec.c +++ b/src/lib/crater/vec.c @@ -45,7 +45,10 @@ void *cr8r_default_resize(cr8r_base_ft *base, void *p, uint64_t cap){ } return NULL; } - return p ? realloc(p, cap*base->size) : malloc(cap*base->size); + if(base->size){ + return p ? realloc(p, cap*base->size) : malloc(cap*base->size); + } + return p; } void *cr8r_default_resize_pass(cr8r_base_ft *base, void *p, uint64_t cap){ @@ -208,7 +211,7 @@ void cr8r_vec_shuffle(cr8r_vec *self, cr8r_vec_ft *ft, cr8r_prng *prng){ } static inline bool ensure_cap(cr8r_vec *self, cr8r_vec_ft *ft, uint64_t cap){ - if(cap > self->cap && ft->base.size){ + if(cap > self->cap){ uint64_t new_cap = ft->new_size(&ft->base, self->cap); if(cap > new_cap){ new_cap = cap; @@ -577,21 +580,24 @@ void *cr8r_vec_pivot_m3(const cr8r_vec *self, cr8r_vec_ft *ft, uint64_t a, uint6 return NULL; } void *fst = self->buf + a*ft->base.size; + if(b - a < 3){ + return fst; + } void *lst = self->buf + (b - 1)*ft->base.size; void *mid = self->buf + (a + b - 1)/2*ft->base.size; int ord = ft->cmp(&ft->base, fst, mid); int sorted; - if(!ord){ + if(!ord){// if *fst == *mid, then both are valid pivots regardless of *lst return mid; - }else if((sorted = ord*ft->cmp(&ft->base, mid, lst))){ - if(sorted > 0){ + }else if((sorted = ord*ft->cmp(&ft->base, mid, lst))){// multiplying the ord of *mid and *lst by the ord of *fst and *mid lets us easily detect if the sequence is monotonic + if(sorted > 0){// in this case, either *fst < *mid < *lst OR *fst > *mid > *lst return mid; - }else if(ft->cmp(&ft->base, lst, fst)*ord >= 0){ + }else if(ft->cmp(&ft->base, lst, fst)*ord >= 0){// if sorted < 0, *mid is either the max or min, determined by ord (the comparison between *fst and *mid) + return fst;// if the ord of *fst and *mid is the same as the ord of *lst and *fst, then either *lst < *fst < *mid or *lst > *fst > *mid. Alternatively, if *lst == *fst, ten both are valid pivots + }else{// otherwise, *fst is either the max or min, but *mid is also either the max or min, and since none of the three are equal in this case, we can conclude tht *lst is the median return lst; - }else{ - return fst; } - }else{ + }else{// if *fst != *mid but *mid == *lst, then both mid and lst are valid pivots regardless of *fst return mid; } } diff --git a/src/test/dlog_t64.c b/src/test/dlog_t64.c index 5048fd3..d408d67 100644 --- a/src/test/dlog_t64.c +++ b/src/test/dlog_t64.c @@ -1,8 +1,8 @@ -#include "crater/container.h" #include #include #include +#include #include const uint64_t gs[4] = {1, (1ull << 63) + 3, (1ull << 63) - 1, -1}; diff --git a/src/test/minmax_heap.c b/src/test/minmax_heap.c index f0d0f56..1da40c9 100644 --- a/src/test/minmax_heap.c +++ b/src/test/minmax_heap.c @@ -1,4 +1,3 @@ -#include "crater/container.h" #include "crater/vec.h" #include #include diff --git a/src/test/pandigital_primes.c b/src/test/pandigital_primes.c index 564fd05..7178f4c 100644 --- a/src/test/pandigital_primes.c +++ b/src/test/pandigital_primes.c @@ -1,5 +1,4 @@ //This test is based on Project Euler 41 -#include "crater/container.h" #include #include #include diff --git a/src/test/pointcloud.c b/src/test/pointcloud.c index 882a820..bd9220d 100644 --- a/src/test/pointcloud.c +++ b/src/test/pointcloud.c @@ -1,10 +1,10 @@ -#include "crater/kd_check.h" #include #include #include #include #include +#include #include int main(){ diff --git a/src/test/vec_bsearch.c b/src/test/vec_bsearch.c index 8629174..0fd27f0 100644 --- a/src/test/vec_bsearch.c +++ b/src/test/vec_bsearch.c @@ -1,4 +1,3 @@ -#include "crater/container.h" #include #include #include diff --git a/src/test/vec_oom.c b/src/test/vec_oom.c index fe084d4..69c9f91 100644 --- a/src/test/vec_oom.c +++ b/src/test/vec_oom.c @@ -1,13 +1,17 @@ #define _GNU_SOURCE -#include "crater/container.h" -#include "crater/vec.h" #include #include #include #include +#include #include +const char *__asan_default_options(){ + return "detect_leaks=0"; + // there is a bogus leak that asan finds but valgrind doesn't +} + inline static void default_copy(cr8r_base_ft *ft, void *dest, const void *src){ memcpy(dest, src, ft->size); } diff --git a/src/test/wc.c b/src/test/wc.c index f426d87..4ac1530 100644 --- a/src/test/wc.c +++ b/src/test/wc.c @@ -1,5 +1,4 @@ #define _POSIX_C_SOURCE 200809L -#include "crater/container.h" #include #include #include