From 4de3cc0f6e468e4a0323780203322f04c5527a79 Mon Sep 17 00:00:00 2001 From: Richard Artoul Date: Thu, 26 Sep 2019 16:28:32 -0400 Subject: [PATCH] Avoid decoding more data than necessary in fetch --- src/dbnode/client/session.go | 13 +++++++++++-- src/dbnode/topology/consistency_level.go | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/dbnode/client/session.go b/src/dbnode/client/session.go index 774fd54e04..07ed9aa535 100644 --- a/src/dbnode/client/session.go +++ b/src/dbnode/client/session.go @@ -1420,6 +1420,7 @@ func (s *session) fetchIDsAttempt( resultErr error resultErrs int32 majority int32 + numReplicas int32 consistencyLevel topology.ReadConsistencyLevel fetchBatchOpsByHostIdx [][]*fetchBatchOp success = false @@ -1471,6 +1472,7 @@ func (s *session) fetchIDsAttempt( consistencyLevel = s.state.readLevel majority = int32(s.state.majority) + numReplicas = int32(s.state.majority) // NB(prateek): namespaceAccessors tracks the number of pending accessors for nsID. // It is set to incremented by `replica` for each requested ID during fetch enqueuing, @@ -1526,8 +1528,15 @@ func (s *session) fetchIDsAttempt( resultErrs++ resultErrLock.Unlock() } else { + numItersToInclude := int(success) + numDesired := topology.NumDesiredForReadConsistency(consistencyLevel, int(numReplicas), int(majority)) + if numDesired < numItersToInclude { + // Avoid decoding more data than is required to satisfy the consistency guarantees. + numItersToInclude = numDesired + } + resultsLock.RLock() - successIters := results[:success] + itersToInclude := results[:numItersToInclude] resultsLock.RUnlock() iter := s.pools.seriesIterator.Get() // NB(prateek): we need to allocate a copy of ident.ID to allow the seriesIterator @@ -1541,7 +1550,7 @@ func (s *session) fetchIDsAttempt( Namespace: namespaceID, StartInclusive: startInclusive, EndExclusive: endExclusive, - Replicas: successIters, + Replicas: itersToInclude, }) iters.SetAt(idx, iter) } diff --git a/src/dbnode/topology/consistency_level.go b/src/dbnode/topology/consistency_level.go index 4c6713a326..c97eef6b50 100644 --- a/src/dbnode/topology/consistency_level.go +++ b/src/dbnode/topology/consistency_level.go @@ -373,3 +373,19 @@ func ReadConsistencyAchieved( } panic(fmt.Errorf("unrecognized consistency level: %s", level.String())) } + +// NumDesiredForReadConsistency returns the number of replicas that would ideally be used to +// satisfy the read consistency. +func NumDesiredForReadConsistency(level ReadConsistencyLevel, numReplicas, majority int) int { + switch level { + case ReadConsistencyLevelAll: + return numReplicas + case ReadConsistencyLevelMajority, ReadConsistencyLevelUnstrictMajority: + return majority + case ReadConsistencyLevelOne: + return 1 + case ReadConsistencyLevelNone: + return 0 + } + panic(fmt.Errorf("unrecognized consistency level: %s", level.String())) +}