Skip to content

Commit 234342c

Browse files
author
Zoran Cvetkov
committed
address review
1 parent ebfe059 commit 234342c

File tree

4 files changed

+65
-38
lines changed

4 files changed

+65
-38
lines changed

graph/src/blockchain/block_stream.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -455,12 +455,12 @@ async fn get_entities_for_range(
455455
from: BlockNumber,
456456
to: BlockNumber,
457457
) -> Result<BTreeMap<BlockNumber, Vec<EntityWithType>>, Error> {
458-
let mut entity_types = vec![];
459-
for entity_name in &filter.entities {
460-
let entity_type = schema.entity_type(entity_name)?;
461-
entity_types.push(entity_type);
462-
}
463-
Ok(store.get_range(entity_types, CausalityRegion::ONCHAIN, from..to)?)
458+
let entity_types: Result<Vec<EntityType>> = filter
459+
.entities
460+
.iter()
461+
.map(|name| schema.entity_type(name))
462+
.collect();
463+
Ok(store.get_range(entity_types?, CausalityRegion::ONCHAIN, from..to)?)
464464
}
465465

466466
impl<C: Blockchain> TriggersAdapterWrapper<C> {

store/postgres/src/block_range.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -132,30 +132,38 @@ impl<'a> QueryFragment<Pg> for BlockRangeUpperBoundClause<'a> {
132132
}
133133
}
134134

135+
#[derive(Debug, Clone, Copy)]
136+
pub enum BoundSide {
137+
Lower,
138+
Upper,
139+
}
140+
135141
/// Helper for generating SQL fragments for selecting entities in a specific block range
136142
#[derive(Debug, Clone, Copy)]
137143
pub enum EntityBlockRange {
138-
Mutable((BlockRange, bool)),
144+
Mutable((BlockRange, BoundSide)),
139145
Immutable(BlockRange),
140146
}
141147

142148
impl EntityBlockRange {
143149
pub fn new(
144150
immutable: bool,
145151
block_range: std::ops::Range<BlockNumber>,
146-
is_uppper_range: bool,
152+
bound_side: BoundSide,
147153
) -> Self {
148154
let start: Bound<BlockNumber> = Bound::Included(block_range.start);
149155
let end: Bound<BlockNumber> = Bound::Excluded(block_range.end);
150156
let block_range: BlockRange = BlockRange(start, end);
151157
if immutable {
152158
Self::Immutable(block_range)
153159
} else {
154-
Self::Mutable((block_range, is_uppper_range))
160+
Self::Mutable((block_range, bound_side))
155161
}
156162
}
157163

158-
/// Output SQL that matches only rows whose block range contains `block`.
164+
/// Output SQL that matches only rows whose block or block_range is
165+
/// contained in a range of blocks. For instance:
166+
/// lower(block_range) >= $1 and lower(block_range) <= $2
159167
pub fn contains<'b>(&'b self, out: &mut AstPass<'_, 'b, Pg>) -> QueryResult<()> {
160168
out.unsafe_to_cache_prepared();
161169
let block_range = match self {
@@ -190,13 +198,10 @@ impl EntityBlockRange {
190198

191199
pub fn compare_column(&self, out: &mut AstPass<Pg>) {
192200
match self {
193-
EntityBlockRange::Mutable((_, is_upper_range)) => {
194-
if *is_upper_range {
195-
out.push_sql(" upper(block_range) ")
196-
} else {
197-
out.push_sql(" lower(block_range) ")
198-
}
199-
}
201+
EntityBlockRange::Mutable((_, bound_side)) => match bound_side {
202+
BoundSide::Lower => out.push_sql(" lower(block_range) "),
203+
BoundSide::Upper => out.push_sql(" upper(block_range) "),
204+
},
200205
EntityBlockRange::Immutable(_) => out.push_sql(" block$ "),
201206
}
202207
}

store/postgres/src/relational.rs

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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};
7575
pub use crate::catalog::Catalog;
7676
use crate::connection_pool::ForeignServer;
7777
use 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)

store/postgres/src/relational_queries.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use std::ops::Range;
3535
use std::str::FromStr;
3636
use std::string::ToString;
3737

38-
use crate::block_range::EntityBlockRange;
38+
use crate::block_range::{BoundSide, EntityBlockRange};
3939
use crate::relational::{
4040
Column, ColumnType, Layout, SqlName, Table, BYTE_ARRAY_PREFIX_SIZE, PRIMARY_KEY_COLUMN,
4141
STRING_PREFIX_SIZE,
@@ -2025,7 +2025,7 @@ impl<'a, Conn> RunQueryDsl<Conn> for FindQuery<'a> {}
20252025
pub struct FindRangeQuery<'a> {
20262026
tables: &'a Vec<&'a Table>,
20272027
causality_region: CausalityRegion,
2028-
is_upper_range: bool,
2028+
bound_side: BoundSide,
20292029
imm_range: EntityBlockRange,
20302030
mut_range: EntityBlockRange,
20312031
}
@@ -2034,15 +2034,15 @@ impl<'a> FindRangeQuery<'a> {
20342034
pub fn new(
20352035
tables: &'a Vec<&Table>,
20362036
causality_region: CausalityRegion,
2037-
is_upper_range: bool,
2037+
bound_side: BoundSide,
20382038
block_range: Range<BlockNumber>,
20392039
) -> Self {
2040-
let imm_range = EntityBlockRange::new(true, block_range.clone(), false);
2041-
let mut_range = EntityBlockRange::new(false, block_range, is_upper_range);
2040+
let imm_range = EntityBlockRange::new(true, block_range.clone(), bound_side);
2041+
let mut_range = EntityBlockRange::new(false, block_range, bound_side);
20422042
Self {
20432043
tables,
20442044
causality_region,
2045-
is_upper_range,
2045+
bound_side,
20462046
imm_range,
20472047
mut_range,
20482048
}
@@ -2056,7 +2056,7 @@ impl<'a> QueryFragment<Pg> for FindRangeQuery<'a> {
20562056

20572057
for table in self.tables.iter() {
20582058
// the immutable entities don't have upper range and also can't be modified or deleted
2059-
if !(self.is_upper_range && table.immutable) {
2059+
if matches!(self.bound_side, BoundSide::Lower) || !table.immutable {
20602060
if first {
20612061
first = false;
20622062
} else {

0 commit comments

Comments
 (0)