Skip to content

Commit 6df9346

Browse files
lutterincrypto32
authored andcommitted
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 1883a33 commit 6df9346

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
@@ -305,6 +305,37 @@ impl EntityModification {
305305
}
306306
}
307307

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

319350
/// Map the `key.entity_id` of all entries in `rows` to the index with
320-
/// the most recent entry for that id to speed up lookups
321-
last_mod: HashMap<Id, usize>,
351+
/// the most recent entry for that id to speed up lookups.
352+
last_mod: LastMod,
322353
}
323354

324355
impl RowGroup {
@@ -327,7 +358,7 @@ impl RowGroup {
327358
entity_type,
328359
rows: Vec::new(),
329360
immutable,
330-
last_mod: HashMap::new(),
361+
last_mod: LastMod::new(),
331362
}
332363
}
333364

@@ -384,8 +415,9 @@ impl RowGroup {
384415
}
385416

386417
pub fn last_op(&self, key: &EntityKey, at: BlockNumber) -> Option<EntityOp<'_>> {
387-
if ENV_VARS.store.write_batch_memoize {
388-
let idx = *self.last_mod.get(&key.entity_id)?;
418+
// If we have `key` in `last_mod`, use that and return the
419+
// corresponding op. If not, fall through to a more expensive search
420+
if let Some(&idx) = self.last_mod.get(&key.entity_id) {
389421
if let Some(op) = self.rows.get(idx).and_then(|emod| {
390422
if emod.block() <= at {
391423
Some(emod.as_entity_op(at))
@@ -432,12 +464,10 @@ impl RowGroup {
432464

433465
/// Find the most recent entry for `id`
434466
fn prev_row_mut(&mut self, id: &Id) -> Option<&mut EntityModification> {
435-
if ENV_VARS.store.write_batch_memoize {
436-
let idx = *self.last_mod.get(id)?;
437-
self.rows.get_mut(idx)
438-
} else {
439-
self.rows.iter_mut().rfind(|emod| emod.id() == id)
467+
if let Some(&idx) = self.last_mod.get(id) {
468+
return self.rows.get_mut(idx);
440469
}
470+
self.rows.iter_mut().rfind(|emod| emod.id() == id)
441471
}
442472

443473
/// Append `row` to `self.rows` by combining it with a previously
@@ -989,7 +1019,7 @@ mod test {
9891019
};
9901020
use lazy_static::lazy_static;
9911021

992-
use super::RowGroup;
1022+
use super::{LastMod, RowGroup};
9931023

9941024
#[track_caller]
9951025
fn check_runs(values: &[usize], blocks: &[BlockNumber], exp: &[(BlockNumber, &[usize])]) {
@@ -1007,13 +1037,15 @@ mod test {
10071037
block: *block,
10081038
})
10091039
.collect();
1010-
let last_mod = rows
1011-
.iter()
1012-
.enumerate()
1013-
.fold(HashMap::new(), |mut map, (idx, emod)| {
1014-
map.insert(emod.id().clone(), idx);
1015-
map
1016-
});
1040+
let last_mod = LastMod {
1041+
map: rows
1042+
.iter()
1043+
.enumerate()
1044+
.fold(HashMap::new(), |mut map, (idx, emod)| {
1045+
map.insert(emod.id().clone(), idx);
1046+
map
1047+
}),
1048+
};
10171049

10181050
let group = RowGroup {
10191051
entity_type: ENTRY_TYPE.clone(),

0 commit comments

Comments
 (0)