util: add jsonl_load/jsonl_append helpers, convert graph.rs
Shared JSONL read/write in util.rs replaces hand-rolled patterns. graph.rs metrics load/save converted as first consumer. Co-Authored-By: ProofOfConcept <poc@bcachefs.org>
This commit is contained in:
parent
0e1e5a1981
commit
c6bb7c3910
2 changed files with 31 additions and 18 deletions
|
|
@ -524,27 +524,12 @@ fn metrics_log_path() -> std::path::PathBuf {
|
||||||
|
|
||||||
/// Load previous metrics snapshots
|
/// Load previous metrics snapshots
|
||||||
pub fn load_metrics_history() -> Vec<MetricsSnapshot> {
|
pub fn load_metrics_history() -> Vec<MetricsSnapshot> {
|
||||||
let path = metrics_log_path();
|
crate::util::jsonl_load(&metrics_log_path())
|
||||||
let content = match std::fs::read_to_string(&path) {
|
|
||||||
Ok(c) => c,
|
|
||||||
Err(_) => return Vec::new(),
|
|
||||||
};
|
|
||||||
content.lines()
|
|
||||||
.filter_map(|line| serde_json::from_str(line).ok())
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Append a metrics snapshot to the log
|
/// Append a metrics snapshot to the log
|
||||||
pub fn save_metrics_snapshot(snap: &MetricsSnapshot) {
|
pub fn save_metrics_snapshot(snap: &MetricsSnapshot) {
|
||||||
let path = metrics_log_path();
|
let _ = crate::util::jsonl_append(&metrics_log_path(), snap);
|
||||||
if let Ok(json) = serde_json::to_string(snap) {
|
|
||||||
use std::io::Write;
|
|
||||||
if let Ok(mut f) = std::fs::OpenOptions::new()
|
|
||||||
.create(true).append(true).open(&path)
|
|
||||||
{
|
|
||||||
let _ = writeln!(f, "{}", json);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute current graph metrics as a snapshot (no side effects).
|
/// Compute current graph metrics as a snapshot (no side effects).
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,12 @@
|
||||||
|
|
||||||
use crate::store;
|
use crate::store;
|
||||||
|
|
||||||
|
use serde::de::DeserializeOwned;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::io::Write;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
/// Ensure a subdirectory of the memory dir exists and return its path.
|
/// Ensure a subdirectory of the memory dir exists and return its path.
|
||||||
pub fn memory_subdir(name: &str) -> Result<PathBuf, String> {
|
pub fn memory_subdir(name: &str) -> Result<PathBuf, String> {
|
||||||
|
|
@ -29,6 +33,30 @@ pub fn first_n_chars(s: &str, n: usize) -> String {
|
||||||
s.chars().take(n).collect()
|
s.chars().take(n).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── JSONL helpers ───────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/// Read a JSONL file, deserializing each line. Silently skips bad lines.
|
||||||
|
pub fn jsonl_load<T: DeserializeOwned>(path: &Path) -> Vec<T> {
|
||||||
|
let content = match fs::read_to_string(path) {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(_) => return Vec::new(),
|
||||||
|
};
|
||||||
|
content.lines()
|
||||||
|
.filter_map(|line| serde_json::from_str(line).ok())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Append one record as a JSON line to a file (create if missing).
|
||||||
|
pub fn jsonl_append<T: Serialize>(path: &Path, item: &T) -> Result<(), String> {
|
||||||
|
let json = serde_json::to_string(item)
|
||||||
|
.map_err(|e| format!("serialize: {}", e))?;
|
||||||
|
let mut f = fs::OpenOptions::new()
|
||||||
|
.create(true).append(true).open(path)
|
||||||
|
.map_err(|e| format!("open {}: {}", path.display(), e))?;
|
||||||
|
writeln!(f, "{}", json)
|
||||||
|
.map_err(|e| format!("write {}: {}", path.display(), e))
|
||||||
|
}
|
||||||
|
|
||||||
/// Parse a timestamp string to unix epoch seconds.
|
/// Parse a timestamp string to unix epoch seconds.
|
||||||
/// Handles: "2026-03-05T19:56:00", "2026-03-05T19:56", "2026-03-05 19:56:00", "2026-03-05 19:56"
|
/// Handles: "2026-03-05T19:56:00", "2026-03-05T19:56", "2026-03-05 19:56:00", "2026-03-05 19:56"
|
||||||
pub fn parse_timestamp_to_epoch(ts: &str) -> Option<i64> {
|
pub fn parse_timestamp_to_epoch(ts: &str) -> Option<i64> {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue