#include "share_mem.h" #include #include #include #include #include "utils.h" #define SHM_NAME_LIST "/shm_hybbwa_name_list" #define SHM_HYB_PREFIX "/shm_hybbwa_" #define SHM_NAME_LIST_SIZE 65535 static inline double get_GB(double bytes) { return bytes / 1024 / 1024 / 1024; } // 根据文件路径获取文件名 const char* get_fn_from_path(const char* file_path) { const char* fn = strrchr(file_path, '/'); if (fn != NULL) return fn + 1; return file_path; } // 将hybrid-index保存到share memrory里 int shm_keep_hyb(const char* idx_prefix) { char full_path[MAX_PATH]; const char* file_name = NULL; char share_name[MAX_PATH]; FILE* fp = NULL; struct stat st; int shmid, init_shm = 0, idx_name_len; uint8_t *shm_idx_list, *mem; uint16_t* shm_idx_cnt; // share memory中index数量 uint16_t* shm_byte_cnt; // 和占用的总内存数 double sec_time; ///////////////// #define __shm_keep_hyb_code(suffix) \ sec_time = realtime(); \ strcat(strcpy(full_path, idx_prefix), suffix); \ file_name = get_fn_from_path(full_path); \ strcat(strcpy(share_name, SHM_HYB_PREFIX), get_fn_from_path(full_path)); \ if ((shmid = shm_open(share_name, O_CREAT | O_RDWR | O_EXCL, 0644)) < 0) { \ perror("shm_open()"); \ return -1; \ } \ err_check_true(stat(full_path, &st), 0); \ if (ftruncate(shmid, st.st_size) < 0) \ return -1; \ idx_name_len = 8 + strlen(file_name) + 1; \ if (idx_name_len + *shm_byte_cnt > SHM_NAME_LIST_SIZE) \ return -1; \ memcpy(shm_idx_list + *shm_byte_cnt, &st.st_size, 8); \ memcpy(shm_idx_list + *shm_byte_cnt + 8, file_name, idx_name_len - 8); \ *shm_byte_cnt += idx_name_len; \ *shm_idx_cnt += 1; \ mem = (uint8_t*)mmap(0, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0); \ fp = xopen(full_path, "r"); \ err_fread_noeof(mem, 1, st.st_size, fp); \ err_fclose(fp); \ munmap(mem, st.st_size); \ fprintf(stderr, "%s, %0.2f GB, %0.2f s\n", file_name, get_GB(st.st_size), realtime() - sec_time); ////////////////////// // 打开保存索引名称的共享内存 if ((shmid = shm_open(SHM_NAME_LIST, O_RDWR, 0)) < 0) { // 之前没有创建过,那就创建并初始化 shmid = shm_open(SHM_NAME_LIST, O_CREAT | O_RDWR | O_EXCL, 0644); init_shm = 1; } if (shmid < 0 || ftruncate(shmid, SHM_NAME_LIST_SIZE) < 0) return -1; shm_idx_list = (uint8_t*)mmap(0, SHM_NAME_LIST_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0); shm_idx_cnt = (uint16_t*)shm_idx_list; shm_byte_cnt = (uint16_t*)(shm_idx_list + 2); if (init_shm) { // 需要初始化share mem中的索引列表 memset(shm_idx_list, 0, SHM_NAME_LIST_SIZE); *shm_byte_cnt = 4; } __shm_keep_hyb_code(HYB_PAC_SUFFIX); __shm_keep_hyb_code(HYB_SA_SUFFIX); __shm_keep_hyb_code(HYB_KMER_SUFFIX); __shm_keep_hyb_code(HYB_DATA_SUFFIX); return 0; } // 清理所有保存在share memory中的索引数据 int shm_clear_hyb() { char share_name[MAX_PATH]; int shmid; uint16_t *shm_idx_cnt, i; char* shm_idx_list; char* ptr; if ((shmid = shm_open(SHM_NAME_LIST, O_RDONLY, 0)) < 0) return -1; shm_idx_list = (char*)mmap(0, SHM_NAME_LIST_SIZE, PROT_READ, MAP_SHARED, shmid, 0); shm_idx_cnt = (uint16_t*)shm_idx_list; for (i = 0, ptr = shm_idx_list + 4; i < *shm_idx_cnt; ++i) { ptr += 8; strcat(strcpy(share_name, SHM_HYB_PREFIX), ptr); fprintf(stderr, "clear: %s\n", ptr); shm_unlink(share_name); ptr += strlen(ptr) + 1; } munmap(shm_idx_list, SHM_NAME_LIST_SIZE); shm_unlink(SHM_NAME_LIST); return 0; } // 从share mem中获取对应的索引数据 void* shm_get_index(const char* full_path) { char share_name[MAX_PATH]; int shmid; uint16_t *shm_idx_cnt, i; char* shm_idx_list; uint64_t idx_bytes; char* ptr; const char* file_name = get_fn_from_path(full_path); if ((shmid = shm_open(SHM_NAME_LIST, O_RDONLY, 0)) < 0) return NULL; shm_idx_list = (char*)mmap(0, SHM_NAME_LIST_SIZE, PROT_READ, MAP_SHARED, shmid, 0); shm_idx_cnt = (uint16_t*)shm_idx_list; for (i = 0, ptr = shm_idx_list + 4; i < *shm_idx_cnt; ++i) { memcpy(&idx_bytes, ptr, 8); ptr += 8; if (strcmp(ptr, file_name) == 0) break; ptr += strlen(ptr) + 1; } if (i == *shm_idx_cnt) return NULL; munmap(shm_idx_list, SHM_NAME_LIST_SIZE); strcat(strcpy(share_name, SHM_HYB_PREFIX), file_name); if ((shmid = shm_open(share_name, O_RDONLY, 0)) < 0) return NULL; return mmap(0, idx_bytes, PROT_READ, MAP_SHARED, shmid, 0); } // 列出共享内存中的hybrid-index int list_shm_hyb_indices() { int shmid; uint16_t *shm_idx_cnt, i; char* shm_idx_list; char* ptr; if ((shmid = shm_open(SHM_NAME_LIST, O_RDONLY, 0)) < 0) { fprintf(stderr, "No shared hybrid index found.\n"); return -1; } shm_idx_list = (char*)mmap(0, SHM_NAME_LIST_SIZE, PROT_READ, MAP_SHARED, shmid, 0); shm_idx_cnt = (uint16_t*)shm_idx_list; fprintf(stderr, "Shared hybrid indices (%d):\n", *shm_idx_cnt); for (i = 0, ptr = shm_idx_list + 4; i < *shm_idx_cnt; ++i) { uint64_t idx_bytes; memcpy(&idx_bytes, ptr, 8); ptr += 8; fprintf(stderr, "%s, %0.2f GB\n", ptr, get_GB(idx_bytes)); ptr += strlen(ptr) + 1; } munmap(shm_idx_list, SHM_NAME_LIST_SIZE); return 0; }