int block_cache_trace_analyzer_tool()

in tools/block_cache_analyzer/block_cache_trace_analyzer.cc [2110:2305]


int block_cache_trace_analyzer_tool(int argc, char** argv) {
  ParseCommandLineFlags(&argc, &argv, true);
  if (FLAGS_block_cache_trace_path.empty()) {
    fprintf(stderr, "block cache trace path is empty\n");
    exit(1);
  }
  uint64_t warmup_seconds =
      FLAGS_cache_sim_warmup_seconds > 0 ? FLAGS_cache_sim_warmup_seconds : 0;
  uint32_t downsample_ratio = FLAGS_block_cache_trace_downsample_ratio > 0
                                  ? FLAGS_block_cache_trace_downsample_ratio
                                  : 0;
  std::vector<CacheConfiguration> cache_configs =
      parse_cache_config_file(FLAGS_block_cache_sim_config_path);
  std::unique_ptr<BlockCacheTraceSimulator> cache_simulator;
  if (!cache_configs.empty()) {
    cache_simulator.reset(new BlockCacheTraceSimulator(
        warmup_seconds, downsample_ratio, cache_configs));
    Status s = cache_simulator->InitializeCaches();
    if (!s.ok()) {
      fprintf(stderr, "Cannot initialize cache simulators %s\n",
              s.ToString().c_str());
      exit(1);
    }
  }
  BlockCacheTraceAnalyzer analyzer(
      FLAGS_block_cache_trace_path, FLAGS_block_cache_analysis_result_dir,
      FLAGS_human_readable_trace_file_path,
      !FLAGS_reuse_distance_labels.empty(), FLAGS_mrc_only,
      FLAGS_is_block_cache_human_readable_trace, std::move(cache_simulator));
  Status s = analyzer.Analyze();
  if (!s.IsIncomplete() && !s.ok()) {
    // Read all traces.
    fprintf(stderr, "Cannot process the trace %s\n", s.ToString().c_str());
    exit(1);
  }
  fprintf(stdout, "Status: %s\n", s.ToString().c_str());
  analyzer.WriteMissRatioCurves();
  analyzer.WriteMissRatioTimeline(1);
  analyzer.WriteMissRatioTimeline(kSecondInMinute);
  analyzer.WriteMissRatioTimeline(kSecondInHour);
  analyzer.WriteMissTimeline(1);
  analyzer.WriteMissTimeline(kSecondInMinute);
  analyzer.WriteMissTimeline(kSecondInHour);

  if (FLAGS_mrc_only) {
    fprintf(stdout,
            "Skipping the analysis statistics since the user wants to compute "
            "MRC only");
    return 0;
  }

  analyzer.PrintStatsSummary();
  if (FLAGS_print_access_count_stats) {
    print_break_lines(/*num_break_lines=*/3);
    analyzer.PrintAccessCountStats(
        /*user_access_only=*/false, FLAGS_analyze_bottom_k_access_count_blocks,
        FLAGS_analyze_top_k_access_count_blocks);
    print_break_lines(/*num_break_lines=*/3);
    analyzer.PrintAccessCountStats(
        /*user_access_only=*/true, FLAGS_analyze_bottom_k_access_count_blocks,
        FLAGS_analyze_top_k_access_count_blocks);
  }
  if (FLAGS_print_block_size_stats) {
    print_break_lines(/*num_break_lines=*/3);
    analyzer.PrintBlockSizeStats();
  }
  if (FLAGS_print_data_block_access_count_stats) {
    print_break_lines(/*num_break_lines=*/3);
    analyzer.PrintDataBlockAccessStats();
  }
  print_break_lines(/*num_break_lines=*/3);

  if (!FLAGS_timeline_labels.empty()) {
    std::stringstream ss(FLAGS_timeline_labels);
    while (ss.good()) {
      std::string label;
      getline(ss, label, ',');
      if (label.find("block") != std::string::npos) {
        analyzer.WriteAccessTimeline(label, kSecondInMinute, true);
        analyzer.WriteAccessTimeline(label, kSecondInMinute, false);
        analyzer.WriteAccessTimeline(label, kSecondInHour, true);
        analyzer.WriteAccessTimeline(label, kSecondInHour, false);
      } else {
        analyzer.WriteAccessTimeline(label, kSecondInMinute, false);
        analyzer.WriteAccessTimeline(label, kSecondInHour, false);
      }
    }
  }

  if (!FLAGS_analyze_callers.empty()) {
    analyzer.WritePercentAccessSummaryStats();
    std::stringstream ss(FLAGS_analyze_callers);
    while (ss.good()) {
      std::string caller;
      getline(ss, caller, ',');
      analyzer.WriteDetailedPercentAccessSummaryStats(string_to_caller(caller));
    }
  }

  if (!FLAGS_access_count_buckets.empty()) {
    std::vector<uint64_t> buckets = parse_buckets(FLAGS_access_count_buckets);
    analyzer.WriteAccessCountSummaryStats(buckets, /*user_access_only=*/true);
    analyzer.WriteAccessCountSummaryStats(buckets, /*user_access_only=*/false);
  }

  if (!FLAGS_reuse_distance_labels.empty() &&
      !FLAGS_reuse_distance_buckets.empty()) {
    std::vector<uint64_t> buckets = parse_buckets(FLAGS_reuse_distance_buckets);
    std::stringstream ss(FLAGS_reuse_distance_labels);
    while (ss.good()) {
      std::string label;
      getline(ss, label, ',');
      analyzer.WriteReuseDistance(label, buckets);
    }
  }

  if (!FLAGS_reuse_interval_labels.empty() &&
      !FLAGS_reuse_interval_buckets.empty()) {
    std::vector<uint64_t> buckets = parse_buckets(FLAGS_reuse_interval_buckets);
    std::stringstream ss(FLAGS_reuse_interval_labels);
    while (ss.good()) {
      std::string label;
      getline(ss, label, ',');
      analyzer.WriteReuseInterval(label, buckets);
    }
  }

  if (!FLAGS_reuse_lifetime_labels.empty() &&
      !FLAGS_reuse_lifetime_buckets.empty()) {
    std::vector<uint64_t> buckets = parse_buckets(FLAGS_reuse_lifetime_buckets);
    std::stringstream ss(FLAGS_reuse_lifetime_labels);
    while (ss.good()) {
      std::string label;
      getline(ss, label, ',');
      analyzer.WriteReuseLifetime(label, buckets);
    }
  }

  if (FLAGS_analyze_blocks_reuse_k_reuse_window != 0) {
    std::vector<TraceType> block_types{TraceType::kBlockTraceIndexBlock,
                                       TraceType::kBlockTraceDataBlock,
                                       TraceType::kBlockTraceFilterBlock};
    for (auto block_type : block_types) {
      analyzer.WriteBlockReuseTimeline(
          FLAGS_analyze_blocks_reuse_k_reuse_window,
          /*user_access_only=*/true, block_type);
      analyzer.WriteBlockReuseTimeline(
          FLAGS_analyze_blocks_reuse_k_reuse_window,
          /*user_access_only=*/false, block_type);
    }
  }

  if (!FLAGS_analyze_get_spatial_locality_labels.empty() &&
      !FLAGS_analyze_get_spatial_locality_buckets.empty()) {
    std::vector<uint64_t> buckets =
        parse_buckets(FLAGS_analyze_get_spatial_locality_buckets);
    std::stringstream ss(FLAGS_analyze_get_spatial_locality_labels);
    while (ss.good()) {
      std::string label;
      getline(ss, label, ',');
      analyzer.WriteGetSpatialLocality(label, buckets);
    }
  }

  if (!FLAGS_analyze_correlation_coefficients_labels.empty()) {
    std::stringstream ss(FLAGS_analyze_correlation_coefficients_labels);
    while (ss.good()) {
      std::string label;
      getline(ss, label, ',');
      analyzer.WriteCorrelationFeatures(
          label, FLAGS_analyze_correlation_coefficients_max_number_of_values);
    }
    analyzer.WriteCorrelationFeaturesForGet(
        FLAGS_analyze_correlation_coefficients_max_number_of_values);
  }

  if (!FLAGS_skew_labels.empty() && !FLAGS_skew_buckets.empty()) {
    std::vector<uint64_t> buckets = parse_buckets(FLAGS_skew_buckets);
    std::stringstream ss(FLAGS_skew_labels);
    while (ss.good()) {
      std::string label;
      getline(ss, label, ',');
      if (label.find("block") != std::string::npos) {
        analyzer.WriteSkewness(label, buckets,
                               TraceType::kBlockTraceIndexBlock);
        analyzer.WriteSkewness(label, buckets,
                               TraceType::kBlockTraceFilterBlock);
        analyzer.WriteSkewness(label, buckets, TraceType::kBlockTraceDataBlock);
        analyzer.WriteSkewness(label, buckets, TraceType::kTraceMax);
      } else {
        analyzer.WriteSkewness(label, buckets, TraceType::kTraceMax);
      }
    }
  }
  return 0;
}