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 }