github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/storage/memstore.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  package storage
    28  
    29  import (
    30  	"context"
    31  	"sync"
    32  
    33  	lru "github.com/hashicorp/golang-lru"
    34  )
    35  
    36  type MemStore struct {
    37  	cache    *lru.Cache
    38  	requests *lru.Cache
    39  	mu       sync.RWMutex
    40  	disabled bool
    41  }
    42  
    43  //
    44  //
    45  //
    46  //
    47  //
    48  //
    49  func NewMemStore(params *StoreParams, _ *LDBStore) (m *MemStore) {
    50  	if params.CacheCapacity == 0 {
    51  		return &MemStore{
    52  			disabled: true,
    53  		}
    54  	}
    55  
    56  	onEvicted := func(key interface{}, value interface{}) {
    57  		v := value.(*Chunk)
    58  		<-v.dbStoredC
    59  	}
    60  	c, err := lru.NewWithEvict(int(params.CacheCapacity), onEvicted)
    61  	if err != nil {
    62  		panic(err)
    63  	}
    64  
    65  	requestEvicted := func(key interface{}, value interface{}) {
    66  //
    67  //
    68  	}
    69  	r, err := lru.NewWithEvict(int(params.ChunkRequestsCacheCapacity), requestEvicted)
    70  	if err != nil {
    71  		panic(err)
    72  	}
    73  
    74  	return &MemStore{
    75  		cache:    c,
    76  		requests: r,
    77  	}
    78  }
    79  
    80  func (m *MemStore) Get(ctx context.Context, addr Address) (*Chunk, error) {
    81  	if m.disabled {
    82  		return nil, ErrChunkNotFound
    83  	}
    84  
    85  	m.mu.RLock()
    86  	defer m.mu.RUnlock()
    87  
    88  	r, ok := m.requests.Get(string(addr))
    89  //
    90  	if ok {
    91  		return r.(*Chunk), nil
    92  	}
    93  
    94  //
    95  	c, ok := m.cache.Get(string(addr))
    96  	if !ok {
    97  		return nil, ErrChunkNotFound
    98  	}
    99  	return c.(*Chunk), nil
   100  }
   101  
   102  func (m *MemStore) Put(ctx context.Context, c *Chunk) {
   103  	if m.disabled {
   104  		return
   105  	}
   106  
   107  	m.mu.Lock()
   108  	defer m.mu.Unlock()
   109  
   110  //
   111  	if c.ReqC != nil {
   112  		select {
   113  		case <-c.ReqC:
   114  			if c.GetErrored() != nil {
   115  				m.requests.Remove(string(c.Addr))
   116  				return
   117  			}
   118  			m.cache.Add(string(c.Addr), c)
   119  			m.requests.Remove(string(c.Addr))
   120  		default:
   121  			m.requests.Add(string(c.Addr), c)
   122  		}
   123  		return
   124  	}
   125  
   126  //
   127  	m.cache.Add(string(c.Addr), c)
   128  	m.requests.Remove(string(c.Addr))
   129  }
   130  
   131  func (m *MemStore) setCapacity(n int) {
   132  	if n <= 0 {
   133  		m.disabled = true
   134  	} else {
   135  		onEvicted := func(key interface{}, value interface{}) {
   136  			v := value.(*Chunk)
   137  			<-v.dbStoredC
   138  		}
   139  		c, err := lru.NewWithEvict(n, onEvicted)
   140  		if err != nil {
   141  			panic(err)
   142  		}
   143  
   144  		r, err := lru.New(defaultChunkRequestsCacheCapacity)
   145  		if err != nil {
   146  			panic(err)
   147  		}
   148  
   149  		m = &MemStore{
   150  			cache:    c,
   151  			requests: r,
   152  		}
   153  	}
   154  }
   155  
   156  func (s *MemStore) Close() {}