gitee.com/lh-her-team/common@v1.5.1/birdsnest/snapshot.go (about)

     1  // Package birdsnest snapshot
     2  package birdsnest
     3  
     4  import (
     5  	"os"
     6  	"path/filepath"
     7  	"strconv"
     8  	"sync"
     9  
    10  	"gitee.com/lh-her-team/common/wal"
    11  )
    12  
    13  // WalSnapshot wal snapshot
    14  type WalSnapshot struct {
    15  	snapshotM sync.Mutex
    16  	wal       *wal.Log
    17  }
    18  
    19  // NewWalSnapshot new wal snapshot eg: data/tx_filter/chainN/birdsnestN
    20  func NewWalSnapshot(path, name string, number int) (*WalSnapshot, error) {
    21  	opts := wal.DefaultOptions
    22  	opts.NoSync = false
    23  	if number > 0 {
    24  		// eg: data/txfilter/chainN/birdnest1
    25  		path = filepath.Join(path, name+strconv.Itoa(number))
    26  	} else {
    27  		// eg: data/txfilter/chainN/birdnest
    28  		path = filepath.Join(path, name)
    29  	}
    30  	err := createDirIfNotExist(path)
    31  	if err != nil {
    32  		return nil, err
    33  	}
    34  	file, err := wal.Open(path, opts)
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  	ws := &WalSnapshot{
    39  		wal:       file,
    40  		snapshotM: sync.Mutex{},
    41  	}
    42  	return ws, nil
    43  }
    44  
    45  // Read safe read wal
    46  func (s *WalSnapshot) Read() ([]byte, error) {
    47  	s.snapshotM.Lock()
    48  	defer s.snapshotM.Unlock()
    49  	index, err := s.wal.LastIndex()
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  	if index == 0 {
    54  		return nil, nil
    55  	}
    56  	read, err := s.wal.Read(index)
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  	return read, nil
    61  }
    62  
    63  // Write safe write wal
    64  func (s *WalSnapshot) Write(data []byte) error {
    65  	s.snapshotM.Lock()
    66  	defer s.snapshotM.Unlock()
    67  	index, err := s.wal.LastIndex()
    68  	if err != nil {
    69  		return err
    70  	}
    71  	index++
    72  	err = s.wal.Write(index, data)
    73  	if err != nil {
    74  		return err
    75  	}
    76  	err = s.wal.TruncateFront(index)
    77  	if err != nil {
    78  		return err
    79  	}
    80  	return nil
    81  }
    82  
    83  // createDirIfNotExist create dir if not exist
    84  func createDirIfNotExist(path string) error {
    85  	_, err := os.Stat(path)
    86  	if err == nil {
    87  		return nil
    88  	}
    89  	if os.IsNotExist(err) {
    90  		// create dir
    91  		err := os.MkdirAll(path, os.ModePerm)
    92  		if err != nil {
    93  			return err
    94  		}
    95  	}
    96  	return nil
    97  }