@@ -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 ) ]
308339pub 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
322353impl 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