github.com/iotexproject/iotex-core@v1.14.1-rc1/db/trie/mptrie/log.go (about)

     1  package mptrie
     2  
     3  import (
     4  	"bufio"
     5  	"os"
     6  
     7  	"github.com/pkg/errors"
     8  )
     9  
    10  var (
    11  	enabledLogMptrie = false
    12  	logFile          *os.File
    13  	logWriter        *bufio.Writer
    14  )
    15  
    16  type nodeType byte
    17  type actionType byte
    18  
    19  const (
    20  	_nodeTypeLeaf      nodeType = 'l'
    21  	_nodeTypeExtension nodeType = 'e'
    22  	_nodeTypeBranch    nodeType = 'b'
    23  
    24  	_actionTypeSearch actionType = 's'
    25  	_actionTypeUpsert actionType = 'u'
    26  	_actionTypeDelete actionType = 'd'
    27  	_actionTypeNew    actionType = 'n'
    28  )
    29  
    30  // nodeEvent is the event of node
    31  type nodeEvent struct {
    32  	NodeType    nodeType
    33  	ActionType  actionType
    34  	KeyLen      uint8
    35  	Key         []byte
    36  	PathLen     uint8
    37  	Path        []byte
    38  	ChildrenLen uint8
    39  	Children    []byte
    40  	HashLen     uint8
    41  	HashVal     []byte
    42  }
    43  
    44  // Bytes returns the bytes of node event
    45  func (e nodeEvent) Bytes() []byte {
    46  	b := make([]byte, 0, 1+1+1+e.KeyLen+1+e.PathLen+1+e.ChildrenLen+1+e.HashLen)
    47  	b = append(b, byte(e.NodeType))
    48  	b = append(b, byte(e.ActionType))
    49  	b = append(b, e.KeyLen)
    50  	b = append(b, e.Key...)
    51  	b = append(b, e.PathLen)
    52  	b = append(b, e.Path...)
    53  	b = append(b, e.ChildrenLen)
    54  	b = append(b, e.Children...)
    55  	b = append(b, e.HashLen)
    56  	b = append(b, e.HashVal...)
    57  	return b
    58  }
    59  
    60  // OpenLogDB open the log DB file
    61  func OpenLogDB(dbPath string) error {
    62  	var err error
    63  	logFile, err = os.OpenFile(dbPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
    64  	if err != nil {
    65  		return err
    66  	}
    67  	logWriter = bufio.NewWriter(logFile)
    68  	enabledLogMptrie = true
    69  	return nil
    70  }
    71  
    72  // CloseLogDB close the log DB file
    73  func CloseLogDB() error {
    74  	if !enabledLogMptrie {
    75  		return nil
    76  	}
    77  	if err := logWriter.Flush(); err != nil {
    78  		return err
    79  	}
    80  	return logFile.Close()
    81  }
    82  
    83  func logNode(nt nodeType, at actionType, n node, cli client) error {
    84  	if !enabledLogMptrie {
    85  		return nil
    86  	}
    87  	nodeKey, nodePath, nodeChildren, hashvalue, err := parseNode(n, cli)
    88  	if err != nil {
    89  		return err
    90  	}
    91  	event := nodeEvent{
    92  		NodeType:    nt,
    93  		ActionType:  at,
    94  		KeyLen:      uint8(len(nodeKey)),
    95  		Key:         nodeKey,
    96  		PathLen:     uint8(len(nodePath)),
    97  		Path:        nodePath,
    98  		ChildrenLen: uint8(len(nodeChildren)),
    99  		Children:    nodeChildren,
   100  		HashLen:     uint8(len(hashvalue)),
   101  		HashVal:     hashvalue,
   102  	}
   103  	// write event length
   104  	if err = logWriter.WriteByte(byte(len(event.Bytes()))); err != nil {
   105  		return err
   106  	}
   107  	// write event body
   108  	_, err = logWriter.Write(event.Bytes())
   109  	return err
   110  }
   111  
   112  func parseNode(n node, cli client) (nodeKey, nodePath, nodeChildren, hashvalue []byte, err error) {
   113  	switch n := n.(type) {
   114  	case *leafNode:
   115  		nodeKey = n.key
   116  		hashvalue, err = n.cacheNode.Hash(cli)
   117  	case *extensionNode:
   118  		nodePath = n.path
   119  		hashvalue, err = n.cacheNode.Hash(cli)
   120  	case *branchNode:
   121  		nodeChildren = n.indices.List()
   122  		hashvalue, err = n.cacheNode.Hash(cli)
   123  	default:
   124  		err = errors.Errorf("unknown node type %T", n)
   125  	}
   126  	return
   127  }