@@ -14,45 +14,35 @@ use rusqlite::{
1414use sqlite_pool:: { Committable , SqliteConn } ;
1515use std:: rc:: Rc ;
1616use tempfile:: TempDir ;
17- use thread_local:: ThreadLocal ;
1817use tracing:: { error, info, trace, warn} ;
1918
2019use crate :: vtab:: unnest:: UnnestTab ;
2120
2221pub type SqlitePool = sqlite_pool:: Pool < CrConn > ;
2322pub type SqlitePoolError = sqlite_pool:: PoolError ;
23+ use lazy_static:: lazy_static;
2424
25- // Global registry for thread-local query stats
26- type QueryStatsMap = Mutex < HashMap < String , u128 > > ;
27- static QUERY_STATS_REGISTRY : Lazy < Arc < ThreadLocal < QueryStatsMap > > > =
28- Lazy :: new ( || Arc :: new ( ThreadLocal :: new ( ) ) ) ;
29-
30- pub fn print_aggregated_query_stats ( ) {
31- print_aggregated_stats ( & QUERY_STATS_REGISTRY ) ;
25+ // Global registry for query stats - single shared HashMap
26+ lazy_static ! {
27+ static ref QUERY_STATS : Mutex <HashMap <String , u128 >> =
28+ Mutex :: new( HashMap :: new( ) ) ;
3229}
33-
34- fn print_aggregated_stats ( registry : & Arc < ThreadLocal < QueryStatsMap > > ) {
35- let mut aggregated: HashMap < String , u128 > = HashMap :: new ( ) ;
36-
37- // Collect and reset stats from all threads
38- for stats in registry. iter ( ) {
39- let mut stats = stats. lock ( ) ;
40- for ( query, total_nanos) in stats. iter ( ) {
41- * aggregated. entry ( query. clone ( ) ) . or_insert ( 0 ) += total_nanos;
42- }
43- stats. clear ( ) ; // Reset for next interval
44- }
45-
46- if !aggregated. is_empty ( ) {
30+ pub fn print_aggregated_query_stats ( ) {
31+ let mut stats = QUERY_STATS . lock ( ) ;
32+
33+ if !stats. is_empty ( ) {
4734 info ! ( "=== Query Statistics (last 10s) ===" ) ;
48- let mut sorted: Vec < _ > = aggregated . iter ( ) . collect ( ) ;
35+ let mut sorted: Vec < _ > = stats . iter ( ) . collect ( ) ;
4936 sorted. sort_by ( |a, b| b. 1 . cmp ( a. 1 ) ) ; // Sort by total time descending
5037
5138 for ( query, total_nanos) in sorted. iter ( ) . take ( 10 ) {
5239 let total_ms = * total_nanos / 1_000_000 ;
5340 info ! ( " {total_ms}ms total: {query}" ) ;
5441 }
5542 info ! ( "===================================" ) ;
43+
44+ // Clear stats for next interval
45+ stats. clear ( ) ;
5646 }
5747}
5848
@@ -115,10 +105,10 @@ pub fn rusqlite_to_crsqlite(mut conn: rusqlite::Connection) -> rusqlite::Result<
115105 let dur = duration. as_nanos ( ) ;
116106 let sql = stmt_ref. sql ( ) . to_string ( ) ;
117107
118- // Get or create thread-local stats
119- let stats = QUERY_STATS_REGISTRY . get_or ( || Mutex :: new ( HashMap :: new ( ) ) ) ;
120- let mut stats = stats. lock ( ) ;
108+ // Update shared stats
109+ let mut stats = QUERY_STATS . lock ( ) ;
121110 * stats. entry ( sql. clone ( ) ) . or_insert ( 0 ) += dur;
111+ drop ( stats) ; // Release lock quickly
122112
123113 if duration >= SLOW_THRESHOLD {
124114 warn ! ( "SLOW query {duration:?} => {}" , sql) ;
0 commit comments