github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/storage/mock/mem/mem.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //
    10  //
    11  //
    12  //
    13  //
    14  //
    15  //
    16  //
    17  //
    18  //
    19  //
    20  //
    21  //
    22  //
    23  //
    24  
    25  //
    26  //
    27  //
    28  package mem
    29  
    30  import (
    31  	"archive/tar"
    32  	"bytes"
    33  	"encoding/json"
    34  	"io"
    35  	"io/ioutil"
    36  	"sync"
    37  
    38  	"github.com/ethereum/go-ethereum/common"
    39  	"github.com/ethereum/go-ethereum/swarm/storage/mock"
    40  )
    41  
    42  //
    43  //
    44  type GlobalStore struct {
    45  	nodes map[string]map[common.Address]struct{}
    46  	data  map[string][]byte
    47  	mu    sync.Mutex
    48  }
    49  
    50  //
    51  func NewGlobalStore() *GlobalStore {
    52  	return &GlobalStore{
    53  		nodes: make(map[string]map[common.Address]struct{}),
    54  		data:  make(map[string][]byte),
    55  	}
    56  }
    57  
    58  //
    59  //
    60  func (s *GlobalStore) NewNodeStore(addr common.Address) *mock.NodeStore {
    61  	return mock.NewNodeStore(addr, s)
    62  }
    63  
    64  //
    65  //
    66  func (s *GlobalStore) Get(addr common.Address, key []byte) (data []byte, err error) {
    67  	s.mu.Lock()
    68  	defer s.mu.Unlock()
    69  
    70  	if _, ok := s.nodes[string(key)][addr]; !ok {
    71  		return nil, mock.ErrNotFound
    72  	}
    73  
    74  	data, ok := s.data[string(key)]
    75  	if !ok {
    76  		return nil, mock.ErrNotFound
    77  	}
    78  	return data, nil
    79  }
    80  
    81  //
    82  func (s *GlobalStore) Put(addr common.Address, key []byte, data []byte) error {
    83  	s.mu.Lock()
    84  	defer s.mu.Unlock()
    85  
    86  	if _, ok := s.nodes[string(key)]; !ok {
    87  		s.nodes[string(key)] = make(map[common.Address]struct{})
    88  	}
    89  	s.nodes[string(key)][addr] = struct{}{}
    90  	s.data[string(key)] = data
    91  	return nil
    92  }
    93  
    94  //
    95  func (s *GlobalStore) HasKey(addr common.Address, key []byte) bool {
    96  	s.mu.Lock()
    97  	defer s.mu.Unlock()
    98  
    99  	_, ok := s.nodes[string(key)][addr]
   100  	return ok
   101  }
   102  
   103  //
   104  //
   105  func (s *GlobalStore) Import(r io.Reader) (n int, err error) {
   106  	s.mu.Lock()
   107  	defer s.mu.Unlock()
   108  
   109  	tr := tar.NewReader(r)
   110  
   111  	for {
   112  		hdr, err := tr.Next()
   113  		if err != nil {
   114  			if err == io.EOF {
   115  				break
   116  			}
   117  			return n, err
   118  		}
   119  
   120  		data, err := ioutil.ReadAll(tr)
   121  		if err != nil {
   122  			return n, err
   123  		}
   124  
   125  		var c mock.ExportedChunk
   126  		if err = json.Unmarshal(data, &c); err != nil {
   127  			return n, err
   128  		}
   129  
   130  		addrs := make(map[common.Address]struct{})
   131  		for _, a := range c.Addrs {
   132  			addrs[a] = struct{}{}
   133  		}
   134  
   135  		key := string(common.Hex2Bytes(hdr.Name))
   136  		s.nodes[key] = addrs
   137  		s.data[key] = c.Data
   138  		n++
   139  	}
   140  	return n, err
   141  }
   142  
   143  //
   144  //
   145  func (s *GlobalStore) Export(w io.Writer) (n int, err error) {
   146  	s.mu.Lock()
   147  	defer s.mu.Unlock()
   148  
   149  	tw := tar.NewWriter(w)
   150  	defer tw.Close()
   151  
   152  	buf := bytes.NewBuffer(make([]byte, 0, 1024))
   153  	encoder := json.NewEncoder(buf)
   154  	for key, addrs := range s.nodes {
   155  		al := make([]common.Address, 0, len(addrs))
   156  		for a := range addrs {
   157  			al = append(al, a)
   158  		}
   159  
   160  		buf.Reset()
   161  		if err = encoder.Encode(mock.ExportedChunk{
   162  			Addrs: al,
   163  			Data:  s.data[key],
   164  		}); err != nil {
   165  			return n, err
   166  		}
   167  
   168  		data := buf.Bytes()
   169  		hdr := &tar.Header{
   170  			Name: common.Bytes2Hex([]byte(key)),
   171  			Mode: 0644,
   172  			Size: int64(len(data)),
   173  		}
   174  		if err := tw.WriteHeader(hdr); err != nil {
   175  			return n, err
   176  		}
   177  		if _, err := tw.Write(data); err != nil {
   178  			return n, err
   179  		}
   180  		n++
   181  	}
   182  	return n, err
   183  }