@@ -71,7 +71,7 @@ use graph::prelude::{
7171 QueryExecutionError , StoreError , StoreEvent , ValueType , BLOCK_NUMBER_MAX ,
7272} ;
7373
74- use crate :: block_range:: { BLOCK_COLUMN , BLOCK_RANGE_COLUMN } ;
74+ use crate :: block_range:: { BoundSide , BLOCK_COLUMN , BLOCK_RANGE_COLUMN } ;
7575pub use crate :: catalog:: Catalog ;
7676use crate :: connection_pool:: ForeignServer ;
7777use crate :: { catalog, deployment} ;
@@ -530,14 +530,27 @@ impl Layout {
530530 et_map. insert ( et. to_string ( ) , Arc :: new ( et) ) ;
531531 }
532532 let mut entities: BTreeMap < BlockNumber , Vec < EntityWithType > > = BTreeMap :: new ( ) ;
533- let lower_vec = FindRangeQuery :: new ( & tables, causality_region, false , block_range. clone ( ) )
534- . get_results :: < EntityDataExt > ( conn)
535- . optional ( ) ?
536- . unwrap_or_default ( ) ;
537- let upper_vec = FindRangeQuery :: new ( & tables, causality_region, true , block_range)
538- . get_results :: < EntityDataExt > ( conn)
539- . optional ( ) ?
540- . unwrap_or_default ( ) ;
533+
534+ // collect all entities that have their 'lower(block_range)' attribute in the
535+ // interval of blocks defined by the variable block_range. For the immutable
536+ // entities the respective attribute is 'block$'.
537+ let lower_vec = FindRangeQuery :: new (
538+ & tables,
539+ causality_region,
540+ BoundSide :: Lower ,
541+ block_range. clone ( ) ,
542+ )
543+ . get_results :: < EntityDataExt > ( conn)
544+ . optional ( ) ?
545+ . unwrap_or_default ( ) ;
546+ // collect all entities that have their 'upper(block_range)' attribute in the
547+ // interval of blocks defined by the variable block_range. For the immutable
548+ // entities no entries are returned.
549+ let upper_vec =
550+ FindRangeQuery :: new ( & tables, causality_region, BoundSide :: Upper , block_range)
551+ . get_results :: < EntityDataExt > ( conn)
552+ . optional ( ) ?
553+ . unwrap_or_default ( ) ;
541554 let mut lower_iter = lower_vec. iter ( ) . fuse ( ) . peekable ( ) ;
542555 let mut upper_iter = upper_vec. iter ( ) . fuse ( ) . peekable ( ) ;
543556 let mut lower_now = lower_iter. next ( ) ;
@@ -560,27 +573,36 @@ impl Layout {
560573 } ;
561574 Ok ( ( ewt, block) )
562575 } ;
576+
577+ // The algorithm advances simultaneously entities from both lower_vec and upper_vec and tries
578+ // to match entities that have entries in both vectors for a particular block. The match is
579+ // successfull if an entry in one array has same values for the number of the block, entity
580+ // name and the entity id. The comparison operation over the EntityDataExt fullfils that check.
581+ // In addition to that, it also helps to order the elements so the algorith can detect if one
582+ // side of the range exists and the other is missing. That way a creation and deletion are
583+ // deduced. For immutable entities the entries in upper_vec are missing hence they are considered
584+ // having a lower bound at particular block and upper bound at infinity.
563585 while lower_now. is_some ( ) || upper_now. is_some ( ) {
564586 let ( ewt, block) = if lower_now. is_some ( ) {
565587 if upper_now. is_some ( ) {
566588 if lower > upper {
567589 // we have upper bound at this block, but no lower bounds at the same block so it's deletion
568590 let ( ewt, block) = transform ( upper, EntitySubgraphOperation :: Delete ) ?;
569- // advance upper
591+ // advance upper_vec pointer
570592 upper_now = upper_iter. next ( ) ;
571593 upper = upper_now. unwrap_or ( & EntityDataExt :: default ( ) ) . clone ( ) ;
572594 ( ewt, block)
573595 } else if lower < upper {
574596 // we have lower bound at this block but no upper bound at the same block so its creation
575597 let ( ewt, block) = transform ( lower, EntitySubgraphOperation :: Create ) ?;
576- // advance lower
598+ // advance lower_vec pointer
577599 lower_now = lower_iter. next ( ) ;
578600 lower = lower_now. unwrap_or ( & EntityDataExt :: default ( ) ) . clone ( ) ;
579601 ( ewt, block)
580602 } else {
581603 assert ! ( upper == lower) ;
582604 let ( ewt, block) = transform ( lower, EntitySubgraphOperation :: Modify ) ?;
583- // advance both
605+ // advance both lower_vec and upper_vec pointers
584606 lower_now = lower_iter. next ( ) ;
585607 lower = lower_now. unwrap_or ( & EntityDataExt :: default ( ) ) . clone ( ) ;
586608 upper_now = upper_iter. next ( ) ;
@@ -590,7 +612,7 @@ impl Layout {
590612 } else {
591613 // we have lower bound at this block but no upper bound at the same block so its creation
592614 let ( ewt, block) = transform ( lower, EntitySubgraphOperation :: Create ) ?;
593- // advance lower
615+ // advance lower_vec pointer
594616 lower_now = lower_iter. next ( ) ;
595617 lower = lower_now. unwrap_or ( & EntityDataExt :: default ( ) ) . clone ( ) ;
596618 ( ewt, block)
@@ -599,7 +621,7 @@ impl Layout {
599621 // we have upper bound at this block, but no lower bounds at all so it's deletion
600622 assert ! ( upper_now. is_some( ) ) ;
601623 let ( ewt, block) = transform ( upper, EntitySubgraphOperation :: Delete ) ?;
602- // advance upper
624+ // advance upper_vec pointer
603625 upper_now = upper_iter. next ( ) ;
604626 upper = upper_now. unwrap_or ( & EntityDataExt :: default ( ) ) . clone ( ) ;
605627 ( ewt, block)
0 commit comments