Merge pull request #317 from nspcc-dev/fix/data-race-in-memeory-store

Fix DataRace in MemoryStore
- Add RWMutex to MemoryStore struct
- Use Lock/Unlock for writing
- Use RLock/RUnlock for reading
- Fix #313 issue
This commit is contained in:
Evgeniy Kulikov 2019-08-27 16:51:54 +03:00 committed by GitHub
commit 96169ef266
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -2,11 +2,13 @@ package storage
import ( import (
"encoding/hex" "encoding/hex"
"sync"
) )
// MemoryStore is an in-memory implementation of a Store, mainly // MemoryStore is an in-memory implementation of a Store, mainly
// used for testing. Do not use MemoryStore in production. // used for testing. Do not use MemoryStore in production.
type MemoryStore struct { type MemoryStore struct {
*sync.RWMutex
mem map[string][]byte mem map[string][]byte
} }
@ -29,12 +31,15 @@ func (b *MemoryBatch) Len() int {
// NewMemoryStore creates a new MemoryStore object. // NewMemoryStore creates a new MemoryStore object.
func NewMemoryStore() *MemoryStore { func NewMemoryStore() *MemoryStore {
return &MemoryStore{ return &MemoryStore{
RWMutex: new(sync.RWMutex),
mem: make(map[string][]byte), mem: make(map[string][]byte),
} }
} }
// Get implements the Store interface. // Get implements the Store interface.
func (s *MemoryStore) Get(key []byte) ([]byte, error) { func (s *MemoryStore) Get(key []byte) ([]byte, error) {
s.RLock()
defer s.RUnlock()
if val, ok := s.mem[makeKey(key)]; ok { if val, ok := s.mem[makeKey(key)]; ok {
return val, nil return val, nil
} }
@ -43,7 +48,9 @@ func (s *MemoryStore) Get(key []byte) ([]byte, error) {
// Put implements the Store interface. // Put implements the Store interface.
func (s *MemoryStore) Put(key, value []byte) error { func (s *MemoryStore) Put(key, value []byte) error {
s.Lock()
s.mem[makeKey(key)] = value s.mem[makeKey(key)] = value
s.Unlock()
return nil return nil
} }