Добавлена серелизация. исправлены малые ошибки.

This commit is contained in:
romenskiy 2025-07-03 09:33:43 +03:00
parent 228f0baef3
commit 36c2faf176
8 changed files with 366 additions and 20 deletions

BIN
.file.h.kate-swp Normal file

Binary file not shown.

View file

@ -3,6 +3,13 @@ cmake_minimum_required(VERSION 3.0)
project(webdisk_c LANGUAGES C)
add_executable(webdisk_c main.c cJSON/cJSON.c)
set (CMAKE_C_FLAGS "-g -O3 -ljemalloc -L /usr/lib64/libjemalloc.so")
set (CMAKE_C_FLAGS "-g -O3 -DUSE_JEMALLOC")# -DUSE_JEMALLOC
target_link_libraries(webdisk_c jemalloc)
target_include_directories(webdisk_c PRIVATE
"${CMAKE_SOURCE_DIR}/jemalloc/build/include"
)
# Правильно указываем папку с .so для линковки
target_link_directories(webdisk_c PRIVATE
"${CMAKE_SOURCE_DIR}/jemalloc/build/lib"
)
install(TARGETS webdisk_c RUNTIME DESTINATION bin)

43
args_parser.h Normal file
View file

@ -0,0 +1,43 @@
#pragma once
#include <getopt.h>
void print_help(const char *progname) {
printf("Использование: %s [опции]\n", progname);
printf(" -h, --help показать это сообщение\n");
printf(" -r, --recursion N указать глубину json\n");
printf(" -j, --json вывод в виде json\n");
}
void aaa(int* argc, char *argv[]){
const struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"recursion", required_argument, 0, 'r'},
{"json", no_argument, 0, 'j'},
{0, 0, 0, 0}
};
int opt;
while ((opt = getopt_long(*argc, argv, "hr:j", long_options, NULL)) != -1) {
switch (opt) {
case 'h':
print_help(argv[0]);
exit(0);
break;
case 'r':
opts.recursion = atoi(optarg);
break;
case 'j':
opts.json = 1;
break;
default:
print_help(argv[0]);
exit(1);
}
}
}

246
file.h Normal file
View file

@ -0,0 +1,246 @@
#pragma once
/*
struct dir_list_struct{
struct metadata* top;
struct metadata* file;
struct dir_list_struct* next;
};
typedef struct metadata {
char* name;
bool tipe_dir;
long int size;
struct dir_list_struct* dir_list;
struct metadata* top;
struct dir_list_struct* jamp;
} stack_element;
*/
struct NodeDisk {
uint32_t id;
uint32_t parent_id;
uint32_t first_child_id;
uint32_t next_sibling_id;
uint64_t name_offset; // смещение имени в файле имён
uint32_t name_len; // длина имени, опционально
uint64_t type;
// другие ваши поля
};
/*
// Файл 1: структура дерева
void serialize_tree(Node *node, FILE *f_struct, FILE *f_names, uint64_t *names_offset) {
FILE *f_nodes = fopen("nodes.bin", "wb");
struct NodeDisk disk;
disk.type = node->type;
disk.name_offset = *names_offset;
// Сохраняем имя во второй файл
uint16_t len = strlen(node->name);
fwrite(&len, 2, 1, f_names);
fwrite(node->name, 1, len, f_names);
*names_offset += 2 + len;
fwrite(&disk, sizeof(disk), 1, f_struct);
for (Node *child = node->first_child; child; child = child->next_sibling)
serialize_tree(child, f_struct, f_names, names_offset);
uint8_t end = END_MARKER;
fwrite(&end, 1, 1, f_struct); // Маркер конца детей
}
*/
#define DOWN_MARKER 0xFE
#define END_MARKER 0xFF
struct metadata_file {
uint64_t name_offset;
bool tipe_dir;
long int size;
};
void name_file_w(char* name, FILE * f_names, uint64_t *names_offset){
uint16_t len = strlen(name);
fwrite(&len, sizeof(uint16_t), 1, f_names);
fwrite(name, 1, len, f_names);
names_offset += len + sizeof(uint16_t);
}
void nodes_file_w(struct metadata* meta, FILE * f_nodes, uint64_t *nodes_offset, uint64_t names_offset){
struct metadata_file file;
file.name_offset = names_offset;
file.size = meta->size;
file.tipe_dir = meta->tipe_dir;
fwrite(&file, 1, sizeof(struct metadata_file), f_nodes);
nodes_offset += sizeof(struct metadata_file);
}
void aaasss(struct dir_list_struct* dir_list, struct metadata* mata_local, struct metadata* mata_local_top, FILE *f_nodes, FILE *f_names, int* marker, uint16_t* len){
if (NULL != dir_list->file){
dir_list = dir_list->next;
dir_list = je_malloc(sizeof(struct dir_list_struct));
}
mata_local = malloc(sizeof(struct metadata));
// Это не маркер — значит начало структуры!
ungetc(*marker, f_nodes); // возвращаем байт обратно
struct metadata_file file;
fread(&file, sizeof(file), 1, f_nodes);
mata_local->size = file.size;
mata_local->tipe_dir = file.tipe_dir;
fread(len, 1, sizeof(uint16_t), f_names);
mata_local->name = malloc(*len+1);
fread(mata_local->name, 1, *len, f_names);
printf("Файл: %s\n", mata_local->name);
// Дальше обработка структуры...
dir_list->top = mata_local_top;
mata_local->top = mata_local_top;
dir_list->file = mata_local;
*marker = fgetc(f_nodes);
}
void nanaaa_2(struct metadata* mata){
FILE *f_nodes = fopen("nodes.bin", "rb");
FILE *f_names = fopen("names.bin", "rb");
struct metadata_file file, file_2;
uint16_t len;
struct metadata* mata_local = mata;
struct metadata* mata_local_top = mata;
mata_local->name = "./";
struct dir_list_struct* dir_list = je_malloc(sizeof(struct dir_list_struct));
mata_local->dir_list = dir_list;
int marker = fgetc(f_nodes);
while(marker != EOF){
if (marker == 0xFF){
if (mata_local->jamp != NULL && mata_local->jamp->next != NULL ){
dir_list = mata_local->jamp->next;
mata_local = mata_local->jamp->next->file;
aaasss(dir_list, mata_local, mata_local_top, f_nodes, f_names, &marker, &len);
}
else{
DEBUG_PRINT("Контлоьные точки закончелись, поднимаюсь!\n");
if (mata_local->top == NULL){
printf("Подём отменён!\n");
break;
}
aaasss(dir_list, mata_local, mata_local_top, f_nodes, f_names, &marker, &len);
DEBUG_PRINT("Подём!\n");
mata_local = mata_local->top;
}
dir_list = mata_local->jamp->next;
//if (dir_list == NULL) printf("ПИЗДЕЦ\n");
//dir_list = je_malloc(sizeof(struct dir_list_struct));
//aaasss(dir_list, mata_local, mata_local_top, f_nodes, f_names, &marker, &len);
dir_list->file = mata_local;
mata_local = dir_list->file;
// END_MARKER: конец детей, возвращаемся наверх
//return;
continue;
}else if (marker == 0xFE){
printf("SAS_xxxx\n");
mata_local->jamp = dir_list;
//struct dir_list_struct* dir_list = je_malloc(sizeof(struct dir_list_struct));
mata_local->dir_list = dir_list;
mata_local->top = mata_local_top;
aaasss(dir_list, mata_local, mata_local_top, f_nodes, f_names, &marker, &len);
// DOWN_MARKER: начало детей, идём вниз
// Ваша логика: вызывать рекурсивный парсер детей
}else{
printf("SAS_AAA\n");
aaasss(dir_list, mata_local, mata_local_top, f_nodes, f_names, &marker, &len);
dir_list = dir_list->next;
dir_list = je_malloc(sizeof(struct dir_list_struct));
}
}
fread(&file, 1, sizeof(struct metadata_file), f_nodes);
fread(&len, 1, sizeof(uint16_t), f_names);
fread(&file_2, 1, len, f_names);
file.name_offset;
char* name;
//printf("Файл: %s\n", name);
}
void nanaaa(struct metadata* mata){
uint64_t names_offset = 0;
uint64_t nodes_offset = 0;
FILE *f_nodes = fopen("nodes.bin", "wb");
FILE *f_names = fopen("names.bin", "wb");
struct metadata *meta_data, *meta_data_tmp;
meta_data = mata;
if (meta_data->dir_list == NULL)
meta_data->jamp = meta_data->dir_list;
struct dir_list_struct* global_dir_list = meta_data->dir_list;
while(1){
DEBUG_PRINT("Цикол!\n");
while(global_dir_list != NULL){
DEBUG_PRINT("%s" ,"while global_dir_list\n");
if (global_dir_list->file->tipe_dir){
DEBUG_PRINT("Выполняю прыжок вниз!\n");
DEBUG_PRINT("%s%s",global_dir_list->file->name ," AAA \n");
meta_data_tmp = global_dir_list->file;
DEBUG_PRINT("%s --- dd\n", global_dir_list->file->name);
meta_data_tmp->jamp = global_dir_list;
meta_data = meta_data_tmp;
global_dir_list = meta_data->dir_list;
//printf("Name0: %s\n", meta_data->name);
nodes_file_w(meta_data, f_nodes, &nodes_offset, names_offset);
name_file_w(meta_data->name, f_names, &names_offset);
//fwrite(meta_data->name, 1, sizeof(struct metadata), f_names);
fputc(DOWN_MARKER, f_nodes);
break;
}
else{
DEBUG_PRINT("Нaйден файл: %s\n",global_dir_list->file->name);
//printf("Name1: %s\n", global_dir_list->file->name);
nodes_file_w(global_dir_list->file, f_nodes, &nodes_offset, names_offset);
name_file_w(global_dir_list->file->name, f_names, &names_offset);
global_dir_list = global_dir_list->next;
DEBUG_PRINT("Прыгаю вперёд!\n");
}
}
if (global_dir_list == NULL){
DEBUG_PRINT("Глобальный список закончен, прыгаю верх за контрольную точку!\n");
if (meta_data->jamp != NULL && meta_data->jamp->next != NULL ){
global_dir_list = meta_data->jamp->next;
meta_data = meta_data->jamp->next->file;
fputc(END_MARKER, f_nodes);
}
else{
DEBUG_PRINT("Контлоьные точки закончелись, поднимаюсь!\n");
if (meta_data->top == NULL){
DEBUG_PRINT("Подём отменён!\n");
break;
}
fputc(END_MARKER, f_nodes);
DEBUG_PRINT("Подём!\n");
meta_data = meta_data->top;
}
}
}
DEBUG_PRINT("Готово!\n");
}
/*
void file_weit(struct metadata mata){
FILE *f_nodes = fopen("nodes.bin", "wb");
FILE *f_names = fopen("names.bin", "wb");
uint64_t names_offset = 0;
struct metadata mata_local = mata;
fwrite(&mata_local, 1, sizeof(struct metadata), f_nodes);
for (){
}
mata
for (int i = 0; i < num_nodes; ++i) {
NodeDisk n = ...;
// имя
n.name_offset = names_offset;
n.name_len = strlen(node[i].name);
fwrite(node[i].name, 1, n.name_len, f_names);
names_offset += n.name_len;
fwrite(&n, sizeof(n), 1, f_nodes);
}
}
*/

1
jemalloc Submodule

@ -0,0 +1 @@
Subproject commit 1972241cd204c60fb5b66f23c48a117879636161

76
main.c
View file

@ -11,13 +11,25 @@
#include <pthread.h>
#include "cJSON/cJSON.h"
#define bool unsigned char
#ifdef USE_JEMALLOC
const char *je_malloc_conf = "narenas:2,lg_chunk:20,stats_print:false";
#include <jemalloc/jemalloc.h>
#else
#define je_malloc(size) malloc(size)
#define je_calloc(nmemb, size) calloc((nmemb), (size))
#define je_realloc(ptr, size) realloc((ptr), (size))
#define je_free(ptr) free((ptr))
#endif
unsigned narenas = 4;
//#define bool unsigned char
#define DEBUG 0
#define jemalloc 0
#if defined(DEBUG) && DEBUG > 1
#define DEBUG_PRINT(fmt, args...) fprintf(stderr, "DEBUG: %s:%d:%s(): " fmt, \
@ -29,6 +41,12 @@ unsigned narenas = 4;
#define DEBUG_PRINT(fmt, args...) /* Don't do anything in release builds */
#endif
struct opts_struct{
int recursion;
int json;
};
struct opts_struct opts;
struct tred_pizdec{
char* name;
long int* size;
@ -49,6 +67,10 @@ typedef struct metadata {
struct dir_list_struct* jamp;
} stack_element;
#include "file.h"
#include "args_parser.h"
void dir_list_struct_init(struct dir_list_struct* dir_list_struct){
dir_list_struct->top = NULL;
dir_list_struct->file = NULL;
@ -121,15 +143,16 @@ struct metadata* metadata_create(bool tipe_dir,char* path, struct metadata* top)
mata->size = mata->size;
//struct metadata* mata_2 = mata;
struct tred_pizdec* mata_2 = malloc(sizeof(struct tred_pizdec));
/*
struct tred_pizdec* mata_2 = je_malloc(sizeof(struct tred_pizdec));
mata_2->name = path;
mata_2->size = &mata->size;
pthread_t thread;
pthread_create(&thread, NULL, get_file_size_multi_tred, (void*)mata_2);
pthread_join(thread, NULL);
*/
//mata->size = get_file_size(path);
mata->size = get_file_size(path);
DEBUG_PRINT("Объём:%li - %s\n", mata->size, mata->name);
}
return mata;
@ -140,23 +163,19 @@ void scanning(struct metadata *mata){
DIR *dp;
bool AAA = 1;
dp = opendir(mata->name);
//printf("TEST: %s\n", mata->name);
DEBUG_PRINT("TEST: %s\n", mata->name);
struct dir_list_struct* put_2;
DEBUG_PRINT("XXXXXXXXXXXXX_1!\n");
DEBUG_PRINT("One\n");
DEBUG_PRINT("%i\n", errno);
/*
if (errno == 2){
printf("Нет такого файла или каталога!\n");
//printf("%s\n", strerror(errno));
printf("file: %s\n", mata->name);
}
if (errno == 22){
else if (errno == 22){
printf("Недопустимый аргумент!\n");
//printf("%s\n", strerror(errno));
printf("file: %s\n", mata->name);
}
*/
if (errno == 13){
printf("Отказ в доступе!\n");
//printf("%s\n", strerror(errno));
@ -164,10 +183,13 @@ void scanning(struct metadata *mata){
else{
entry = readdir(dp);
}
printf("Нет такого файла или каталога!\n");
//printf("TEST: %s\n", mata->name);
DEBUG_PRINT("TEST: %s\n", mata->name);
struct dir_list_struct* put_2;
//printf("%s\n", strerror(errno));
printf("file: %s\n", mata->name);
DEBUG_PRINT("Two\n");
while(entry != NULL){
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0){
entry = readdir(dp);
@ -179,7 +201,7 @@ void scanning(struct metadata *mata){
DEBUG_PRINT("mata->name обём: %li\n",(strlen(mata->name) * sizeof(char)));
DEBUG_PRINT("entry->d_name обём: %li\n",(strlen(entry->d_name) * sizeof(char)));
char* putaa = malloc(strlen(mata->name) + (strlen(entry->d_name)) + 2);
char* putaa = je_malloc(strlen(mata->name) + (strlen(entry->d_name)) + 2);
//snprintf(putaa, path_len, "%s/%s", mata->name, entry->d_name);
//char* putaa = malloc(sizeof(mata->name) + sizeof(entry->d_name) + sizeof(char));
@ -195,14 +217,14 @@ void scanning(struct metadata *mata){
}
DEBUG_PRINT("SAS готов! \n");
if (AAA){
put_2 = malloc(sizeof(struct dir_list_struct));
put_2 = je_malloc(sizeof(struct dir_list_struct));
dir_list_struct_init(put_2);
DEBUG_PRINT("put_2 1 готов!\n");
mata->dir_list = put_2;
AAA = 0;
}
else{
put_2->next = malloc(sizeof(struct dir_list_struct));
put_2->next = je_malloc(sizeof(struct dir_list_struct));
dir_list_struct_init(put_2->next);
DEBUG_PRINT("put_2 2 готов! \n");
put_2 = put_2->next;
@ -438,12 +460,24 @@ int main(int argc, char *argv[]){
int_depth= opts.r_value;
path = opts.path;
struct metadata * mata = malloc(sizeof(stack_element));
struct metadata * mata = je_malloc(sizeof(stack_element));
meta_data_init(mata);
mata->name = path;
mata->tipe_dir = 1;
scanning(mata);
scan_dir(mata);
/*
struct metadata * mata = je_malloc(sizeof(stack_element));
nanaaa_2(mata);
printf("AAAA0: %s\n", mata->name);
printf("AAAA1: %s\n", mata->dir_list->file->name);
printf("tipe_dir: %i\n", mata->dir_list->file->tipe_dir);
printf("size: %li\n", mata->dir_list->file->size);
if (mata->dir_list->next == NULL) printf("SUKA\n");
printf("AAAA2: %s\n", mata->dir_list->next->file->name);
//printf("AAAA2: %s\n", mata->dir_list->file->dir_list->file->name);
*/
char output[64];
struct dir_list_struct* list = mata->dir_list;
@ -457,5 +491,11 @@ int main(int argc, char *argv[]){
DEBUG_PRINT("ччччч!\n");
printf("AA: %s\n", string);
printf("%s","bye.\n");
//file_weit(mata);
nanaaa(mata);
return 0;
}

9
tmp Normal file
View file

@ -0,0 +1,9 @@
git clone https://github.com/jemalloc/jemalloc.git
cd jemalloc
./autogen.sh
mkdir build
cd build
../configure --prefix=$PWD/local
make -j$(nproc)

BIN
webdisk_c Executable file

Binary file not shown.