| 183 | } |
| 184 | |
| 185 | static void _analyze_trace(lcs_trace_stat_t &stat, const std::unordered_map<uint64_t, struct obj_info> &obj_map, |
| 186 | const std::unordered_map<int32_t, int32_t> &tenant_cnt, |
| 187 | const std::unordered_map<int32_t, int32_t> &ttl_cnt) { |
| 188 | INFO("########################################\n"); |
| 189 | INFO("trace stat: n_req %lld, n_obj %lld, n_byte %lld (%.2lf GiB), n_uniq_byte %lld (%.2lf GiB)\n", |
| 190 | (long long)stat.n_req, (long long)stat.n_obj, (long long)stat.n_req_byte, (double)stat.n_req_byte / GiB, |
| 191 | (long long)stat.n_obj_byte, (double)stat.n_obj_byte / GiB); |
| 192 | INFO("n_read %lld, n_write %lld, n_delete %lld\n", (long long)stat.n_read, (long long)stat.n_write, |
| 193 | (long long)stat.n_delete); |
| 194 | |
| 195 | INFO("start time %lld, end time %lld, duration %lld seconds %.2lf days\n", (long long)stat.start_timestamp, |
| 196 | (long long)stat.end_timestamp, (long long)(stat.end_timestamp - stat.start_timestamp), |
| 197 | (double)(stat.end_timestamp - stat.start_timestamp) / (24 * 3600.0)); |
| 198 | |
| 199 | /**** analyze object size ****/ |
| 200 | std::unordered_map<int64_t, int32_t> size_cnt; |
| 201 | stat.smallest_obj_size = INT64_MAX; |
| 202 | stat.largest_obj_size = 0; |
| 203 | for (const auto &kv : obj_map) { |
| 204 | if (size_cnt.find(kv.second.size) == size_cnt.end()) { |
| 205 | size_cnt[kv.second.size] = 1; |
| 206 | } else { |
| 207 | size_cnt[kv.second.size]++; |
| 208 | } |
| 209 | if (kv.second.size < stat.smallest_obj_size) { |
| 210 | stat.smallest_obj_size = kv.second.size; |
| 211 | } |
| 212 | if (kv.second.size > stat.largest_obj_size) { |
| 213 | stat.largest_obj_size = kv.second.size; |
| 214 | } |
| 215 | } |
| 216 | |
| 217 | std::vector<std::pair<int64_t, int32_t>> size_cnt_vec(size_cnt.begin(), size_cnt.end()); |
| 218 | std::sort(size_cnt_vec.begin(), size_cnt_vec.end(), [](const auto &a, const auto &b) { return a.second > b.second; }); |
| 219 | for (size_t i = 0; i < std::min(size_cnt_vec.size(), (size_t)N_MOST_COMMON); i++) { |
| 220 | stat.most_common_obj_sizes[i] = size_cnt_vec[i].first; |
| 221 | stat.most_common_obj_size_ratio[i] = (float)size_cnt_vec[i].second / stat.n_obj; |
| 222 | } |
| 223 | |
| 224 | INFO("object size: smallest %lld, largest %lld\n", (long long)stat.smallest_obj_size, |
| 225 | (long long)stat.largest_obj_size); |
| 226 | INFO("most common object sizes (req fraction): %ld(%.4lf) %ld(%.4lf) %ld(%.4lf) %ld(%.4lf)...\n", |
| 227 | stat.most_common_obj_sizes[0], stat.most_common_obj_size_ratio[0], stat.most_common_obj_sizes[1], |
| 228 | stat.most_common_obj_size_ratio[1], stat.most_common_obj_sizes[2], stat.most_common_obj_size_ratio[2], |
| 229 | stat.most_common_obj_sizes[3], stat.most_common_obj_size_ratio[3]); |
| 230 | |
| 231 | /**** analyze object popularity ****/ |
| 232 | std::unordered_map<int32_t, int32_t> freq_cnt; |
| 233 | for (const auto &kv : obj_map) { |
| 234 | if (freq_cnt.find(kv.second.freq) == freq_cnt.end()) { |
| 235 | freq_cnt[kv.second.freq] = 1; |
| 236 | } else { |
| 237 | freq_cnt[kv.second.freq]++; |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | // sort by freq |
| 242 | std::vector<std::pair<int32_t, int32_t>> freq_cnt_vec(freq_cnt.begin(), freq_cnt.end()); |
no test coverage detected