From cce51386bf976ebc34ef530f32e1e9378ce43e3b Mon Sep 17 00:00:00 2001 From: Dmitrii Krosh Date: Fri, 24 Jul 2026 06:29:08 +0300 Subject: [PATCH] some upgrades --- reimplement/newset.c | 41 +++++++++++----- reimplement/newset_f.c | 108 ----------------------------------------- 2 files changed, 28 insertions(+), 121 deletions(-) delete mode 100644 reimplement/newset_f.c diff --git a/reimplement/newset.c b/reimplement/newset.c index fe014a4..2e25751 100644 --- a/reimplement/newset.c +++ b/reimplement/newset.c @@ -1,10 +1,14 @@ #include #include #include +#include #include "rpmlib.h" -#include "stdint.h" -#include "stdio.h" +#ifdef SELF_TEST +#undef NDEBUG +#include +#endif +#include "set.h" #include "system.h" #define CACHE_SIZE 256 @@ -343,16 +347,27 @@ static int char_to_num(char c) { return 0xee; // invalid character } -// надо посмотреть, насколько в действительности это делает хуже -static char* putnbits(int n, int c, char* bit_pt) { - for (int i = 0; i < n; ++i) { - *bit_pt++ = (c >> i) & 1; - } +static char* put6bits(int c, char* bit_pt) { + *bit_pt++ = (c >> 0) & 1; + *bit_pt++ = (c >> 1) & 1; + *bit_pt++ = (c >> 2) & 1; + *bit_pt++ = (c >> 3) & 1; + *bit_pt++ = (c >> 4) & 1; + *bit_pt++ = (c >> 5) & 1; return bit_pt; } -// Main base62 decoding routine: unpack base62 string into bitv[]. +static char* put4bits(int c, char* bit_pt) { + *bit_pt++ = (c >> 0) & 1; + *bit_pt++ = (c >> 1) & 1; + *bit_pt++ = (c >> 2) & 1; + *bit_pt++ = (c >> 3) & 1; + + return bit_pt; +} + +// Main base62 decoding routine: unpack base62 string into bit_pt[]. static int decode_base62(const char* base62_str, char* bit_pt) { char* bit_start = bit_pt; @@ -361,7 +376,7 @@ static int decode_base62(const char* base62_str, char* bit_pt) { if (num6b == 0xee) return -1; if (num6b < 61) { - bit_pt = putnbits(6, num6b, bit_pt); + bit_pt = put6bits(num6b, bit_pt); } else { assert(num6b == 61); // 61 62 63 cases @@ -375,8 +390,8 @@ static int decode_base62(const char* base62_str, char* bit_pt) { num4b &= ~mask; // low bits assert(num2b != mask); // not both bits set - bit_pt = putnbits(6, 61 + (num2b >> 4), bit_pt); // 61 + (0|1|2) in high bits - bit_pt = putnbits(4, num4b, bit_pt); + bit_pt = put6bits(61 + (num2b >> 4), bit_pt); // 61 + (0|1|2) in high bits + bit_pt = put4bits(num4b, bit_pt); } num6b = char_to_num(*base62_str++); @@ -510,13 +525,13 @@ static int cache_decode_set(const char* str, const unsigned** hash_pt) { // decode int len = strlen(str); int cnt = decode_set_size(str); - ent = xmalloc(sizeof(*ent) + len + 1 + (cnt + SENTINELS) * sizeof(unsigned)); + ent = malloc(sizeof(*ent) + len + 1 + (cnt + SENTINELS) * sizeof(unsigned)); ent->hash_arr = (unsigned*)(ent + 1); ent->str = (char*)(ent->hash_arr + cnt + SENTINELS); cnt = ent->cnt = decode_set(str, ent->hash_arr); if (cnt <= 0) { - _free(ent); + free(ent); return cnt; } diff --git a/reimplement/newset_f.c b/reimplement/newset_f.c deleted file mode 100644 index 7038f8c..0000000 --- a/reimplement/newset_f.c +++ /dev/null @@ -1,108 +0,0 @@ -#include "stdint.h" -#include "stdio.h" -#include "system.h" - -struct set { - size_t cnt; - struct symbols { - const char* str; - uint64_t hash; - }* symbols_v; -}; - -struct set* set_new() { - // should we use x___ funcs? - struct set* set = xmalloc(sizeof *set); - set->cnt = 0; - set->symbols_v = NULL; - - return set; -} - -void set_add(struct set* set, const char* sym) { - const int delta = 1024; - - if (set->cnt % delta == 0) { - set->symbols_v = xrealloc(set->symbols_v, sizeof(*set->symbols_v) * (set->cnt + delta)); - } - - set->symbols_v[set->cnt].str = xstrdup(sym); - set->symbols_v[set->cnt].hash = 0; - set->cnt++; - - return; -} - -struct set* set_free(struct set* set) { - if (set) { - for (size_t i = 0; i < set->cnt; ++i) { - _free((char*)set->symbols_v[i].str); - } - - _free(set->symbols_v); - set = _free(set); - } - - return NULL; -} - -// --- - -uint64_t hash(const char* str) { - uint64_t h = 0xcbf29ce484222325ULL; - - while (*str) { - h ^= (uint64_t)(unsigned char)(*str++); - h *= 0x100000001b3ULL; - } - - return h; -} - -int cmp(const void* arg1, const void* arg2) { - const struct symbols* s1 = (const struct symbols*)arg1; - const struct symbols* s2 = (const struct symbols*)arg2; - - if (s1->hash > s2->hash) return 1; - if (s2->hash > s1->hash) return -1; - - return 0; -} - -const char* set_fini(struct set* set, int bpp) { - // Implementation for finalizing the set - - assert(set != NULL); - assert(set->cnt > 0); - assert(bpp >= 10 && bpp <= 63); - - uint64_t mask = (1ULL << bpp) - 1; - - for (size_t i = 0; i < set->cnt; ++i) { - set->symbols_v[i].hash = hash(set->symbols_v[i].str) & mask; - } - - qsort(set->symbols_v, set->cnt, sizeof *set->symbols_v, cmp); - - // warn on hash collizions - for (size_t i = 0; i < set->cnt - 1; ++i) { - if (set->symbols_v[i].hash != set->symbols_v[i + 1].hash) continue; - if (!strcmp(set->symbols_v[i].str, set->symbols_v[i + 1].str)) continue; - - fprintf(stderr, "warning: hash collision: %s %s\n", set->symbols_v[i].str, - set->symbols_v[i + 1].str); - } - - uint64_t unique_hash[set->cnt]; - size_t unique_cnt = 0; - - // delete duplicates - for (size_t i = 0; i < set->cnt; ++i) { - while (i + 1 < set->cnt && set->symbols_v[i].hash == set->symbols_v[i + 1].hash) { - ++i; - } - unique_hash[unique_cnt++] = set->symbols_v[i].hash; - } - - return NULL; -}