#include "common.h"  
#include <stdio.h>  

// 堆排序实现  
void heapify(FrequencyItem *arr, size_t n, size_t i) {  
    size_t largest = i;  
    size_t left = 2 * i + 1;  
    size_t right = 2 * i + 2;  

    // 比较频率，频率相同时比较字节值  
    if (left < n && (arr[left].frequency > arr[largest].frequency ||   
        (arr[left].frequency == arr[largest].frequency &&   
         arr[left].byte < arr[largest].byte))) {  
        largest = left;  
    }  

    if (right < n && (arr[right].frequency > arr[largest].frequency ||   
        (arr[right].frequency == arr[largest].frequency &&   
         arr[right].byte < arr[largest].byte))) {  
        largest = right;  
    }  

    if (largest != i) {  
        FrequencyItem temp = arr[i];  
        arr[i] = arr[largest];  
        arr[largest] = temp;  
        heapify(arr, n, largest);  
    }  
}  

void heap_sort(FrequencyItem *arr, size_t n) {  
    // 构建最大堆  
    for (int i = n / 2 - 1; i >= 0; i--)  
        heapify(arr, n, i);  

    // 逐个从堆中取出元素  
    for (int i = n - 1; i > 0; i--) {  
        FrequencyItem temp = arr[0];  
        arr[0] = arr[i];  
        arr[i] = temp;  
        heapify(arr, i, 0);  
    }  
}  


uint64_t fnv1a_64(const void* data, size_t len) {  
    const uint64_t FNV_PRIME = 1099511628211ULL;  
    const uint64_t FNV_OFFSET = 14695981039346656037ULL;  
    
    uint64_t hash = FNV_OFFSET;  
    const unsigned char* bytes = (const unsigned char*)data;  
    
    for (size_t i = 0; i < len; i++) {  
        hash ^= bytes[i];  
        hash *= FNV_PRIME;  
    }  
    
    return hash;  
}  

// 文件操作辅助函数实现  
size_t get_file_size(const char *filename) {  
    FILE *file = fopen(filename, "rb");  
    if (!file) return 0;  
    
    fseek(file, 0, SEEK_END);  
    size_t size = ftell(file);  
    fclose(file);  
    
    return size;  
}  

int read_file_content(const char *filename, unsigned char **content, size_t *size) {  
    *size = get_file_size(filename);  
    if (*size == 0) return -1;  

    *content = (unsigned char *)malloc(*size);  
    if (!*content) return -1;  

    FILE *file = fopen(filename, "rb");  
    if (!file) {  
        free(*content);  
        return -1;  
    }  

    size_t read_size = fread(*content, 1, *size, file);  
    fclose(file);  

    if (read_size != *size) {  
        free(*content);  
        return -1;  
    }  

    return 0;  
}
