* @brief Convert a trace to lcs format * * @param reader * @param ofilepath * @param sample_ratio * @param output_txt * @param remove_size_change * @param lcs_ver the version of lcs format, see lcs.h for more details */
| 44 | * @param lcs_ver the version of lcs format, see lcs.h for more details |
| 45 | */ |
| 46 | void convert_to_lcs(reader_t *reader, std::string ofilepath, bool output_txt, bool remove_size_change, int lcs_ver) { |
| 47 | request_t *req = new_request(); |
| 48 | std::ofstream ofile_temp(ofilepath + ".reverse", std::ios::out | std::ios::binary | std::ios::trunc); |
| 49 | std::unordered_map<uint64_t, struct obj_info> obj_map; |
| 50 | std::unordered_map<int32_t, int32_t> tenant_cnt; |
| 51 | std::unordered_map<int32_t, int32_t> ttl_cnt; |
| 52 | int n_features = LCS_VER_TO_N_FEATURES[lcs_ver]; |
| 53 | |
| 54 | lcs_trace_stat_t stat; |
| 55 | memset(&stat, 0, sizeof(stat)); |
| 56 | stat.version = CURR_STAT_VERSION; |
| 57 | int64_t n_req_total = get_num_of_req(reader); |
| 58 | obj_map.reserve(n_req_total / 100 + 1e4); |
| 59 | |
| 60 | INFO("%s: %.2f M requests in total\n", reader->trace_path, (double)n_req_total / 1.0e6); |
| 61 | |
| 62 | reader->read_direction = READ_BACKWARD; |
| 63 | reader_set_read_pos(reader, 1.0); |
| 64 | go_back_one_req(reader); |
| 65 | read_one_req(reader, req); |
| 66 | |
| 67 | // because we read backwards, the first request is the last request in the trace |
| 68 | stat.end_timestamp = req->clock_time; |
| 69 | |
| 70 | while (true) { |
| 71 | if (lcs_ver == 1 || lcs_ver == 2) { |
| 72 | if (req->clock_time > UINT32_MAX) { |
| 73 | WARN("clock_time %ld > UINT32_MAX, may cause overflow consider using lcs_ver 3\n", req->clock_time); |
| 74 | } |
| 75 | if (req->obj_size > UINT32_MAX) { |
| 76 | WARN("obj_size %ld > UINT32_MAX, may cause overflow consider using lcs_ver 3\n", req->obj_size); |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | auto info_it = obj_map.find(req->obj_id); |
| 81 | |
| 82 | if (info_it == obj_map.end()) { |
| 83 | req->next_access_vtime = INT64_MAX; |
| 84 | stat.n_obj++; |
| 85 | stat.n_obj_byte += req->obj_size; |
| 86 | struct obj_info info = {req->obj_size, 1, stat.n_req}; |
| 87 | obj_map[req->obj_id] = info; |
| 88 | } else { |
| 89 | req->next_access_vtime = info_it->second.last_access_vtime; |
| 90 | info_it->second.last_access_vtime = stat.n_req; |
| 91 | info_it->second.freq++; |
| 92 | if (info_it->second.size != req->obj_size) { |
| 93 | if (!remove_size_change) { |
| 94 | WARN("find object size change, prev %ld new %ld, please enable remove_size_change\n", info_it->second.size, |
| 95 | req->obj_size); |
| 96 | } else { |
| 97 | req->obj_size = info_it->second.size; |
| 98 | } |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | lcs_req_full_t lcs_req; |
| 103 | lcs_req.clock_time = req->clock_time; |
no test coverage detected