rewrite for compability

This commit is contained in:
2026-07-14 15:46:22 +03:00
parent e39d6b2401
commit 0628c9ba48
2 changed files with 128 additions and 17 deletions
+20 -17
View File
@@ -2,24 +2,11 @@
#include "stdio.h"
#include "system.h"
uint64_t hash(const char* str) {
uint64_t h = 0xcbf29ce484222325ULL;
while (*str) {
h ^= (uint64_t)(unsigned char)(*str++);
h *= 0x100000001b3ULL;
}
return h;
}
// ---
struct set {
size_t cnt;
struct symbols {
const char* str;
uint64_t hash;
int hash;
}* symbols_v;
};
@@ -61,6 +48,20 @@ struct set* set_free(struct set* set) {
// ---
static unsigned int hash(const char* str) {
unsigned int hash = 0x9e3779b9;
const unsigned char* p = (const unsigned char*)str;
while (*p) {
hash += *p++;
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return hash;
}
int cmp(const void* arg1, const void* arg2) {
const struct symbols* s1 = arg1;
const struct symbols* s2 = arg2;
@@ -76,9 +77,9 @@ const char* set_fini(struct set* set, int bpp) {
assert(set != NULL);
assert(set->cnt > 0);
assert(bpp >= 10 && bpp <= 63);
assert(bpp >= 10 && bpp <= 32);
uint64_t mask = (1ULL << bpp) - 1;
int mask = (bpp < 32) ? (1u << bpp) - 1 : ~0u;
for (size_t i = 0; i < set->cnt; ++i) {
set->symbols_v[i].hash = hash(set->symbols_v[i].str) & mask;
@@ -86,6 +87,7 @@ const char* set_fini(struct set* set, int bpp) {
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;
@@ -94,9 +96,10 @@ const char* set_fini(struct set* set, int bpp) {
set->symbols_v[i + 1].str);
}
uint64_t unique_hash[set->cnt];
int 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;