Skip to content

Commit

Permalink
Merge pull request #94 from instaclustr/csv-compressor
Browse files Browse the repository at this point in the history
CSV compressor implementation
  • Loading branch information
rukai authored Aug 1, 2024
2 parents 5816c3f + 12561d0 commit 780ea7c
Show file tree
Hide file tree
Showing 8 changed files with 543 additions and 22 deletions.
106 changes: 102 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 1 addition & 14 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ members = [
"tools",
"wavbrro",
"vsri",
"csv-compressor"
]
resolver = "2"

Expand All @@ -17,18 +18,4 @@ opt-level = 3
codegen-units = 1

[workspace.dependencies]
sysinfo = "0.29.0"
hound = "3.5"
chrono = "0.4.26"
claxon = "0.4.3"
warp = "0.3.5"
tokio = { version= "1", features = ["full"] }
symphonia = { version = "0.5.3", features = ["flac"] }
prom-remote-api = { version = "0.3.0", features = ["warp"] }
async-trait = "0.1.71"
env_logger = "0.10.0"
log = "0.4.0"
clap = {version = "4.3.14", features = ["derive"] }
regex = "1.9.1"
median = "0.3.2"
dtw_rs = "0.9.5"
19 changes: 19 additions & 0 deletions csv-compressor/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "csv-compressor"
version = "0.1.0"
edition = "2021"
description = "Utilizes brro-compressor functionalities to compress CSV formatted data"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
brro-compressor = { version = "0.5.0", path = "../brro-compressor" }
clap = { workspace = true, features = ["derive"] }
csv = "1.3.0"
serde = { version = "1.0.171", features = ["derive"] }
wavbrro = { version = "0.1.0", path = "../wavbrro" }
log = "0.4.19"
env_logger = "0.10.0"
vsri = { version = "0.1.0", path = "../vsri" }
[dev-dependencies]
tempdir = "0.3.7"
105 changes: 105 additions & 0 deletions csv-compressor/src/csv.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
use serde::{Deserialize, Serialize};
use std::fs::{File, OpenOptions};
use std::path::Path;

/// Sample describe a single metric record according to csv format.
/// The file should have the following structure:
/// | timestamp | value |
/// | 000001 | 1.01 |
/// | 000005 | 1.22 |
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub struct Sample {
pub timestamp: i64,
pub value: f64,
}

impl Sample {
pub fn new(timestamp: i64, value: f64) -> Self {
Sample { timestamp, value }
}
}

/// Reads samples from csv file at dest.
/// The file should contain the following structure:
/// | timestamp | value |
/// | 000001 | 1.01 |
/// | 000005 | 1.22 |
pub fn read_samples_from_csv_file(dest: &Path) -> Result<Vec<Sample>, csv::Error> {
let file = OpenOptions::new().read(true).open(dest)?;
let mut reader = csv::Reader::from_reader(file);
reader.deserialize().collect()
}

/// Writes samples to file at dest as csv
pub fn write_samples_to_csv_file(dest: &Path, samples: &[Sample]) -> Result<(), csv::Error> {
let mut csv_file = File::create(dest)?;
let mut writer = csv::Writer::from_writer(&mut csv_file);
for sample in samples {
writer.serialize(sample)?;
}

Ok(())
}

#[cfg(test)]
mod tests {
use super::*;
use std::fs::File;
use std::io::Write;
use tempdir::TempDir;

#[test]
fn test_write_samples_to_csv_file() {
let expected_contents = "timestamp,value\n1,1.01\n5,1.22\n";
let samples = vec![Sample::new(1, 1.01), Sample::new(5, 1.22)];

let temp_dir =
TempDir::new("test_write_samples").expect("Unable to create temporary directory");
let path = temp_dir.path().join("samples.csv");

let result = write_samples_to_csv_file(&path, &samples);
assert!(result.is_ok());

let contents = std::fs::read_to_string(&path).expect("Unable to read the file");
assert_eq!(contents, expected_contents);
}

#[test]
fn test_read_samples_from_csv_file() {
let csv_content = "timestamp,value\n1,1.01\n5,1.22\n";
let expected_samples = vec![Sample::new(1, 1.01), Sample::new(5, 1.22)];

let temp_dir =
TempDir::new("test_read_samples").expect("Unable to create temporary directory");
let path = temp_dir.path().join("samples.csv");

// Writing content to test file
let mut file = File::create(&path).expect("Unable to create test file");
file.write_all(csv_content.as_bytes())
.expect("Unable to write data");

let result = read_samples_from_csv_file(&path);
assert!(result.is_ok());

let samples = result.unwrap();
assert_eq!(samples, expected_samples);
}

#[test]
fn test_write_and_read_samples() {
let samples = vec![Sample::new(1, 1.01), Sample::new(5, 1.22)];

let temp_dir = TempDir::new("test_write_and_read_samples")
.expect("Unable to create temporary directory");
let path = temp_dir.path().join("samples.csv");

let write_result = write_samples_to_csv_file(&path, &samples);
assert!(write_result.is_ok());

let read_result = read_samples_from_csv_file(&path);
assert!(read_result.is_ok());

let read_samples = read_result.unwrap();
assert_eq!(samples, read_samples);
}
}
Loading

0 comments on commit 780ea7c

Please sign in to comment.