@@ -78,6 +78,10 @@ struct Inner {
7878 /// This is used for [`PhysicalExpr::snapshot_generation`] to have a cheap check for changes.
7979 generation : u64 ,
8080 expr : Arc < dyn PhysicalExpr > ,
81+ /// Flag for quick synchronous check if filter is complete.
82+ /// This is redundant with the watch channel state, but allows us to return immediately
83+ /// from `wait_complete()` without subscribing if already complete.
84+ is_complete : bool ,
8185}
8286
8387impl Inner {
@@ -87,6 +91,7 @@ impl Inner {
8791 // This is not currently used anywhere but it seems useful to have this simple distinction.
8892 generation : 1 ,
8993 expr,
94+ is_complete : false ,
9095 }
9196 }
9297
@@ -231,6 +236,7 @@ impl DynamicFilterPhysicalExpr {
231236 * current = Inner {
232237 generation : new_generation,
233238 expr : new_expr,
239+ is_complete : current. is_complete ,
234240 } ;
235241 drop ( current) ; // Release the lock before broadcasting
236242
@@ -246,7 +252,11 @@ impl DynamicFilterPhysicalExpr {
246252 /// This signals that all expected updates have been received.
247253 /// Waiters using [`Self::wait_complete`] will be notified.
248254 pub fn mark_complete ( & self ) {
249- let current_generation = self . inner . read ( ) . generation ;
255+ let mut current = self . inner . write ( ) ;
256+ let current_generation = current. generation ;
257+ current. is_complete = true ;
258+ drop ( current) ;
259+
250260 // Broadcast completion to all waiters
251261 let _ = self . state_watch . send ( FilterState :: Complete {
252262 generation : current_generation,
@@ -274,8 +284,11 @@ impl DynamicFilterPhysicalExpr {
274284 /// Unlike [`Self::wait_update`], this method guarantees that when it returns,
275285 /// the filter is fully complete with no more updates expected.
276286 pub async fn wait_complete ( & self ) {
287+ if self . inner . read ( ) . is_complete {
288+ return ;
289+ }
290+
277291 let mut rx = self . state_watch . subscribe ( ) ;
278- // Wait until the state becomes Complete
279292 let _ = rx
280293 . wait_for ( |state| matches ! ( state, FilterState :: Complete { .. } ) )
281294 . await ;
@@ -580,4 +593,18 @@ mod test {
580593 "Expected err when evaluate is called after changing the expression."
581594 ) ;
582595 }
596+
597+ #[ tokio:: test]
598+ async fn test_wait_complete_already_complete ( ) {
599+ let dynamic_filter = Arc :: new ( DynamicFilterPhysicalExpr :: new (
600+ vec ! [ ] ,
601+ lit ( 42 ) as Arc < dyn PhysicalExpr > ,
602+ ) ) ;
603+
604+ // Mark as complete immediately
605+ dynamic_filter. mark_complete ( ) ;
606+
607+ // wait_complete should return immediately
608+ dynamic_filter. wait_complete ( ) . await ;
609+ }
583610}
0 commit comments