From 34784a39f68d13b866cc9172ab589958d996c7d7 Mon Sep 17 00:00:00 2001 From: Cameron Date: Thu, 21 Aug 2025 16:39:33 -0400 Subject: [PATCH] Use rayon for memories endpoint --- src/memories.rs | 95 +++++++++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 43 deletions(-) diff --git a/src/memories.rs b/src/memories.rs index 6066840..0a062e3 100644 --- a/src/memories.rs +++ b/src/memories.rs @@ -5,6 +5,7 @@ use chrono::{DateTime, Datelike, FixedOffset, Local, LocalResult, NaiveDate, Tim use log::{debug, trace, warn}; use opentelemetry::trace::{Span, Status, Tracer}; use opentelemetry::KeyValue; +use rayon::prelude::*; use serde::{Deserialize, Serialize}; use std::path::Path; use walkdir::WalkDir; @@ -133,11 +134,10 @@ fn extract_date_from_filename(filename: &str) -> Option> { }; // 1. Screenshot format: Screenshot_2014-06-01-20-44-50.png - if let Some(captures) = - regex::Regex::new(r"Screenshot_(\d{4})-(\d{2})-(\d{2})-(\d{2})-(\d{2})-(\d{2})") - .ok()? - .captures(filename) - .and_then(|c| build_date_from_ymd_capture(&c)) + if let Some(captures) = regex::Regex::new(r"Screenshot_(\d{4})-(\d{2})-(\d{2})-(\d{2})-(\d{2})-(\d{2})") + .ok()? + .captures(filename) + .and_then(|c| build_date_from_ymd_capture(&c)) { return Some(captures); } @@ -169,19 +169,25 @@ fn extract_date_from_filename(filename: &str) -> Option> { // Millisecond timestamp (13 digits) if timestamp_str.len() >= 13 { - if let Ok(ts_millis) = timestamp_str[0..13].parse::() { - if let Some(naive_dt) = DateTime::from_timestamp_millis(ts_millis) { - return Some(naive_dt.fixed_offset()); - } + if let Some(date_time) = timestamp_str[0..13] + .parse::() + .ok() + .and_then(|timestamp_millis| DateTime::from_timestamp_millis(timestamp_millis)) + .map(|naive_dt| naive_dt.fixed_offset()) + { + return Some(date_time); } } // Second timestamp (10 digits) if timestamp_str.len() >= 10 { - if let Ok(ts_secs) = timestamp_str[0..10].parse::() { - if let Some(naive_dt) = DateTime::from_timestamp(ts_secs, 0) { - return Some(naive_dt.fixed_offset()); - } + if let Some(date_time) = timestamp_str[0..10] + .parse::() + .ok() + .and_then(|timestamp_secs| DateTime::from_timestamp(timestamp_secs, 0)) + .map(|naive_dt| naive_dt.fixed_offset()) + { + return Some(date_time); } } } @@ -226,43 +232,46 @@ pub async fn list_memories( let base = Path::new(&app_state.base_path); - let mut memories_with_dates: Vec<(MemoryItem, NaiveDate)> = Vec::new(); - - for entry in WalkDir::new(base) + let entries: Vec<_> = WalkDir::new(base) .into_iter() .filter_map(|e| e.ok()) .filter(|e| e.file_type().is_file()) - { - let path = entry.path(); + .filter(|e| is_image_or_video(e.path())) + .collect(); - if !is_image_or_video(path) { - continue; - } + let mut memories_with_dates: Vec<(MemoryItem, NaiveDate)> = entries + .par_iter() + .filter_map(|entry| { + let path = entry.path(); - // Get file date and timestamps in one operation - let (file_date, created, modified) = match get_file_date_info(path, &client_timezone) { - Some(info) => info, - None => { - warn!("No date info found for file: {:?}", path); - continue; + // Get file date and timestamps in one operation + let (file_date, created, modified) = match get_file_date_info(path, &client_timezone) { + Some(info) => info, + None => { + warn!("No date info found for file: {:?}", path); + return None; + } + }; + + if is_memories_match(file_date, now, span_mode, years_back) { + return if let Ok(rel) = path.strip_prefix(base) { + Some(( + MemoryItem { + path: rel.to_string_lossy().to_string(), + created, + modified, + }, + file_date, + )) + } else { + warn!("Failed to strip prefix from path: {:?}", path); + None + }; } - }; - if is_memories_match(file_date, now, span_mode, years_back) { - if let Ok(rel) = path.strip_prefix(base) { - memories_with_dates.push(( - MemoryItem { - path: rel.to_string_lossy().to_string(), - created, - modified, - }, - file_date, - )); - } else { - warn!("Failed to strip prefix from path: {:?}", path); - } - } - } + None + }) + .collect(); match span_mode { // Sort by absolute time for a more 'overview'