1- use anyhow:: anyhow;
1+ use anyhow:: { anyhow, bail } ;
22use std:: borrow:: Borrow ;
33use std:: collections:: HashMap ;
44use std:: fmt:: { self , Debug } ;
@@ -17,6 +17,10 @@ use super::{BlockNumber, DerivedEntityQuery, LoadRelatedRequest, StoreError};
1717
1818pub type EntityLfuCache = LfuCache < EntityKey , Option < Arc < Entity > > > ;
1919
20+ // Number of VIDs that are reserved outside of the generated ones here.
21+ // Currently none is used, but lets reserve a few more.
22+ const RESERVED_VIDS : u32 = 100 ;
23+
2024/// The scope in which the `EntityCache` should perform a `get` operation
2125pub enum GetScope {
2226 /// Get from all previously stored entities in the store
@@ -105,6 +109,10 @@ pub struct EntityCache {
105109 /// generated IDs, the `EntityCache` needs to be newly instantiated for
106110 /// each block
107111 seq : u32 ,
112+
113+ // Sequence number of the next VID value for this block. The value written
114+ // in the database consist of a block number and this SEQ number.
115+ pub vid_seq : u32 ,
108116}
109117
110118impl Debug for EntityCache {
@@ -132,6 +140,7 @@ impl EntityCache {
132140 schema : store. input_schema ( ) ,
133141 store,
134142 seq : 0 ,
143+ vid_seq : RESERVED_VIDS ,
135144 }
136145 }
137146
@@ -152,6 +161,7 @@ impl EntityCache {
152161 schema : store. input_schema ( ) ,
153162 store,
154163 seq : 0 ,
164+ vid_seq : RESERVED_VIDS ,
155165 }
156166 }
157167
@@ -278,7 +288,7 @@ impl EntityCache {
278288 ) -> Result < Option < Entity > , anyhow:: Error > {
279289 match op {
280290 EntityOp :: Update ( entity) | EntityOp :: Overwrite ( entity)
281- if query. matches ( key, entity) =>
291+ if query. matches ( key, & entity) =>
282292 {
283293 Ok ( Some ( entity. clone ( ) ) )
284294 }
@@ -353,6 +363,7 @@ impl EntityCache {
353363 & mut self ,
354364 key : EntityKey ,
355365 entity : Entity ,
366+ block : BlockNumber ,
356367 write_capacity_remaining : Option < & mut usize > ,
357368 ) -> Result < ( ) , anyhow:: Error > {
358369 // check the validate for derived fields
@@ -371,6 +382,21 @@ impl EntityCache {
371382 * write_capacity_remaining -= weight;
372383 }
373384
385+ // The next VID is based on a block number and a sequence within the block
386+ let vid = ( ( block as i64 ) << 32 ) + self . vid_seq as i64 ;
387+ self . vid_seq += 1 ;
388+ let mut entity = entity;
389+ let old_vid = entity. set_vid ( vid) . expect ( "the vid should be set" ) ;
390+ // Make sure that there was no VID previously set for this entity.
391+ if let Some ( ovid) = old_vid {
392+ bail ! (
393+ "VID: {} of entity: {} with ID: {} was already present when set in EntityCache" ,
394+ ovid,
395+ key. entity_type,
396+ entity. id( )
397+ ) ;
398+ }
399+
374400 self . entity_op ( key. clone ( ) , EntityOp :: Update ( entity) ) ;
375401
376402 // The updates we were given are not valid by themselves; force a
@@ -507,7 +533,7 @@ impl EntityCache {
507533 // Entity was removed and then updated, so it will be overwritten
508534 ( Some ( current) , EntityOp :: Overwrite ( data) ) => {
509535 let data = Arc :: new ( data) ;
510- self . current . insert ( key. clone ( ) , Some ( data. clone ( ) ) ) ;
536+ self . current . insert ( key. clone ( ) , Some ( data. cheap_clone ( ) ) ) ;
511537 if current != data {
512538 Some ( Overwrite {
513539 key,
0 commit comments