github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/kv/kvserver/batcheval/eval_context.go (about)

     1  // Copyright 2017 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package batcheval
    12  
    13  import (
    14  	"context"
    15  	"fmt"
    16  
    17  	"github.com/cockroachdb/cockroach/pkg/kv"
    18  	"github.com/cockroachdb/cockroach/pkg/kv/kvserver/abortspan"
    19  	"github.com/cockroachdb/cockroach/pkg/kv/kvserver/concurrency"
    20  	"github.com/cockroachdb/cockroach/pkg/kv/kvserver/kvserverbase"
    21  	"github.com/cockroachdb/cockroach/pkg/roachpb"
    22  	"github.com/cockroachdb/cockroach/pkg/settings/cluster"
    23  	"github.com/cockroachdb/cockroach/pkg/storage"
    24  	"github.com/cockroachdb/cockroach/pkg/storage/cloud"
    25  	"github.com/cockroachdb/cockroach/pkg/storage/enginepb"
    26  	"github.com/cockroachdb/cockroach/pkg/util/hlc"
    27  	"github.com/cockroachdb/cockroach/pkg/util/limit"
    28  	"github.com/cockroachdb/cockroach/pkg/util/uuid"
    29  	"golang.org/x/time/rate"
    30  )
    31  
    32  // Limiters is the collection of per-store limits used during cmd evaluation.
    33  type Limiters struct {
    34  	BulkIOWriteRate              *rate.Limiter
    35  	ConcurrentImportRequests     limit.ConcurrentRequestLimiter
    36  	ConcurrentExportRequests     limit.ConcurrentRequestLimiter
    37  	ConcurrentAddSSTableRequests limit.ConcurrentRequestLimiter
    38  	// concurrentRangefeedIters is a semaphore used to limit the number of
    39  	// rangefeeds in the "catch-up" state across the store. The "catch-up" state
    40  	// is a temporary state at the beginning of a rangefeed which is expensive
    41  	// because it uses an engine iterator.
    42  	ConcurrentRangefeedIters limit.ConcurrentRequestLimiter
    43  }
    44  
    45  // EvalContext is the interface through which command evaluation accesses the
    46  // underlying state.
    47  type EvalContext interface {
    48  	fmt.Stringer
    49  	ClusterSettings() *cluster.Settings
    50  	EvalKnobs() kvserverbase.BatchEvalTestingKnobs
    51  
    52  	Engine() storage.Engine
    53  	Clock() *hlc.Clock
    54  	DB() *kv.DB
    55  	AbortSpan() *abortspan.AbortSpan
    56  	GetConcurrencyManager() concurrency.Manager
    57  	GetLimiters() *Limiters
    58  
    59  	NodeID() roachpb.NodeID
    60  	StoreID() roachpb.StoreID
    61  	GetRangeID() roachpb.RangeID
    62  	GetNodeLocality() roachpb.Locality
    63  
    64  	IsFirstRange() bool
    65  	GetFirstIndex() (uint64, error)
    66  	GetTerm(uint64) (uint64, error)
    67  	GetLeaseAppliedIndex() uint64
    68  
    69  	Desc() *roachpb.RangeDescriptor
    70  	ContainsKey(key roachpb.Key) bool
    71  
    72  	// CanCreateTxnRecord determines whether a transaction record can be created
    73  	// for the provided transaction information. See Replica.CanCreateTxnRecord
    74  	// for details about its arguments, return values, and preconditions.
    75  	CanCreateTxnRecord(
    76  		txnID uuid.UUID, txnKey []byte, txnMinTS hlc.Timestamp,
    77  	) (ok bool, minCommitTS hlc.Timestamp, reason roachpb.TransactionAbortedReason)
    78  
    79  	// GetMVCCStats returns a snapshot of the MVCC stats for the range.
    80  	// If called from a command that declares a read/write span on the
    81  	// entire range, the stats will be consistent with the data that is
    82  	// visible to the batch. Otherwise, it may return inconsistent
    83  	// results due to concurrent writes.
    84  	GetMVCCStats() enginepb.MVCCStats
    85  
    86  	// GetSplitQPS returns the queries/s request rate for this range.
    87  	//
    88  	// NOTE: This should not be used when the load based splitting cluster
    89  	// setting is disabled.
    90  	GetSplitQPS() float64
    91  
    92  	GetGCThreshold() hlc.Timestamp
    93  	GetLastReplicaGCTimestamp(context.Context) (hlc.Timestamp, error)
    94  	GetLease() (roachpb.Lease, roachpb.Lease)
    95  
    96  	GetExternalStorage(ctx context.Context, dest roachpb.ExternalStorage) (cloud.ExternalStorage, error)
    97  	GetExternalStorageFromURI(ctx context.Context, uri string) (cloud.ExternalStorage, error)
    98  }
    99  
   100  // MockEvalCtx is a dummy implementation of EvalContext for testing purposes.
   101  // For technical reasons, the interface is implemented by a wrapper .EvalContext().
   102  type MockEvalCtx struct {
   103  	ClusterSettings  *cluster.Settings
   104  	Desc             *roachpb.RangeDescriptor
   105  	StoreID          roachpb.StoreID
   106  	Clock            *hlc.Clock
   107  	Stats            enginepb.MVCCStats
   108  	QPS              float64
   109  	AbortSpan        *abortspan.AbortSpan
   110  	GCThreshold      hlc.Timestamp
   111  	Term, FirstIndex uint64
   112  	CanCreateTxn     func() (bool, hlc.Timestamp, roachpb.TransactionAbortedReason)
   113  	Lease            roachpb.Lease
   114  }
   115  
   116  // EvalContext returns the MockEvalCtx as an EvalContext. It will reflect future
   117  // modifications to the underlying MockEvalContext.
   118  func (m *MockEvalCtx) EvalContext() EvalContext {
   119  	return &mockEvalCtxImpl{m}
   120  }
   121  
   122  type mockEvalCtxImpl struct {
   123  	// Hide the fields of MockEvalCtx which have names that conflict with some
   124  	// of the interface methods.
   125  	*MockEvalCtx
   126  }
   127  
   128  func (m *mockEvalCtxImpl) String() string {
   129  	return "mock"
   130  }
   131  func (m *mockEvalCtxImpl) ClusterSettings() *cluster.Settings {
   132  	return m.MockEvalCtx.ClusterSettings
   133  }
   134  func (m *mockEvalCtxImpl) EvalKnobs() kvserverbase.BatchEvalTestingKnobs {
   135  	return kvserverbase.BatchEvalTestingKnobs{}
   136  }
   137  func (m *mockEvalCtxImpl) Engine() storage.Engine {
   138  	panic("unimplemented")
   139  }
   140  func (m *mockEvalCtxImpl) Clock() *hlc.Clock {
   141  	return m.MockEvalCtx.Clock
   142  }
   143  func (m *mockEvalCtxImpl) DB() *kv.DB {
   144  	panic("unimplemented")
   145  }
   146  func (m *mockEvalCtxImpl) GetLimiters() *Limiters {
   147  	panic("unimplemented")
   148  }
   149  func (m *mockEvalCtxImpl) AbortSpan() *abortspan.AbortSpan {
   150  	return m.MockEvalCtx.AbortSpan
   151  }
   152  func (m *mockEvalCtxImpl) GetConcurrencyManager() concurrency.Manager {
   153  	panic("unimplemented")
   154  }
   155  func (m *mockEvalCtxImpl) NodeID() roachpb.NodeID {
   156  	panic("unimplemented")
   157  }
   158  func (m *mockEvalCtxImpl) GetNodeLocality() roachpb.Locality {
   159  	panic("unimplemented")
   160  }
   161  func (m *mockEvalCtxImpl) StoreID() roachpb.StoreID {
   162  	return m.MockEvalCtx.StoreID
   163  }
   164  func (m *mockEvalCtxImpl) GetRangeID() roachpb.RangeID {
   165  	return m.MockEvalCtx.Desc.RangeID
   166  }
   167  func (m *mockEvalCtxImpl) IsFirstRange() bool {
   168  	panic("unimplemented")
   169  }
   170  func (m *mockEvalCtxImpl) GetFirstIndex() (uint64, error) {
   171  	return m.FirstIndex, nil
   172  }
   173  func (m *mockEvalCtxImpl) GetTerm(uint64) (uint64, error) {
   174  	return m.Term, nil
   175  }
   176  func (m *mockEvalCtxImpl) GetLeaseAppliedIndex() uint64 {
   177  	panic("unimplemented")
   178  }
   179  func (m *mockEvalCtxImpl) Desc() *roachpb.RangeDescriptor {
   180  	return m.MockEvalCtx.Desc
   181  }
   182  func (m *mockEvalCtxImpl) ContainsKey(key roachpb.Key) bool {
   183  	return false
   184  }
   185  func (m *mockEvalCtxImpl) GetMVCCStats() enginepb.MVCCStats {
   186  	return m.Stats
   187  }
   188  func (m *mockEvalCtxImpl) GetSplitQPS() float64 {
   189  	return m.QPS
   190  }
   191  func (m *mockEvalCtxImpl) CanCreateTxnRecord(
   192  	uuid.UUID, []byte, hlc.Timestamp,
   193  ) (bool, hlc.Timestamp, roachpb.TransactionAbortedReason) {
   194  	return m.CanCreateTxn()
   195  }
   196  func (m *mockEvalCtxImpl) GetGCThreshold() hlc.Timestamp {
   197  	return m.GCThreshold
   198  }
   199  func (m *mockEvalCtxImpl) GetLastReplicaGCTimestamp(context.Context) (hlc.Timestamp, error) {
   200  	panic("unimplemented")
   201  }
   202  func (m *mockEvalCtxImpl) GetLease() (roachpb.Lease, roachpb.Lease) {
   203  	return m.Lease, roachpb.Lease{}
   204  }
   205  
   206  func (m *mockEvalCtxImpl) GetExternalStorage(
   207  	ctx context.Context, dest roachpb.ExternalStorage,
   208  ) (cloud.ExternalStorage, error) {
   209  	panic("unimplemented")
   210  }
   211  
   212  func (m *mockEvalCtxImpl) GetExternalStorageFromURI(
   213  	ctx context.Context, uri string,
   214  ) (cloud.ExternalStorage, error) {
   215  	panic("unimplemented")
   216  }