diff --git a/.file.h.kate-swp b/.file.h.kate-swp new file mode 100644 index 0000000..1d91b92 Binary files /dev/null and b/.file.h.kate-swp differ diff --git a/CMakeLists.txt b/CMakeLists.txt index 8154555..cc49e00 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/args_parser.h b/args_parser.h new file mode 100644 index 0000000..c914dff --- /dev/null +++ b/args_parser.h @@ -0,0 +1,43 @@ +#pragma once +#include + +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); + } + } +} + + + + + diff --git a/file.h b/file.h new file mode 100644 index 0000000..f0d1ef1 --- /dev/null +++ b/file.h @@ -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); + } +} +*/ + diff --git a/jemalloc b/jemalloc new file mode 160000 index 0000000..1972241 --- /dev/null +++ b/jemalloc @@ -0,0 +1 @@ +Subproject commit 1972241cd204c60fb5b66f23c48a117879636161 diff --git a/main.c b/main.c index f4f0965..2cfde09 100644 --- a/main.c +++ b/main.c @@ -11,13 +11,25 @@ #include #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 +#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; } diff --git a/tmp b/tmp new file mode 100644 index 0000000..181e79c --- /dev/null +++ b/tmp @@ -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) + + diff --git a/webdisk_c b/webdisk_c new file mode 100755 index 0000000..3824db0 Binary files /dev/null and b/webdisk_c differ