@@ -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 ) ]
310341pub 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
324355impl 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