@@ -37,6 +37,7 @@ type TXIDStoreReader[V driver.ValidationCode] interface {
37
37
type TXIDStore [V driver.ValidationCode ] interface {
38
38
TXIDStoreReader [V ]
39
39
Set (txID driver.TxID , code V , message string ) error
40
+ SetMultiple (txs []driver.ByNum [V ]) error
40
41
Invalidate (txID driver.TxID )
41
42
}
42
43
@@ -289,94 +290,110 @@ func (db *Vault[V]) commitRWs(inputs ...commitInput) error {
289
290
return errors .Wrapf (err , "begin update in store for txid %v failed" , inputs )
290
291
}
291
292
292
- for _ , input := range inputs {
293
- span := trace .SpanFromContext (input .ctx )
293
+ if _ , err := db .setStatuses (inputs , db .vcProvider .Busy ()); err != nil {
294
+ return err
295
+ }
294
296
295
- span .AddEvent ("set_tx_busy" )
296
- if err := db .txIDStore .Set (input .txID , db .vcProvider .Busy (), "" ); err != nil {
297
- if ! errors .HasCause (err , UniqueKeyViolation ) {
298
- return err
297
+ db .logger .Debugf ("parse writes" )
298
+ writes := make (map [driver.Namespace ]map [driver.PKey ]VersionedValue )
299
+ for _ , input := range inputs {
300
+ for ns , ws := range input .rws .Writes {
301
+ vals := versionedValues (ws , input .block , input .indexInBloc )
302
+ if nsWrites , ok := writes [ns ]; ! ok {
303
+ writes [ns ] = vals
304
+ } else {
305
+ collections .CopyMap (nsWrites , vals )
299
306
}
300
307
}
308
+ }
301
309
302
- db .logger .Debugf ("parse writes [%s]" , input .txID )
303
- span .AddEvent ("store_writes" )
304
- if discarded , err := db .storeWrites (input .ctx , input .rws .Writes , input .block , input .indexInBloc ); err != nil {
305
- return errors .Wrapf (err , "failed storing writes" )
306
- } else if discarded {
307
- db .logger .Infof ("Discarded changes while storing writes as duplicates. Skipping..." )
310
+ if errs := db .storeAllWrites (writes ); len (errs ) == 0 {
311
+ db .logger .Debugf ("Successfully stored writes for %d namespaces" , len (writes ))
312
+ } else if discarded , err := db .discard ("" , 0 , 0 , errs ); err != nil {
313
+ return errors .Wrapf (err , "failed storing writes" )
314
+ } else if discarded {
315
+ db .logger .Infof ("Discarded changes while storing writes as duplicates. Skipping..." )
316
+ for _ , input := range inputs {
308
317
db .txIDStore .Invalidate (input .txID )
309
- return nil
310
318
}
319
+ return nil
320
+ }
311
321
312
- db .logger .Debugf ("parse meta writes [%s]" , input .txID )
313
- span .AddEvent ("store_meta_writes" )
314
- if discarded , err := db .storeMetaWrites (input .ctx , input .rws .MetaWrites , input .block , input .indexInBloc ); err != nil {
315
- return errors .Wrapf (err , "failed storing meta writes" )
316
- } else if discarded {
317
- db .logger .Infof ("Discarded changes while storing meta writes as duplicates. Skipping..." )
322
+ db .logger .Debugf ("parse meta writes" )
323
+ metaWrites := make (map [driver.Namespace ]map [driver.PKey ]driver.VersionedMetadataValue )
324
+ for _ , input := range inputs {
325
+ for ns , ws := range input .rws .MetaWrites {
326
+ vals := versionedMetaValues (ws , input .block , input .indexInBloc )
327
+ if nsWrites , ok := metaWrites [ns ]; ! ok {
328
+ metaWrites [ns ] = vals
329
+ } else {
330
+ collections .CopyMap (nsWrites , vals )
331
+ }
332
+ }
333
+ }
334
+ if errs := db .storeAllMetaWrites (metaWrites ); len (errs ) == 0 {
335
+ db .logger .Debugf ("Successfully stored meta writes for %d namespaces" , len (metaWrites ))
336
+ } else if discarded , err := db .discard ("" , 0 , 0 , errs ); err != nil {
337
+ return errors .Wrapf (err , "failed storing meta writes" )
338
+ } else if discarded {
339
+ db .logger .Infof ("Discarded changes while storing meta writes as duplicates. Skipping..." )
340
+ for _ , input := range inputs {
318
341
db .txIDStore .Invalidate (input .txID )
319
- return nil
320
342
}
343
+ return nil
344
+ }
321
345
322
- db .logger .Debugf ("set state to valid [%s]" , input .txID )
323
- span .AddEvent ("set_tx_valid" )
324
- if discarded , err := db .setTxValid (input .txID ); err != nil {
325
- return errors .Wrapf (err , "failed setting tx state to valid" )
326
- } else if discarded {
327
- db .logger .Infof ("Discarded changes while setting tx state to valid as duplicates. Skipping..." )
328
- return nil
346
+ if discarded , err := db .setStatuses (inputs , db .vcProvider .Valid ()); err != nil {
347
+ if err1 := db .store .Discard (); err1 != nil {
348
+ db .logger .Errorf ("got error %s; discarding caused %s" , err .Error (), err1 .Error ())
329
349
}
330
-
350
+ for _ , input := range inputs {
351
+ db .txIDStore .Invalidate (input .txID )
352
+ }
353
+ return errors .Wrapf (err , "failed setting tx state to valid" )
354
+ } else if discarded {
355
+ if err1 := db .store .Discard (); err1 != nil {
356
+ db .logger .Errorf ("got unique key violation; discarding caused %s" , err1 .Error ())
357
+ }
358
+ db .logger .Infof ("Discarded changes while setting tx state to valid as duplicates. Skipping..." )
359
+ return nil
331
360
}
332
361
333
- for _ , input := range inputs {
334
- trace .SpanFromContext (input .ctx ).AddEvent ("commit_update" )
335
- }
336
362
if err := db .store .Commit (); err != nil {
337
363
return errors .Wrapf (err , "committing tx for txid in store [%v] failed" , inputs )
338
364
}
339
-
340
365
return nil
341
366
}
342
367
343
- func (db * Vault [V ]) setTxValid ( txID driver. TxID ) (bool , error ) {
344
- err := db . txIDStore . Set ( txID , db . vcProvider . Valid (), "" )
345
- if err == nil {
346
- return false , nil
368
+ func (db * Vault [V ]) setStatuses ( inputs [] commitInput , v V ) (bool , error ) {
369
+ txs := make ([]driver. ByNum [ V ], len ( inputs ) )
370
+ for i , input := range inputs {
371
+ txs [ i ] = driver. ByNum [ V ]{ TxID : input . txID , Code : v }
347
372
}
348
373
349
- if err1 := db .store .Discard (); err1 != nil {
350
- db .logger .Errorf ("got error %s; discarding caused %s" , err .Error (), err1 .Error ())
351
- }
352
-
353
- if ! errors .HasCause (err , UniqueKeyViolation ) {
354
- db .txIDStore .Invalidate (txID )
355
- return true , errors .Wrapf (err , "error setting tx valid" )
374
+ if err := db .txIDStore .SetMultiple (txs ); err == nil {
375
+ return false , nil
376
+ } else if ! errors .HasCause (err , UniqueKeyViolation ) {
377
+ return true , err
378
+ } else {
379
+ return true , nil
356
380
}
357
- return true , nil
358
381
}
359
382
360
- func (db * Vault [V ]) storeMetaWrites (ctx context.Context , writes NamespaceKeyedMetaWrites , block driver.BlockNum , indexInBloc driver.TxNum ) (bool , error ) {
361
- span := trace .SpanFromContext (ctx )
362
- for ns , keyMap := range writes {
363
- span .AddEvent ("set_tx_metadata_state" )
364
- if errs := db .store .SetStateMetadatas (ns , keyMap , block , indexInBloc ); len (errs ) > 0 {
365
- return db .discard (ns , block , indexInBloc , errs )
366
- }
383
+ func (db * Vault [V ]) storeAllWrites (writes map [driver.Namespace ]map [driver.PKey ]VersionedValue ) map [driver.PKey ]error {
384
+ errs := make (map [driver.PKey ]error )
385
+ for ns , vals := range writes {
386
+ collections .CopyMap (errs , db .store .SetStates (ns , vals ))
367
387
}
368
- return false , nil
388
+ return errs
369
389
}
370
390
371
- func (db * Vault [V ]) storeWrites (ctx context.Context , writes Writes , block driver.BlockNum , indexInBloc driver.TxNum ) (bool , error ) {
372
- span := trace .SpanFromContext (ctx )
373
- for ns , keyMap := range writes {
374
- span .AddEvent ("set_tx_states" )
375
- if errs := db .store .SetStates (ns , versionedValues (keyMap , block , indexInBloc )); len (errs ) > 0 {
376
- return db .discard (ns , block , indexInBloc , errs )
377
- }
391
+ func (db * Vault [V ]) storeAllMetaWrites (metaWrites map [driver.Namespace ]map [driver.PKey ]driver.VersionedMetadataValue ) map [driver.PKey ]error {
392
+ errs := make (map [driver.PKey ]error )
393
+ for ns , vals := range metaWrites {
394
+ collections .CopyMap (errs , db .store .SetStateMetadatas (ns , vals ))
378
395
}
379
- return false , nil
396
+ return errs
380
397
}
381
398
382
399
func versionedValues (keyMap NamespaceWrites , block driver.BlockNum , indexInBloc driver.TxNum ) map [driver.PKey ]VersionedValue {
@@ -387,6 +404,14 @@ func versionedValues(keyMap NamespaceWrites, block driver.BlockNum, indexInBloc
387
404
return vals
388
405
}
389
406
407
+ func versionedMetaValues (keyMap KeyedMetaWrites , block driver.BlockNum , indexInBloc driver.TxNum ) map [driver.PKey ]driver.VersionedMetadataValue {
408
+ vals := make (map [driver.PKey ]driver.VersionedMetadataValue , len (keyMap ))
409
+ for pkey , val := range keyMap {
410
+ vals [pkey ] = driver.VersionedMetadataValue {Metadata : val , Block : block , TxNum : indexInBloc }
411
+ }
412
+ return vals
413
+ }
414
+
390
415
func (db * Vault [V ]) discard (ns driver.Namespace , block driver.BlockNum , indexInBloc driver.TxNum , errs map [driver.PKey ]error ) (bool , error ) {
391
416
if err1 := db .store .Discard (); err1 != nil {
392
417
db .logger .Errorf ("got error %v; discarding caused %s" , errors2 .Join (collections .Values (errs )... ), err1 .Error ())
0 commit comments