[#446] innerring: Use less mutex locks in indexer

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
Alex Vanin 2021-03-26 11:36:07 +03:00 committed by Alex Vanin
parent e05f1e1394
commit 1d1fc04ac9

View file

@ -10,19 +10,25 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
type innerRingIndexer struct { type (
innerRingIndexer struct {
sync.RWMutex sync.RWMutex
cli *client.Client cli *client.Client
key *ecdsa.PublicKey key *ecdsa.PublicKey
timeout time.Duration timeout time.Duration
innerRingIndex, innerRingSize int32 ind indexes
alphabetIndex int32
lastAccess time.Time lastAccess time.Time
} }
indexes struct {
innerRingIndex, innerRingSize int32
alphabetIndex int32
}
)
func newInnerRingIndexer(cli *client.Client, key *ecdsa.PublicKey, to time.Duration) *innerRingIndexer { func newInnerRingIndexer(cli *client.Client, key *ecdsa.PublicKey, to time.Duration) *innerRingIndexer {
return &innerRingIndexer{ return &innerRingIndexer{
cli: cli, cli: cli,
@ -31,12 +37,12 @@ func newInnerRingIndexer(cli *client.Client, key *ecdsa.PublicKey, to time.Durat
} }
} }
func (s *innerRingIndexer) update() (err error) { func (s *innerRingIndexer) update() (ind indexes, err error) {
s.RLock() s.RLock()
if time.Since(s.lastAccess) < s.timeout { if time.Since(s.lastAccess) < s.timeout {
s.RUnlock() s.RUnlock()
return nil return s.ind, nil
} }
s.RUnlock() s.RUnlock()
@ -45,53 +51,47 @@ func (s *innerRingIndexer) update() (err error) {
defer s.Unlock() defer s.Unlock()
if time.Since(s.lastAccess) < s.timeout { if time.Since(s.lastAccess) < s.timeout {
return nil return s.ind, nil
} }
s.innerRingIndex, s.innerRingSize, err = invoke.InnerRingIndex(s.cli, s.key) s.ind.innerRingIndex, s.ind.innerRingSize, err = invoke.InnerRingIndex(s.cli, s.key)
if err != nil { if err != nil {
return err return indexes{}, err
} }
s.alphabetIndex, err = invoke.AlphabetIndex(s.cli, s.key) s.ind.alphabetIndex, err = invoke.AlphabetIndex(s.cli, s.key)
if err != nil { if err != nil {
return err return indexes{}, err
} }
s.lastAccess = time.Now() s.lastAccess = time.Now()
return nil return s.ind, nil
} }
func (s *innerRingIndexer) InnerRingIndex() (int32, error) { func (s *innerRingIndexer) InnerRingIndex() (int32, error) {
if err := s.update(); err != nil { ind, err := s.update()
if err != nil {
return 0, errors.Wrap(err, "can't update index state") return 0, errors.Wrap(err, "can't update index state")
} }
s.RLock() return ind.innerRingIndex, nil
defer s.RUnlock()
return s.innerRingIndex, nil
} }
func (s *innerRingIndexer) InnerRingSize() (int32, error) { func (s *innerRingIndexer) InnerRingSize() (int32, error) {
if err := s.update(); err != nil { ind, err := s.update()
if err != nil {
return 0, errors.Wrap(err, "can't update index state") return 0, errors.Wrap(err, "can't update index state")
} }
s.RLock() return ind.innerRingSize, nil
defer s.RUnlock()
return s.innerRingSize, nil
} }
func (s *innerRingIndexer) AlphabetIndex() (int32, error) { func (s *innerRingIndexer) AlphabetIndex() (int32, error) {
if err := s.update(); err != nil { ind, err := s.update()
if err != nil {
return 0, errors.Wrap(err, "can't update index state") return 0, errors.Wrap(err, "can't update index state")
} }
s.RLock() return ind.alphabetIndex, nil
defer s.RUnlock()
return s.alphabetIndex, nil
} }