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

     1  // Copyright (c) 2020 IoTeX
     2  // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability
     3  // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed.
     4  // This source code is governed by Apache License 2.0 that can be found in the LICENSE file.
     5  
     6  package mptrie
     7  
     8  import (
     9  	"errors"
    10  
    11  	"google.golang.org/protobuf/proto"
    12  )
    13  
    14  type cacheNode struct {
    15  	dirty bool
    16  	serializable
    17  	hashVal []byte
    18  	ser     []byte
    19  }
    20  
    21  func (cn *cacheNode) Hash(cli client) ([]byte, error) {
    22  	return cn.hash(cli, false)
    23  }
    24  
    25  func (cn *cacheNode) hash(cli client, flush bool) ([]byte, error) {
    26  	if len(cn.hashVal) != 0 {
    27  		return cn.hashVal, nil
    28  	}
    29  	if cli == nil {
    30  		return []byte{}, errors.New("client cannot be nil")
    31  	}
    32  	pb, err := cn.proto(cli, flush)
    33  	if err != nil {
    34  		return nil, err
    35  	}
    36  	ser, err := proto.Marshal(pb)
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  
    41  	cn.ser = ser
    42  	cn.hashVal = cli.hash(ser)
    43  
    44  	return cn.hashVal, nil
    45  }
    46  
    47  func (cn *cacheNode) delete(cli client) error {
    48  	if !cn.dirty {
    49  		h, err := cn.hash(cli, false)
    50  		if err != nil {
    51  			return err
    52  		}
    53  		if err := cli.deleteNode(h); err != nil {
    54  			return err
    55  		}
    56  	}
    57  	cn.hashVal = nil
    58  	cn.ser = nil
    59  
    60  	return nil
    61  }
    62  
    63  func (cn *cacheNode) store(cli client) error {
    64  	if !cn.dirty {
    65  		return nil
    66  	}
    67  	h, err := cn.hash(cli, true)
    68  	if err != nil {
    69  		return err
    70  	}
    71  	if err := cli.putNode(h, cn.ser); err != nil {
    72  		return err
    73  	}
    74  	cn.dirty = false
    75  
    76  	return nil
    77  }