@@ -19,7 +19,6 @@ use crate::parsing::janusql_parser::WindowDefinition;
1919use crate :: querying:: oxigraph_adapter:: OxigraphAdapter ;
2020use crate :: storage:: segmented_storage:: StreamingSegmentedStorage ;
2121use crate :: stream:: operators:: historical_fixed_window:: HistoricalFixedWindowOperator ;
22- use crate :: stream:: operators:: historical_sliding_window:: HistoricalSlidingWindowOperator ;
2322use oxigraph:: model:: { GraphName , NamedNode , Quad } ;
2423use rsp_rs:: QuadContainer ;
2524use std:: collections:: { HashMap , HashSet } ;
@@ -166,23 +165,16 @@ impl HistoricalExecutor {
166165 window : & WindowDefinition ,
167166 sparql_query : & ' a str ,
168167 ) -> impl Iterator < Item = Result < Vec < HashMap < String , String > > , JanusApiError > > + ' a {
169- let offset = window. offset . unwrap_or ( 0 ) ;
170- let width = window. width ;
171- let slide = window. slide ;
172-
173168 let now = std:: time:: SystemTime :: now ( )
174169 . duration_since ( std:: time:: UNIX_EPOCH )
175170 . unwrap_or_default ( )
176171 . as_millis ( ) as u64 ;
177172
178- let start_time = now. saturating_sub ( offset) ;
179-
180173 SlidingWindowIterator {
181174 executor : self ,
182- current_start : start_time,
183- evaluation_time : now,
184- width,
185- slide,
175+ window : window. clone ( ) ,
176+ current_evaluation_time : now,
177+ latest_evaluation_time : now,
186178 sparql_query : sparql_query. to_string ( ) ,
187179 }
188180 }
@@ -397,47 +389,40 @@ impl HistoricalExecutor {
397389 & self ,
398390 window : & WindowDefinition ,
399391 ) -> Result < ( u64 , u64 ) , JanusApiError > {
400- // For fixed windows: use explicit start/end
401- if let ( Some ( start) , Some ( end) ) = ( window. start , window. end ) {
402- return Ok ( ( start, end) ) ;
403- }
404-
405- // For sliding windows: calculate from offset and width
406- if let Some ( offset) = window. offset {
407- let now = std:: time:: SystemTime :: now ( )
392+ let evaluation_time = if window. offset . is_some ( ) {
393+ std:: time:: SystemTime :: now ( )
408394 . duration_since ( std:: time:: UNIX_EPOCH )
409395 . map_err ( |e| JanusApiError :: ExecutionError ( format ! ( "System time error: {}" , e) ) ) ?
410- . as_millis ( ) as u64 ;
411-
412- let start = now. saturating_sub ( offset) ;
413- let end = start + window. width ;
414- return Ok ( ( start, end) ) ;
415- }
396+ . as_millis ( ) as u64
397+ } else {
398+ window. end . unwrap_or_default ( )
399+ } ;
416400
417- Err ( JanusApiError :: ExecutionError (
418- "Window definition must have either (start, end) or (offset, width)" . to_string ( ) ,
419- ) )
401+ window. resolve_historical_bounds ( evaluation_time) . ok_or_else ( || {
402+ JanusApiError :: ExecutionError (
403+ "Window definition cannot resolve complete historical bounds" . to_string ( ) ,
404+ )
405+ } )
420406 }
421407}
422408
423409/// Iterator for sliding windows that queries storage directly
424410struct SlidingWindowIterator < ' a > {
425411 executor : & ' a HistoricalExecutor ,
426- current_start : u64 ,
427- evaluation_time : u64 ,
428- width : u64 ,
429- slide : u64 ,
412+ window : WindowDefinition ,
413+ current_evaluation_time : u64 ,
414+ latest_evaluation_time : u64 ,
430415 sparql_query : String ,
431416}
432417
433418impl < ' a > Iterator for SlidingWindowIterator < ' a > {
434419 type Item = Result < Vec < HashMap < String , String > > , JanusApiError > ;
435420
436421 fn next ( & mut self ) -> Option < Self :: Item > {
437- let window_start = self . current_start ;
438- let window_end = window_start . checked_add ( self . width ) ?;
422+ let ( window_start, window_end ) =
423+ self . window . resolve_historical_bounds ( self . current_evaluation_time ) ?;
439424
440- if window_end > self . evaluation_time {
425+ if window_end > self . latest_evaluation_time {
441426 return None ;
442427 }
443428
@@ -453,7 +438,8 @@ impl<'a> Iterator for SlidingWindowIterator<'a> {
453438 let result = self . executor . execute_sparql_on_events ( & events, & self . sparql_query ) ;
454439
455440 // Advance window
456- self . current_start += self . slide ;
441+ self . current_evaluation_time =
442+ self . current_evaluation_time . checked_add ( self . window . slide ) ?;
457443
458444 Some ( result)
459445 }
@@ -557,7 +543,7 @@ mod tests {
557543 . execute_sliding_windows ( & window, "SELECT ?s WHERE { ?s ?p ?o }" )
558544 . collect :: < Vec < _ > > ( ) ;
559545
560- assert_eq ! ( results. len( ) , 4 ) ;
546+ assert_eq ! ( results. len( ) , 6 ) ;
561547 assert ! ( results. iter( ) . all( |result| result. is_ok( ) ) ) ;
562548 }
563549
@@ -586,7 +572,7 @@ mod tests {
586572 . execute_sliding_windows ( & window, "SELECT ?s WHERE { ?s ?p ?o }" )
587573 . collect :: < Vec < _ > > ( ) ;
588574
589- assert_eq ! ( results. len( ) , 2 ) ;
575+ assert_eq ! ( results. len( ) , 3 ) ;
590576 assert ! ( results. iter( ) . all( |result| result. is_ok( ) ) ) ;
591577 }
592578
0 commit comments