// NewBatch returns an implementation that allows batch writes. Note that the bolt // implementation spawns a goroutine that will live until a Commit() is issued. func (bdb *BoltDB) NewBatch() Batch { b := new(batch) b.db = bdb.db b.ch = make(chan batchOp) go func() { tx, err := b.db.Begin(true) if err != nil { dvid.Error("Error on beginning bolt db batch write: %s", err.Error()) return } for { curOp := <-b.ch // If this is the first op, determine the Bucket based on the key type. if b.bucket == nil { if curOp.kv.K == nil { dvid.Error("Nil key sent to bolt db batch routine!") return } bucketName := curOp.kv.K.KeyType().String() b.bucket = tx.Bucket(bucketName) } // Do the operation. switch curOp.op { case PutOp: kBytes := curOp.kv.K.Bytes() if err := b.bucket.Put(kBytes, curOp.kv.V); err != nil { dvid.Error("Error in bolt db batch Put: %s", err.Error()) return } StoreKeyBytesWritten <- len(kBytes) StoreValueBytesWritten <- len(curOp.kv.V) case DeleteOp: kBytes := curOp.kv.K.Bytes() if err := b.bucket.Delete(kBytes); err != nil { dvid.Error("Error in bolt db batch Delete: %s", err.Error()) return } case CommitOp: tx.Commit() return default: dvid.Error("Unknown batch op %d", curOp.op) return } } }() return b }
func (b *batch) Delete(k Key) { if b != nil { dvid.StartCgo() defer dvid.StopCgo() if err := b.txn.Del(b.dbi, k.Bytes(), nil); err != nil { dvid.Error("Error in batch Delete: %s", err.Error()) } } }
// NewBatch returns an implementation that allows batch writes. This lmdb implementation // uses a transaction for the batch. func (db *LMDB) NewBatch() Batch { if db == nil || db.env == nil { dvid.Error("Cannot do NewBatch() of lmdb with nil database") return nil } b := new(batch) b.env = db.env b.dbi = db.dbi dvid.StartCgo() defer dvid.StopCgo() txn, err := db.env.BeginTxn(nil, 0) if err != nil { dvid.Error("Error in BeginTxn() for NewBatch() of lmdb") return nil } b.txn = txn return b }
func (b *batch) Put(k Key, v []byte) { if b != nil { dvid.StartCgo() defer dvid.StopCgo() kBytes := k.Bytes() if v == nil || len(v) == 0 { v = []byte{0} } if err := b.txn.Put(b.dbi, kBytes, v, 0); err != nil { dvid.Error("Error in batch Put: %s", err.Error()) return } StoreKeyBytesWritten <- len(kBytes) StoreValueBytesWritten <- len(v) } }