Skip to content

Commit a7defe3

Browse files
committed
graph: Fix a bug in RowGroup::last_op
If we didn't have an entry for key in last_mod, we would immediately return with None instead of searching for the key in the fallback part of the method. This also tries to clean up the code a little by introducing a LastMod struct that encapsulates different behavior between having batch memoization turned on and turned off. Fixes #6313
1 parent 8c87348 commit a7defe3

File tree

1 file changed

+50
-18
lines changed

1 file changed

+50
-18
lines changed

graph/src/components/store/write.rs

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,37 @@ impl EntityModification {
303303
}
304304
}
305305

306+
/// A map from entity ids to the index of the last modification for that id.
307+
/// If `ENV_VARS.store.write_batch_memoize` is `false`, this map is never
308+
/// written to and always empty
309+
#[derive(Debug, CacheWeight)]
310+
struct LastMod {
311+
/// If `ENV_VARS.store.write_batch_memoize` is `false`, we never write
312+
/// into this map
313+
map: HashMap<Id, usize>,
314+
}
315+
316+
impl LastMod {
317+
fn new() -> LastMod {
318+
LastMod {
319+
map: HashMap::new(),
320+
}
321+
}
322+
323+
fn get(&self, id: &Id) -> Option<&usize> {
324+
if ENV_VARS.store.write_batch_memoize {
325+
return self.map.get(id);
326+
}
327+
None
328+
}
329+
330+
fn insert(&mut self, id: Id, idx: usize) {
331+
if ENV_VARS.store.write_batch_memoize {
332+
self.map.insert(id, idx);
333+
}
334+
}
335+
}
336+
306337
/// A list of entity changes grouped by the entity type
307338
#[derive(Debug, CacheWeight)]
308339
pub struct RowGroup {
@@ -315,8 +346,8 @@ pub struct RowGroup {
315346
immutable: bool,
316347

317348
/// Map the `key.entity_id` of all entries in `rows` to the index with
318-
/// the most recent entry for that id to speed up lookups
319-
last_mod: HashMap<Id, usize>,
349+
/// the most recent entry for that id to speed up lookups.
350+
last_mod: LastMod,
320351
}
321352

322353
impl RowGroup {
@@ -325,7 +356,7 @@ impl RowGroup {
325356
entity_type,
326357
rows: Vec::new(),
327358
immutable,
328-
last_mod: HashMap::new(),
359+
last_mod: LastMod::new(),
329360
}
330361
}
331362

@@ -382,8 +413,9 @@ impl RowGroup {
382413
}
383414

384415
pub fn last_op(&self, key: &EntityKey, at: BlockNumber) -> Option<EntityOp<'_>> {
385-
if ENV_VARS.store.write_batch_memoize {
386-
let idx = *self.last_mod.get(&key.entity_id)?;
416+
// If we have `key` in `last_mod`, use that and return the
417+
// corresponding op. If not, fall through to a more expensive search
418+
if let Some(&idx) = self.last_mod.get(&key.entity_id) {
387419
if let Some(op) = self.rows.get(idx).and_then(|emod| {
388420
if emod.block() <= at {
389421
Some(emod.as_entity_op(at))
@@ -430,12 +462,10 @@ impl RowGroup {
430462

431463
/// Find the most recent entry for `id`
432464
fn prev_row_mut(&mut self, id: &Id) -> Option<&mut EntityModification> {
433-
if ENV_VARS.store.write_batch_memoize {
434-
let idx = *self.last_mod.get(id)?;
435-
self.rows.get_mut(idx)
436-
} else {
437-
self.rows.iter_mut().rfind(|emod| emod.id() == id)
465+
if let Some(&idx) = self.last_mod.get(id) {
466+
return self.rows.get_mut(idx);
438467
}
468+
self.rows.iter_mut().rfind(|emod| emod.id() == id)
439469
}
440470

441471
/// Append `row` to `self.rows` by combining it with a previously
@@ -997,7 +1027,7 @@ mod test {
9971027
};
9981028
use lazy_static::lazy_static;
9991029

1000-
use super::RowGroup;
1030+
use super::{LastMod, RowGroup};
10011031

10021032
#[track_caller]
10031033
fn check_runs(values: &[usize], blocks: &[BlockNumber], exp: &[(BlockNumber, &[usize])]) {
@@ -1015,13 +1045,15 @@ mod test {
10151045
block: *block,
10161046
})
10171047
.collect();
1018-
let last_mod = rows
1019-
.iter()
1020-
.enumerate()
1021-
.fold(HashMap::new(), |mut map, (idx, emod)| {
1022-
map.insert(emod.id().clone(), idx);
1023-
map
1024-
});
1048+
let last_mod = LastMod {
1049+
map: rows
1050+
.iter()
1051+
.enumerate()
1052+
.fold(HashMap::new(), |mut map, (idx, emod)| {
1053+
map.insert(emod.id().clone(), idx);
1054+
map
1055+
}),
1056+
};
10251057

10261058
let group = RowGroup {
10271059
entity_type: ENTRY_TYPE.clone(),

0 commit comments

Comments
 (0)