diff --git a/ctl/ust.h b/ctl/ust.h index d39eab30..b59989c5 100644 --- a/ctl/ust.h +++ b/ctl/ust.h @@ -28,7 +28,6 @@ typedef struct A B** bucket; size_t size; size_t bucket_count; - int saturated; } A; @@ -185,21 +184,50 @@ JOIN(A, swap)(A* self, A* other) } static inline size_t -JOIN(A, closest_prime)(size_t number, int* saturated) -{ - static size_t primes[] = { - 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, - 103, 109, 113, 127, 137, 139, 149, 157, 167, 179, 193, 199, 211, 227, 241, 257, 277, 293, 313, 337, - 359, 383, 409, 439, 467, 503, 541, 577, 619, 661, 709, 761, 823, 887, 953, 1031, 1109, 1193, 1289, 1381, - 1493, 1613, 1741, 1879, 2029, 2179, 2357, 2549, 2753, 2971, 3209, 3469, 3739, 4027, 4349, - 4703, 5087, 5503, 5953, 6427, 6949, 7517, 8123, 8783, 9497, 10273, 11113, 12011, 12983, 14033, - 15173, 16411, 17749, 19183, 20753, 22447, 24281, 26267, 28411, 30727, 33223, 35933, 38873, 42043, 45481, - 49201, 53201, 57557, 62233, 67307, 72817, 78779, 85229, 92203, 99733, 107897, 116731, 126271, 136607, 147793, - 159871, 172933, 187091, 202409, 218971, 236897, 256279, 277261, 299951, 324503, 351061, 379787, 410857, 444487, - 480881, 520241, 562841, 608903, 658753, 712697, 771049, 834181, 902483, 976369, 1056323, 1142821, 1236397, 1337629, - 1447153, 1565659, 1693859, 1832561, 1982627, 2144977, 2320627, 2510653, 2716249, 2938679, 3179303, 3439651, 3721303, - 4026031, 4355707, 4712381, 5098259, 5515729, 5967347, 6456007, 6984629, 7556579, 8175383, 8844859, 9569143, 10352717, - 11200489, 12117689, 13109983, 14183539, 15345007, 16601593, 17961079, 19431899, 21023161, 22744717, 24607243 +JOIN(A, closest_prime)(size_t number) +{ + static uint32_t primes[] = { + 2, 3, 5, 7, 11, + 13, 17, 19, 23, 29, 31, + 37, 41, 43, 47, 53, 59, + 61, 67, 71, 73, 79, 83, + 89, 97, 103, 109, 113, 127, + 137, 139, 149, 157, 167, 179, + 193, 199, 211, 227, 241, 257, + 277, 293, 313, 337, 359, 383, + 409, 439, 467, 503, 541, 577, + 619, 661, 709, 761, 823, 887, + 953, 1031, 1109, 1193, 1289, 1381, + 1493, 1613, 1741, 1879, 2029, 2179, + 2357, 2549, 2753, 2971, 3209, 3469, + 3739, 4027, 4349, 4703, 5087, 5503, + 5953, 6427, 6949, 7517, 8123, 8783, + 9497, 10273, 11113, 12011, 12983, 14033, + 15173, 16411, 17749, 19183, 20753, 22447, + 24281, 26267, 28411, 30727, 33223, 35933, + 38873, 42043, 45481, 49201, 53201, 57557, + 62233, 67307, 72817, 78779, 85229, 92203, + 99733, 107897, 116731, 126271, 136607, 147793, + 159871, 172933, 187091, 202409, 218971, 236897, + 256279, 277261, 299951, 324503, 351061, 379787, + 410857, 444487, 480881, 520241, 562841, 608903, + 658753, 712697, 771049, 834181, 902483, 976369, + 1056323, 1142821, 1236397, 1337629, 1447153, 1565659, + 1693859, 1832561, 1982627, 2144977, 2320627, 2510653, + 2716249, 2938679, 3179303, 3439651, 3721303, 4026031, + 4355707, 4712381, 5098259, 5515729, 5967347, 6456007, + 6984629, 7556579, 8175383, 8844859, 9569143, 10352717, + 11200489, 12117689, 13109983, 14183539, 15345007, 16601593, + 17961079, 19431899, 21023161, 22744717, 24607243, 26622317, + 28802401, 31160981, 33712729, 36473443, 39460231, 42691603, + 46187573, 49969847, 54061849, 58488943, 63278561, 68460391, + 74066549, 80131819, 86693767, 93793069, 101473717, 109783337, + 118773397, 128499677, 139022417, 150406843, 162723577, 176048909, + 190465427, 206062531, 222936881, 241193053, 260944219, 282312799, + 305431229, 330442829, 357502601, 386778277, 418451333, 452718089, + 489790921, 529899637, 573292817, 620239453, 671030513, 725980837, + 785430967, 849749479, 919334987, 994618837, 1076067617, 1164186217, + 1259520799, 1362662261, 1474249943, 1594975441, 1725587117, }; size_t min = primes[0]; if(number < min) @@ -212,8 +240,6 @@ JOIN(A, closest_prime)(size_t number, int* saturated) if(number >= a && number <= b) return number == a ? a : b; } - if(saturated) - *saturated = 1; return primes[size - 1]; } @@ -272,31 +298,29 @@ JOIN(A, rehash)(A* self, size_t desired_count); static inline void JOIN(A, reserve)(A* self, size_t desired_count) { - if(!self->saturated) + if(self->size > 0) + JOIN(A, rehash)(self, desired_count); + else { - if(self->size > 0) - JOIN(A, rehash)(self, desired_count); - else - { - size_t bucket_count = JOIN(A, closest_prime)(desired_count, &self->saturated); - B** temp = (B**) calloc(bucket_count, sizeof(B*)); - for(size_t i = 0; i < self->bucket_count; i++) - temp[i] = self->bucket[i]; - free(self->bucket); - self->bucket = temp; - self->bucket_count = bucket_count; - } + size_t bucket_count = JOIN(A, closest_prime)(desired_count); + B** temp = (B**) calloc(bucket_count, sizeof(B*)); + for(size_t i = 0; i < self->bucket_count; i++) + temp[i] = self->bucket[i]; + free(self->bucket); + self->bucket = temp; + self->bucket_count = bucket_count; } } static inline void JOIN(A, rehash)(A* self, size_t desired_count) { - if(!self->saturated) + if(desired_count <= self->size) + desired_count = self->size + 1; + size_t expected = JOIN(A, closest_prime)(desired_count); + if(expected != self->bucket_count) { A rehashed = JOIN(A, init)(self->hash, self->equal); - if(desired_count <= self->size) - desired_count = self->size + 1; JOIN(A, reserve)(&rehashed, desired_count); foreach(A, self, it) { diff --git a/tests/func/test_c11.c b/tests/func/test_c11.c index b5edc2bd..0c1accd6 100644 --- a/tests/func/test_c11.c +++ b/tests/func/test_c11.c @@ -9,6 +9,10 @@ #define T int #include +#define P +#define T float +#include + size_t int_hash(int* x) { return abs(*x); } @@ -17,6 +21,14 @@ int int_equal(int* a, int* b) { return *a == *b; } +size_t +float_hash(float* x) +{ return abs((int) *x); } + +int +float_equal(float* a, float* b) +{ return *a == *b; } + #define P #define T int #include @@ -199,55 +211,18 @@ main(void) ust_int_insert(&a, -5); ust_int_insert(&a, -6); ust_int_insert(&a, -7); - ust_int_insert(&a, -8); - ust_int_insert(&a, -9); - ust_int_insert(&a, -10); - ust_int_insert(&a, -11); - ust_int_insert(&a, -12); - ust_int_insert(&a, -13); - ust_int_insert(&a, -14); - ust_int_insert(&a, -15); - ust_int_insert(&a, -16); - ust_int_insert(&a, -17); - ust_int_insert(&a, -18); - ust_int_insert(&a, -19); - ust_int_insert(&a, -20); - ust_int_insert(&a, -21); - ust_int_insert(&a, -22); - ust_int_insert(&a, -23); - ust_int_insert(&a, -24); - ust_int_insert(&a, -25); - ust_int_insert(&a, -26); - ust_int_insert(&a, -27); - ust_int_insert(&a, 0); - ust_int_insert(&a, 1); - ust_int_insert(&a, 2); - ust_int_insert(&a, 3); - ust_int_insert(&a, 4); - ust_int_insert(&a, 5); - ust_int_insert(&a, 6); - ust_int_insert(&a, 7); - ust_int_insert(&a, 8); - ust_int_insert(&a, 9); - ust_int_insert(&a, 10); - ust_int_insert(&a, 11); - ust_int_insert(&a, 12); - ust_int_insert(&a, 13); - ust_int_insert(&a, 14); - ust_int_insert(&a, 15); - ust_int_insert(&a, 16); - ust_int_insert(&a, 17); - ust_int_insert(&a, 18); - ust_int_insert(&a, 19); - ust_int_insert(&a, 20); - ust_int_insert(&a, 21); - ust_int_insert(&a, 22); - ust_int_insert(&a, 23); - ust_int_insert(&a, 24); - ust_int_insert(&a, 25); - ust_int_insert(&a, 26); - ust_int_insert(&a, 27); ust_int_free(&a); + }{ + ust_float a = ust_float_init(float_hash, float_equal); + ust_float_insert(&a, -0); + ust_float_insert(&a, -1); + ust_float_insert(&a, -2); + ust_float_insert(&a, -3); + ust_float_insert(&a, -4); + ust_float_insert(&a, -5); + ust_float_insert(&a, -6); + ust_float_insert(&a, -7); + ust_float_free(&a); } TEST_PASS(__FILE__); }