github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/swarm/storage/memstore.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:49</date>
    10  //</624342681736187904>
    11  
    12  //
    13  //
    14  //
    15  //
    16  //
    17  //
    18  //
    19  //
    20  //
    21  //
    22  //
    23  //
    24  //
    25  //
    26  //
    27  
    28  //
    29  
    30  package storage
    31  
    32  import (
    33  	"context"
    34  	"sync"
    35  
    36  	lru "github.com/hashicorp/golang-lru"
    37  )
    38  
    39  type MemStore struct {
    40  	cache    *lru.Cache
    41  	requests *lru.Cache
    42  	mu       sync.RWMutex
    43  	disabled bool
    44  }
    45  
    46  //
    47  //
    48  //
    49  //
    50  //
    51  //
    52  func NewMemStore(params *StoreParams, _ *LDBStore) (m *MemStore) {
    53  	if params.CacheCapacity == 0 {
    54  		return &MemStore{
    55  			disabled: true,
    56  		}
    57  	}
    58  
    59  	onEvicted := func(key interface{}, value interface{}) {
    60  		v := value.(*Chunk)
    61  		<-v.dbStoredC
    62  	}
    63  	c, err := lru.NewWithEvict(int(params.CacheCapacity), onEvicted)
    64  	if err != nil {
    65  		panic(err)
    66  	}
    67  
    68  	requestEvicted := func(key interface{}, value interface{}) {
    69  //
    70  //
    71  	}
    72  	r, err := lru.NewWithEvict(int(params.ChunkRequestsCacheCapacity), requestEvicted)
    73  	if err != nil {
    74  		panic(err)
    75  	}
    76  
    77  	return &MemStore{
    78  		cache:    c,
    79  		requests: r,
    80  	}
    81  }
    82  
    83  func (m *MemStore) Get(ctx context.Context, addr Address) (*Chunk, error) {
    84  	if m.disabled {
    85  		return nil, ErrChunkNotFound
    86  	}
    87  
    88  	m.mu.RLock()
    89  	defer m.mu.RUnlock()
    90  
    91  	r, ok := m.requests.Get(string(addr))
    92  //
    93  	if ok {
    94  		return r.(*Chunk), nil
    95  	}
    96  
    97  //
    98  	c, ok := m.cache.Get(string(addr))
    99  	if !ok {
   100  		return nil, ErrChunkNotFound
   101  	}
   102  	return c.(*Chunk), nil
   103  }
   104  
   105  func (m *MemStore) Put(ctx context.Context, c *Chunk) {
   106  	if m.disabled {
   107  		return
   108  	}
   109  
   110  	m.mu.Lock()
   111  	defer m.mu.Unlock()
   112  
   113  //
   114  	if c.ReqC != nil {
   115  		select {
   116  		case <-c.ReqC:
   117  			if c.GetErrored() != nil {
   118  				m.requests.Remove(string(c.Addr))
   119  				return
   120  			}
   121  			m.cache.Add(string(c.Addr), c)
   122  			m.requests.Remove(string(c.Addr))
   123  		default:
   124  			m.requests.Add(string(c.Addr), c)
   125  		}
   126  		return
   127  	}
   128  
   129  //
   130  	m.cache.Add(string(c.Addr), c)
   131  	m.requests.Remove(string(c.Addr))
   132  }
   133  
   134  func (m *MemStore) setCapacity(n int) {
   135  	if n <= 0 {
   136  		m.disabled = true
   137  	} else {
   138  		onEvicted := func(key interface{}, value interface{}) {
   139  			v := value.(*Chunk)
   140  			<-v.dbStoredC
   141  		}
   142  		c, err := lru.NewWithEvict(n, onEvicted)
   143  		if err != nil {
   144  			panic(err)
   145  		}
   146  
   147  		r, err := lru.New(defaultChunkRequestsCacheCapacity)
   148  		if err != nil {
   149  			panic(err)
   150  		}
   151  
   152  		m = &MemStore{
   153  			cache:    c,
   154  			requests: r,
   155  		}
   156  	}
   157  }
   158  
   159  func (s *MemStore) Close() {}
   160