/
ygl
/
test_statdata
Обзор
Документация
Войти
/
ygl
/
test_statdata
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/stat.c
176 строк
5 KB
user
togit
04 ноя 2025, 15:46
04 ноя 2025, 15:46
53c0af3
Код
Авторство
О чём код?
#include "stat.h" int StoreDump(const char* fn, const StatData* data, size_t size) { FILE* fp = fopen(fn, "wb"); if (!fp) { perror("fopen"); return EXIT_FAILURE; } size_t written = fwrite(data, sizeof(StatData), size, fp); fclose(fp); if (written != size) return EXIT_FAILURE; return 0; } int LoadDump(const char* fn, StatData** sdl, long* sdn) { FILE* fp = fopen(fn, "rb"); if (!fp) { perror("fopen"); return EXIT_FAILURE; } int fsk = fseek(fp, 0, SEEK_END); if (fsk != 0) { perror("fseek end"); return EXIT_FAILURE; }; long fs = ftell(fp); if (fs == -1) { perror("ftell"); return EXIT_FAILURE; }; *sdn = fs / sizeof(StatData); /* Проверка на размер По условию, массивы структур, с которыми оперируют программы имеют произвольную длину в диапазоне от 0 до 100000. два входных по 100000, на выходе 200000 */ if (*sdn > 200000) { fprintf(stderr, "LoadDump: size too large, %li\n", *sdn); fclose(fp); return EXIT_FAILURE; } *sdl = malloc(fs); if (*sdl == NULL) { fprintf(stderr, "out of memory\n"); return EXIT_FAILURE; } rewind(fp); const size_t fread_code = fread(*sdl, sizeof(StatData), *sdn, fp); if (fread_code != (size_t)(*sdn)) { perror("fread"); fclose(fp); free(*sdl); return EXIT_FAILURE; } fclose(fp); return 0; } void ht_insert(const StatData* s, HashSlot* table, size_t mask){ size_t h = (size_t)(s->id ^ (s->id * 113 >> 32)) & mask; for (;;){ if (!table[h].used){ table[h].used = 1; table[h].sd.id = s->id; table[h].sd.count = s->count; table[h].sd.cost = s->cost; table[h].sd.primary = s->primary; table[h].sd.mode = s->mode; return; } if (table[h].sd.id == s->id) { table[h].sd.count += s->count; table[h].sd.cost += s->cost; table[h].sd.primary &= s->primary; if (s->mode > table[h].sd.mode) table[h].sd.mode = s->mode; return; } h = (h + 1) & mask; } } int JoinDump( const StatData* a, long an, const StatData* b, long bn, StatData** r, long* rn) { /* размер хэш таблицы: cap = 2^(n+1) where 2^n > an+bn */ /* 2**16-1=262143 ; 262143 > 100000+100000 */ size_t total = an + bn; size_t cap = 2; while (cap < (total*2 + 1)) cap <<= 1; size_t mask = cap - 1; HashSlot *table = calloc(cap, sizeof(HashSlot)); if (!table) return EXIT_FAILURE; for (long i = 0; i < an; ++i) ht_insert(&a[i], table, mask); for (long i = 0; i < bn; ++i) ht_insert(&b[i], table, mask); StatData *res = malloc(total * sizeof(StatData)); if (!res) { free(table); return EXIT_FAILURE; } size_t ii = 0; for (size_t i = 0; i < cap; ++i) { if (table[i].used) { res[ii].id = table[i].sd.id; res[ii].count = table[i].sd.count; res[ii].cost = table[i].sd.cost; res[ii].primary = table[i].sd.primary; res[ii].mode = table[i].sd.mode; ++ii; } } free(table); /* Уменьшаем размер массива */ if (ii < total) { StatData *resized = realloc(res, sizeof(StatData) * ii); if (!resized) { free(res); return EXIT_FAILURE; } res = resized; } *r = res; *rn = ii; return 0; } /* Сравнение для qsort */ static int compare_cost(const void *a, const void *b) { const StatData *sa = (const StatData*)a; const StatData *sb = (const StatData*)b; if (sa->cost < sb->cost) return -1; if (sa->cost > sb->cost) return 1; return 0; } /* Сортировка по cost */ void SortDump(StatData *data, size_t count) { if (count > 1) { qsort(data, count, sizeof(StatData), compare_cost); } } #define ST_STATDATA_PRINT_LINES 10 /* Печатаем первые 10 записей в виде таблицы; */ void StatDataPrint(const StatData *sd, size_t n) { /* id в шестнадцатеричном виде; count в десятичном виде; cost в научном/экспоненциальном формате c 3 знаками после запятой (123 ->'1.230e+2'); primary нужно печатать "n" если оно 0 и "y" если оно 1; mode в бинарном формате ( 5 -> '101'); */ size_t to = n < ST_STATDATA_PRINT_LINES ? n : ST_STATDATA_PRINT_LINES; printf("%-18s | %8s | %12s | %7s | %4s\n", "id(hex)", "count", "cost", "primary", "mode"); for (size_t i = 0; i < to; ++i) { printf("0x%-16lx | %8d | %12.3e | %7s | %c%c%c\n", (unsigned long)sd[i].id, sd[i].count, (double)sd[i].cost, sd[i].primary ? "y" : "n", (sd[i].mode & 4) ? '1' : '0', (sd[i].mode & 2) ? '1' : '0', (sd[i].mode & 1) ? '1' : '0'); } }