| 30 | } |
| 31 | |
| 32 | uint64_t TraceUtils::merge_l1_trace(vector<string>& l1_trace_path_vec, |
| 33 | string& l2_output_trace_path) { |
| 34 | uint64_t n_req = 0; |
| 35 | vector<FILE*> l1_ifile_vec; |
| 36 | for (auto& l1_path : l1_trace_path_vec) { |
| 37 | l1_ifile_vec.emplace_back(fopen(l1_path.c_str(), "r")); |
| 38 | } |
| 39 | ofstream l2_ofs(l2_output_trace_path, |
| 40 | ofstream::out | ofstream::trunc | ofstream::binary); |
| 41 | |
| 42 | auto comparer = [](const req_t& a, const req_t& b) { return a.ts > b.ts; }; |
| 43 | |
| 44 | priority_queue<req_t, vector<req_t>, decltype(comparer)> pq(comparer); |
| 45 | req_t req; |
| 46 | uint32_t n_finished = 0; |
| 47 | int n_read_field; |
| 48 | |
| 49 | for (int i = 0; i < l1_ifile_vec.size(); i++) { |
| 50 | fscanf(l1_ifile_vec.at(i), "%u,%u,%u", &req.ts, &req.obj_id, &req.sz); |
| 51 | req.trace_id = i; |
| 52 | pq.push(req); |
| 53 | // std::cout << i << ":" << req.ts << ", " << req.obj_id << ", " << |
| 54 | // req.sz << std::endl; |
| 55 | } |
| 56 | |
| 57 | req = pq.top(); |
| 58 | // std::cout << "top " << req.ts << ", " << req.obj_id << ", " << req.sz << |
| 59 | // std::endl; |
| 60 | |
| 61 | while (n_finished < l1_trace_path_vec.size() && !pq.empty()) { |
| 62 | req = pq.top(); |
| 63 | pq.pop(); |
| 64 | n_req += 1; |
| 65 | l2_ofs.write((char*)(&req), 12); |
| 66 | // std::cout << "write " << req.obj_id << "\n"; |
| 67 | if (feof(l1_ifile_vec.at(req.trace_id))) { |
| 68 | n_finished += 1; |
| 69 | } else { |
| 70 | n_read_field = fscanf(l1_ifile_vec.at(req.trace_id), "%u,%u,%u", &req.ts, |
| 71 | &req.obj_id, &req.sz); |
| 72 | if (n_read_field == 3) { |
| 73 | pq.push(req); |
| 74 | } else { |
| 75 | n_finished += 1; |
| 76 | } |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | for (auto& ifile : l1_ifile_vec) { |
| 81 | fclose(ifile); |
| 82 | } |
| 83 | l2_ofs.close(); |
| 84 | return n_req; |
| 85 | } |
nothing calls this directly
no test coverage detected