Skip to content

Commit

Permalink
feat: add tools to convert hit rate to excel and cat excel on terminal
Browse files Browse the repository at this point in the history
  • Loading branch information
sangshuduo committed Nov 11, 2024
1 parent f7ab55f commit c5b1bc3
Show file tree
Hide file tree
Showing 5 changed files with 272 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ members = [
"find_missing_files",
"find_missing_files2",
"find_duplicates",
"hit_rate_converter",
"cat_xlsx",
# Add other tools here
]
resolver = "2" # Add this line to specify resolver version 2
7 changes: 7 additions & 0 deletions cat_xlsx/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "cat_xlsx"
version = "0.1.0"
edition = "2021"

[dependencies]
calamine = "0.21.0"
42 changes: 42 additions & 0 deletions cat_xlsx/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use calamine::{open_workbook_auto, DataType, Reader};
use std::env;
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
// Get the path to the xlsx file from command-line arguments
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
eprintln!("Usage: {} <file.xlsx>", args[0]);
std::process::exit(1);
}
let path = &args[1];

// Open the workbook (auto-detects the format)
let mut workbook = open_workbook_auto(path)?;

// Iterate over the worksheets
let sheet_names = workbook.sheet_names().to_owned();
for sheet_name in sheet_names {
if let Some(Ok(range)) = workbook.worksheet_range(&sheet_name) {
println!("Sheet: {}", sheet_name);
for row in range.rows() {
for cell in row {
match cell {
DataType::Empty => print!("(empty)\t"),
DataType::String(s) => print!("{}\t", s),
DataType::Float(f) => print!("{}\t", f),
DataType::Int(i) => print!("{}\t", i),
DataType::Bool(b) => print!("{}\t", b),
DataType::Error(e) => print!("Error({:?})\t", e),
DataType::DateTime(dt) => print!("DateTime({})\t", dt),
_ => print!("(unknown)\t"),
}
}
println!();
}
println!("-----------------------------------");
}
}

Ok(())
}
9 changes: 9 additions & 0 deletions hit_rate_converter/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "hit_rate_converter"
version = "0.1.0"
edition = "2021"

[dependencies]
clap = { version = "4.0", features = ["derive"] }
rust_xlsxwriter = "0.79.2"
csv = "1.1"
212 changes: 212 additions & 0 deletions hit_rate_converter/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
use std::error::Error;
use std::fs::File;
use std::io::{self, BufRead};

use clap::Parser;
use csv::Writer;
use rust_xlsxwriter::Workbook;

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
/// Benchmark name
#[arg(long, value_name = "BENCHMARK")]
benchmark: String,

/// Module name
#[arg(long, value_name = "MODULE")]
module: String,

/// Input file path
#[arg(long, value_name = "INPUT_FILE")]
input: String,

/// Output file path
#[arg(long, value_name = "OUTPUT_FILE")]
output: String,
}

struct DataEntry {
benchmark: String,
module: String,
dataset: String,
result: String,
values: Vec<String>,
}

fn main() -> Result<(), Box<dyn Error>> {
// Parse command-line arguments
let args = Args::parse();

// Parse the input file
let data_entries = parse_input_file(&args)?;

// Determine output format based on file extension
if args.output.ends_with(".xlsx") {
write_excel(&data_entries, &args.output)?;
} else if args.output.ends_with(".csv") {
write_csv(&data_entries, &args.output)?;
} else {
eprintln!("Unsupported output file format. Please use .xlsx or .csv extension.");
std::process::exit(1);
}

Ok(())
}

fn parse_input_file(args: &Args) -> Result<Vec<DataEntry>, Box<dyn Error>> {
let mut data_entries = Vec::new();
let mut current_dataset = String::new();

let file = File::open(&args.input)?;
let reader = io::BufReader::new(file);

for line_result in reader.lines() {
let line = line_result?;
let line = line.trim();
if line.ends_with("dataset") {
// Dataset line
let dataset_name = line.trim_end_matches("dataset").trim();
current_dataset = dataset_name.to_string();
} else if line.contains(':') {
// Data line
let parts: Vec<&str> = line.splitn(2, ':').collect();
let result_name = parts[0].trim();
let values_str = parts[1].trim();

// Extract values inside square brackets
if values_str.starts_with('[') && values_str.ends_with(']') {
let values_content = &values_str[1..values_str.len() - 1];
// Split values by comma
let values: Vec<String> = values_content
.split(',')
.map(|s| s.trim().to_string())
.collect();

// Create a DataEntry and add to the vector
data_entries.push(DataEntry {
benchmark: args.benchmark.clone(),
module: args.module.clone(),
dataset: current_dataset.clone(),
result: result_name.to_string(),
values,
});
} else {
eprintln!("Invalid values format: {}", line);
}
} else {
// Ignore empty or unrecognized lines
}
}

Ok(data_entries)
}

fn write_excel(data_entries: &[DataEntry], output_file: &str) -> Result<(), Box<dyn Error>> {
// Create a new workbook
let mut workbook = Workbook::new();

// Add a worksheet
let worksheet = workbook.add_worksheet();

// Write the header row
let headers = vec![
"benchmark",
"module",
"dataset",
"result",
"3",
"5",
"10",
"20",
"30",
"40",
"50",
"60",
"70",
"80",
"90",
"100",
];

// Write the headers
for (col_num, header) in headers.iter().enumerate() {
worksheet.write(0, col_num as u16, *header)?;
}

// Write the data entries
for (row_num, entry) in data_entries.iter().enumerate() {
let row = (row_num + 1) as u32;

// Column indices:
// Column 0: benchmark
// Column 1: module
// Column 2: dataset
// Column 3: result
// Columns 4 onward: values

worksheet.write_string(row, 0, &entry.benchmark)?;
worksheet.write_string(row, 1, &entry.module)?;
worksheet.write_string(row, 2, &entry.dataset)?;
worksheet.write_string(row, 3, &entry.result)?;

// Write the values
for (i, value) in entry.values.iter().enumerate() {
let col = (i + 4) as u16;
if let Ok(num) = value.parse::<f64>() {
worksheet.write_number(row, col, num)?;
} else {
worksheet.write_string(row, col, value)?;
}
}
}

// Save the workbook
workbook.save(output_file)?;

Ok(())
}

fn write_csv(data_entries: &[DataEntry], output_file: &str) -> Result<(), Box<dyn Error>> {
let mut wtr = Writer::from_path(output_file)?;

// Write the header row
let headers = vec![
"benchmark",
"module",
"dataset",
"result",
"3",
"5",
"10",
"20",
"30",
"40",
"50",
"60",
"70",
"80",
"90",
"100",
];

wtr.write_record(&headers)?;

// Write the data entries
for entry in data_entries {
let mut row = vec![
entry.benchmark.clone(),
entry.module.clone(),
entry.dataset.clone(),
entry.result.clone(),
];

// Append the values
row.extend(entry.values.clone());

wtr.write_record(&row)?;
}

wtr.flush()?;
Ok(())
}

0 comments on commit c5b1bc3

Please sign in to comment.