few more lines

This commit is contained in:
2026-07-13 23:38:49 +03:00
parent b1e47622ae
commit e39d6b2401
2 changed files with 66 additions and 4 deletions
+60 -4
View File
@@ -1,10 +1,25 @@
#include "stdint.h"
#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 {
int cnt;
size_t cnt;
struct symbols {
const char* str;
unsigned hash;
uint64_t hash;
}* symbols_v;
};
@@ -20,7 +35,7 @@ struct set* set_new() {
void set_add(struct set* set, const char* sym) {
const int delta = 1024;
if ((set->cnt & (delta - 1)) == 0) {
if (set->cnt % delta == 0) {
set->symbols_v = xrealloc(set->symbols_v, sizeof(*set->symbols_v) * (set->cnt + delta));
}
@@ -33,7 +48,7 @@ void set_add(struct set* set, const char* sym) {
struct set* set_free(struct set* set) {
if (set) {
for (int i = 0; i < set->cnt; i++) {
for (size_t i = 0; i < set->cnt; ++i) {
_free((char*)set->symbols_v[i].str);
}
@@ -46,7 +61,48 @@ struct set* set_free(struct set* set) {
// ---
int cmp(const void* arg1, const void* arg2) {
const struct symbols* s1 = arg1;
const struct symbols* s2 = 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);
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;
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;
}
+6
View File
@@ -21,6 +21,7 @@
7. Оптимизации при создании строк:
- сторонняя хэш функция
- также даёт преимущество на 64 бит хэше ("на всякий")
- пока что всё равно остановимся на 64
8. Возможно изменение структуры кода для читаемости, например:
- много init функций
@@ -28,4 +29,9 @@
9. А какую реализацию оставляем?..
## notes
все оптимизации с таблицей более не имеют смысла, т.к. раскодирование сразу по 6 бит гарантированно
И даже если такую делать, то размер бинаря +19 Мб. А вот создание хэша для такого теоритически возможно.
!!! `lib/rpmds.c` стоит исследовать, т.к. сейчас есть шанс, что это единственное место, где используется оптимизация кэширования, если исользуется вовсе