github.com/kaituanwang/hyperledger@v2.0.1+incompatible/core/ledger/kvledger/txmgmt/statedb/statecouchdb/redolog.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  SPDX-License-Identifier: Apache-2.0
     4  */
     5  
     6  package statecouchdb
     7  
     8  import (
     9  	"bytes"
    10  	"encoding/gob"
    11  
    12  	"github.com/hyperledger/fabric/common/ledger/util/leveldbhelper"
    13  	"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/statedb"
    14  	"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/version"
    15  )
    16  
    17  var redologKeyPrefix = []byte{byte(0)}
    18  
    19  type redoLoggerProvider struct {
    20  	leveldbProvider *leveldbhelper.Provider
    21  }
    22  type redoLogger struct {
    23  	dbName   string
    24  	dbHandle *leveldbhelper.DBHandle
    25  }
    26  
    27  type redoRecord struct {
    28  	UpdateBatch *statedb.UpdateBatch
    29  	Version     *version.Height
    30  }
    31  
    32  func newRedoLoggerProvider(dirPath string) (*redoLoggerProvider, error) {
    33  	provider, err := leveldbhelper.NewProvider(&leveldbhelper.Conf{DBPath: dirPath})
    34  	if err != nil {
    35  		return nil, err
    36  	}
    37  	return &redoLoggerProvider{leveldbProvider: provider}, nil
    38  }
    39  
    40  func (p *redoLoggerProvider) newRedoLogger(dbName string) *redoLogger {
    41  	return &redoLogger{
    42  		dbHandle: p.leveldbProvider.GetDBHandle(dbName),
    43  	}
    44  }
    45  
    46  func (p *redoLoggerProvider) close() {
    47  	p.leveldbProvider.Close()
    48  }
    49  
    50  func (l *redoLogger) persist(r *redoRecord) error {
    51  	k := encodeRedologKey(l.dbName)
    52  	v, err := encodeRedologVal(r)
    53  	if err != nil {
    54  		return err
    55  	}
    56  	return l.dbHandle.Put(k, v, true)
    57  }
    58  
    59  func (l *redoLogger) load() (*redoRecord, error) {
    60  	k := encodeRedologKey(l.dbName)
    61  	v, err := l.dbHandle.Get(k)
    62  	if err != nil || v == nil {
    63  		return nil, err
    64  	}
    65  	return decodeRedologVal(v)
    66  }
    67  
    68  func encodeRedologKey(dbName string) []byte {
    69  	return append(redologKeyPrefix, []byte(dbName)...)
    70  }
    71  
    72  func encodeRedologVal(r *redoRecord) ([]byte, error) {
    73  	buf := bytes.NewBuffer(nil)
    74  	encoder := gob.NewEncoder(buf)
    75  	if err := encoder.Encode(r); err != nil {
    76  		return nil, err
    77  	}
    78  	return buf.Bytes(), nil
    79  }
    80  
    81  func decodeRedologVal(b []byte) (*redoRecord, error) {
    82  	decoder := gob.NewDecoder(bytes.NewBuffer(b))
    83  	var r *redoRecord
    84  	if err := decoder.Decode(&r); err != nil {
    85  		return nil, err
    86  	}
    87  	return r, nil
    88  }