@@ -44,6 +44,13 @@ type Datastore struct {
44
44
syncWrites bool
45
45
}
46
46
47
+ // Implements the datastore.Batch interface, enabling batching support for
48
+ // the badger Datastore.
49
+ type batch struct {
50
+ ds * Datastore
51
+ writeBatch * badger.WriteBatch
52
+ }
53
+
47
54
// Implements the datastore.Txn interface, enabling transaction support for
48
55
// the badger Datastore.
49
56
type txn struct {
@@ -112,6 +119,7 @@ var _ ds.Datastore = (*Datastore)(nil)
112
119
var _ ds.TxnDatastore = (* Datastore )(nil )
113
120
var _ ds.TTLDatastore = (* Datastore )(nil )
114
121
var _ ds.GCDatastore = (* Datastore )(nil )
122
+ var _ ds.Batching = (* Datastore )(nil )
115
123
116
124
// NewDatastore creates a new badger datastore.
117
125
//
@@ -388,9 +396,21 @@ func (d *Datastore) Close() error {
388
396
return d .DB .Close ()
389
397
}
390
398
399
+ // Batch creats a new Batch object. This provides a way to do many writes, when
400
+ // there may be too many to fit into a single transaction.
401
+ //
402
+ // After writing to a Batch, always call Commit whether or not writing to the
403
+ // batch was completed successfully or not. This is necessary to flush any
404
+ // remaining data and free any resources associated with an incomplete
405
+ // transaction.
391
406
func (d * Datastore ) Batch () (ds.Batch , error ) {
392
- tx , _ := d .NewTransaction (false )
393
- return tx , nil
407
+ d .closeLk .RLock ()
408
+ defer d .closeLk .RUnlock ()
409
+ if d .closed {
410
+ return nil , ErrClosed
411
+ }
412
+
413
+ return & batch {d , d .DB .NewWriteBatch ()}, nil
394
414
}
395
415
396
416
func (d * Datastore ) CollectGarbage () (err error ) {
@@ -416,6 +436,54 @@ func (d *Datastore) gcOnce() error {
416
436
return d .DB .RunValueLogGC (d .gcDiscardRatio )
417
437
}
418
438
439
+ var _ ds.Batch = (* batch )(nil )
440
+
441
+ func (b * batch ) Put (key ds.Key , value []byte ) error {
442
+ b .ds .closeLk .RLock ()
443
+ defer b .ds .closeLk .RUnlock ()
444
+ if b .ds .closed {
445
+ return ErrClosed
446
+ }
447
+ return b .put (key , value )
448
+ }
449
+
450
+ func (b * batch ) put (key ds.Key , value []byte ) error {
451
+ return b .writeBatch .Set (key .Bytes (), value )
452
+ }
453
+
454
+ func (b * batch ) Delete (key ds.Key ) error {
455
+ b .ds .closeLk .RLock ()
456
+ defer b .ds .closeLk .RUnlock ()
457
+ if b .ds .closed {
458
+ return ErrClosed
459
+ }
460
+
461
+ return b .delete (key )
462
+ }
463
+
464
+ func (b * batch ) delete (key ds.Key ) error {
465
+ return b .writeBatch .Delete (key .Bytes ())
466
+ }
467
+
468
+ func (b * batch ) Commit () error {
469
+ b .ds .closeLk .RLock ()
470
+ defer b .ds .closeLk .RUnlock ()
471
+ if b .ds .closed {
472
+ return ErrClosed
473
+ }
474
+
475
+ return b .commit ()
476
+ }
477
+
478
+ func (b * batch ) commit () error {
479
+ err := b .writeBatch .Flush ()
480
+ if err != nil {
481
+ // Discard incomplete transaction held by b.writeBatch
482
+ b .writeBatch .Cancel ()
483
+ }
484
+ return err
485
+ }
486
+
419
487
var _ ds.Datastore = (* txn )(nil )
420
488
var _ ds.TTLDatastore = (* txn )(nil )
421
489
0 commit comments