github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/roachpb/api.go (about) 1 // Copyright 2014 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 roachpb 12 13 import ( 14 "fmt" 15 16 "github.com/aws/aws-sdk-go/aws" 17 "github.com/aws/aws-sdk-go/aws/credentials" 18 "github.com/cockroachdb/cockroach/pkg/kv/kvserver/concurrency/lock" 19 "github.com/cockroachdb/cockroach/pkg/util/protoutil" 20 "github.com/cockroachdb/errors" 21 ) 22 23 // UserPriority is a custom type for transaction's user priority. 24 type UserPriority float64 25 26 func (up UserPriority) String() string { 27 switch up { 28 case MinUserPriority: 29 return "low" 30 case UnspecifiedUserPriority, NormalUserPriority: 31 return "normal" 32 case MaxUserPriority: 33 return "high" 34 default: 35 return fmt.Sprintf("%g", float64(up)) 36 } 37 } 38 39 const ( 40 // MinUserPriority is the minimum allowed user priority. 41 MinUserPriority UserPriority = 0.001 42 // UnspecifiedUserPriority means NormalUserPriority. 43 UnspecifiedUserPriority UserPriority = 0 44 // NormalUserPriority is set to 1, meaning ops run through the database 45 // are all given equal weight when a random priority is chosen. This can 46 // be set specifically via client.NewDBWithPriority(). 47 NormalUserPriority UserPriority = 1 48 // MaxUserPriority is the maximum allowed user priority. 49 MaxUserPriority UserPriority = 1000 50 ) 51 52 // RequiresReadLease returns whether the ReadConsistencyType requires 53 // that a read-only request be performed on an active valid leaseholder. 54 func (rc ReadConsistencyType) RequiresReadLease() bool { 55 switch rc { 56 case CONSISTENT: 57 return true 58 case READ_UNCOMMITTED: 59 return true 60 case INCONSISTENT: 61 return false 62 } 63 panic("unreachable") 64 } 65 66 // SupportsBatch determines whether the methods in the provided batch 67 // are supported by the ReadConsistencyType, returning an error if not. 68 func (rc ReadConsistencyType) SupportsBatch(ba BatchRequest) error { 69 switch rc { 70 case CONSISTENT: 71 return nil 72 case READ_UNCOMMITTED, INCONSISTENT: 73 for _, ru := range ba.Requests { 74 m := ru.GetInner().Method() 75 switch m { 76 case Get, Scan, ReverseScan: 77 default: 78 return errors.Errorf("method %s not allowed with %s batch", m, rc) 79 } 80 } 81 return nil 82 } 83 panic("unreachable") 84 } 85 86 const ( 87 isAdmin = 1 << iota // admin cmds don't go through raft, but run on lease holder 88 isRead // read-only cmds don't go through raft, but may run on lease holder 89 isWrite // write cmds go through raft and must be proposed on lease holder 90 isTxn // txn commands may be part of a transaction 91 isLocking // locking cmds acquire locks for their transaction (implies isTxn) 92 isIntentWrite // intent write cmds leave intents when they succeed (implies isWrite and isLocking) 93 isRange // range commands may span multiple keys 94 isReverse // reverse commands traverse ranges in descending direction 95 isAlone // requests which must be alone in a batch 96 isPrefix // requests which should be grouped with the next request in a batch 97 isUnsplittable // range command that must not be split during sending 98 skipLeaseCheck // commands which skip the check that the evaluting replica has a valid lease 99 consultsTSCache // mutating commands which write data at a timestamp 100 updatesTSCache // commands which update the timestamp cache 101 updatesTSCacheOnErr // commands which make read data available on errors 102 needsRefresh // commands which require refreshes to avoid serializable retries 103 canBackpressure // commands which deserve backpressure when a Range grows too large 104 ) 105 106 // IsReadOnly returns true iff the request is read-only. A request is 107 // read-only if it does not go through raft, meaning that it cannot 108 // change any replicated state. However, read-only requests may still 109 // acquire locks with an unreplicated durability level; see IsLocking. 110 func IsReadOnly(args Request) bool { 111 flags := args.flags() 112 return (flags&isRead) != 0 && (flags&isWrite) == 0 113 } 114 115 // IsBlindWrite returns true iff the request is a blind-write. A request is a 116 // blind-write if it is a write that does not observe any key-value state when 117 // modifying that state (such as puts and deletes). This is in contrast with 118 // read-write requests, which do observe key-value state when modifying the 119 // state and may base their modifications off of this existing state (such as 120 // conditional puts and increments). 121 // 122 // As a result of being "blind", blind-writes are allowed to be more freely 123 // re-ordered with other writes. In practice, this means that they can be 124 // evaluated with a read timestamp below another write and a write timestamp 125 // above that write without needing to re-evaluate. This allows the WriteTooOld 126 // error that is generated during such an occurrence to be deferred. 127 func IsBlindWrite(args Request) bool { 128 flags := args.flags() 129 return (flags&isRead) == 0 && (flags&isWrite) != 0 130 } 131 132 // IsTransactional returns true if the request may be part of a 133 // transaction. 134 func IsTransactional(args Request) bool { 135 return (args.flags() & isTxn) != 0 136 } 137 138 // IsLocking returns true if the request acquires locks when used within 139 // a transaction. 140 func IsLocking(args Request) bool { 141 return (args.flags() & isLocking) != 0 142 } 143 144 // LockingDurability returns the durability of the locks acquired by the 145 // request. The function assumes that IsLocking(args). 146 func LockingDurability(args Request) lock.Durability { 147 if IsReadOnly(args) { 148 return lock.Unreplicated 149 } 150 return lock.Replicated 151 } 152 153 // IsIntentWrite returns true if the request produces write intents at 154 // the request's sequence number when used within a transaction. 155 func IsIntentWrite(args Request) bool { 156 return (args.flags() & isIntentWrite) != 0 157 } 158 159 // IsRange returns true if the command is range-based and must include 160 // a start and an end key. 161 func IsRange(args Request) bool { 162 return (args.flags() & isRange) != 0 163 } 164 165 // ConsultsTimestampCache returns whether the command must consult 166 // the timestamp cache to determine whether a mutation is safe at 167 // a proposed timestamp or needs to move to a higher timestamp to 168 // avoid re-writing history. 169 func ConsultsTimestampCache(args Request) bool { 170 return (args.flags() & consultsTSCache) != 0 171 } 172 173 // UpdatesTimestampCache returns whether the command must update 174 // the timestamp cache in order to set a low water mark for the 175 // timestamp at which mutations to overlapping key(s) can write 176 // such that they don't re-write history. 177 func UpdatesTimestampCache(args Request) bool { 178 return (args.flags() & updatesTSCache) != 0 179 } 180 181 // UpdatesTimestampCacheOnError returns whether the command must 182 // update the timestamp cache even on error, as in some cases the data 183 // which was read is returned (e.g. ConditionalPut ConditionFailedError). 184 func UpdatesTimestampCacheOnError(args Request) bool { 185 return (args.flags() & updatesTSCacheOnErr) != 0 186 } 187 188 // NeedsRefresh returns whether the command must be refreshed in 189 // order to avoid client-side retries on serializable transactions. 190 func NeedsRefresh(args Request) bool { 191 return (args.flags() & needsRefresh) != 0 192 } 193 194 // CanBackpressure returns whether the command can be backpressured 195 // when waiting for a Range to split after it has grown too large. 196 func CanBackpressure(args Request) bool { 197 return (args.flags() & canBackpressure) != 0 198 } 199 200 // Request is an interface for RPC requests. 201 type Request interface { 202 protoutil.Message 203 // Header returns the request header. 204 Header() RequestHeader 205 // SetHeader sets the request header. 206 SetHeader(RequestHeader) 207 // Method returns the request method. 208 Method() Method 209 // ShallowCopy returns a shallow copy of the receiver. 210 ShallowCopy() Request 211 flags() int 212 } 213 214 // leaseRequestor is implemented by requests dealing with leases. 215 // Implementors return the previous lease at the time the request 216 // was proposed. 217 type leaseRequestor interface { 218 prevLease() Lease 219 } 220 221 var _ leaseRequestor = &RequestLeaseRequest{} 222 223 func (rlr *RequestLeaseRequest) prevLease() Lease { 224 return rlr.PrevLease 225 } 226 227 var _ leaseRequestor = &TransferLeaseRequest{} 228 229 func (tlr *TransferLeaseRequest) prevLease() Lease { 230 return tlr.PrevLease 231 } 232 233 // Response is an interface for RPC responses. 234 type Response interface { 235 protoutil.Message 236 // Header returns the response header. 237 Header() ResponseHeader 238 // SetHeader sets the response header. 239 SetHeader(ResponseHeader) 240 // Verify verifies response integrity, as applicable. 241 Verify(req Request) error 242 } 243 244 // combinable is implemented by response types whose corresponding 245 // requests may cross range boundaries, such as Scan or DeleteRange. 246 // combine() allows responses from individual ranges to be aggregated 247 // into a single one. 248 type combinable interface { 249 combine(combinable) error 250 } 251 252 // CombineResponses attempts to combine the two provided responses. If both of 253 // the responses are combinable, they will be combined. If neither are 254 // combinable, the function is a no-op and returns a nil error. If one of the 255 // responses is combinable and the other isn't, the function returns an error. 256 func CombineResponses(left, right Response) error { 257 cLeft, lOK := left.(combinable) 258 cRight, rOK := right.(combinable) 259 if lOK && rOK { 260 return cLeft.combine(cRight) 261 } else if lOK != rOK { 262 return errors.Errorf("can not combine %T and %T", left, right) 263 } 264 return nil 265 } 266 267 // combine is used by range-spanning Response types (e.g. Scan or DeleteRange) 268 // to merge their headers. 269 func (rh *ResponseHeader) combine(otherRH ResponseHeader) error { 270 if rh.Txn != nil && otherRH.Txn == nil { 271 rh.Txn = nil 272 } 273 if rh.ResumeSpan != nil { 274 return errors.Errorf("combining %+v with %+v", rh.ResumeSpan, otherRH.ResumeSpan) 275 } 276 rh.ResumeSpan = otherRH.ResumeSpan 277 rh.ResumeReason = otherRH.ResumeReason 278 rh.NumKeys += otherRH.NumKeys 279 rh.NumBytes += otherRH.NumBytes 280 rh.RangeInfos = append(rh.RangeInfos, otherRH.RangeInfos...) 281 return nil 282 } 283 284 // combine implements the combinable interface. 285 func (sr *ScanResponse) combine(c combinable) error { 286 otherSR := c.(*ScanResponse) 287 if sr != nil { 288 sr.Rows = append(sr.Rows, otherSR.Rows...) 289 sr.IntentRows = append(sr.IntentRows, otherSR.IntentRows...) 290 sr.BatchResponses = append(sr.BatchResponses, otherSR.BatchResponses...) 291 if err := sr.ResponseHeader.combine(otherSR.Header()); err != nil { 292 return err 293 } 294 } 295 return nil 296 } 297 298 var _ combinable = &AdminVerifyProtectedTimestampResponse{} 299 300 func (avptr *AdminVerifyProtectedTimestampResponse) combine(c combinable) error { 301 other := c.(*AdminVerifyProtectedTimestampResponse) 302 if avptr != nil { 303 avptr.FailedRanges = append(avptr.FailedRanges, other.FailedRanges...) 304 if err := avptr.ResponseHeader.combine(other.Header()); err != nil { 305 return err 306 } 307 } 308 return nil 309 } 310 311 var _ combinable = &ScanResponse{} 312 313 // combine implements the combinable interface. 314 func (sr *ReverseScanResponse) combine(c combinable) error { 315 otherSR := c.(*ReverseScanResponse) 316 if sr != nil { 317 sr.Rows = append(sr.Rows, otherSR.Rows...) 318 sr.IntentRows = append(sr.IntentRows, otherSR.IntentRows...) 319 sr.BatchResponses = append(sr.BatchResponses, otherSR.BatchResponses...) 320 if err := sr.ResponseHeader.combine(otherSR.Header()); err != nil { 321 return err 322 } 323 } 324 return nil 325 } 326 327 var _ combinable = &ReverseScanResponse{} 328 329 // combine implements the combinable interface. 330 func (dr *DeleteRangeResponse) combine(c combinable) error { 331 otherDR := c.(*DeleteRangeResponse) 332 if dr != nil { 333 dr.Keys = append(dr.Keys, otherDR.Keys...) 334 if err := dr.ResponseHeader.combine(otherDR.Header()); err != nil { 335 return err 336 } 337 } 338 return nil 339 } 340 341 var _ combinable = &DeleteRangeResponse{} 342 343 // combine implements the combinable interface. 344 func (dr *RevertRangeResponse) combine(c combinable) error { 345 otherDR := c.(*RevertRangeResponse) 346 if dr != nil { 347 if err := dr.ResponseHeader.combine(otherDR.Header()); err != nil { 348 return err 349 } 350 } 351 return nil 352 } 353 354 var _ combinable = &RevertRangeResponse{} 355 356 // combine implements the combinable interface. 357 func (rr *ResolveIntentRangeResponse) combine(c combinable) error { 358 otherRR := c.(*ResolveIntentRangeResponse) 359 if rr != nil { 360 if err := rr.ResponseHeader.combine(otherRR.Header()); err != nil { 361 return err 362 } 363 } 364 return nil 365 } 366 367 var _ combinable = &ResolveIntentRangeResponse{} 368 369 // Combine implements the combinable interface. 370 func (cc *CheckConsistencyResponse) combine(c combinable) error { 371 if cc != nil { 372 otherCC := c.(*CheckConsistencyResponse) 373 cc.Result = append(cc.Result, otherCC.Result...) 374 if err := cc.ResponseHeader.combine(otherCC.Header()); err != nil { 375 return err 376 } 377 } 378 return nil 379 } 380 381 var _ combinable = &CheckConsistencyResponse{} 382 383 // Combine implements the combinable interface. 384 func (er *ExportResponse) combine(c combinable) error { 385 if er != nil { 386 otherER := c.(*ExportResponse) 387 if err := er.ResponseHeader.combine(otherER.Header()); err != nil { 388 return err 389 } 390 er.Files = append(er.Files, otherER.Files...) 391 } 392 return nil 393 } 394 395 var _ combinable = &ExportResponse{} 396 397 // Combine implements the combinable interface. 398 func (r *AdminScatterResponse) combine(c combinable) error { 399 if r != nil { 400 otherR := c.(*AdminScatterResponse) 401 if err := r.ResponseHeader.combine(otherR.Header()); err != nil { 402 return err 403 } 404 r.Ranges = append(r.Ranges, otherR.Ranges...) 405 } 406 return nil 407 } 408 409 var _ combinable = &AdminScatterResponse{} 410 411 // Header implements the Request interface. 412 func (rh RequestHeader) Header() RequestHeader { 413 return rh 414 } 415 416 // SetHeader implements the Request interface. 417 func (rh *RequestHeader) SetHeader(other RequestHeader) { 418 *rh = other 419 } 420 421 // Span returns the key range that the Request operates over. 422 func (rh RequestHeader) Span() Span { 423 return Span{Key: rh.Key, EndKey: rh.EndKey} 424 } 425 426 // SetSpan addresses the RequestHeader to the specified key span. 427 func (rh *RequestHeader) SetSpan(s Span) { 428 rh.Key = s.Key 429 rh.EndKey = s.EndKey 430 } 431 432 // RequestHeaderFromSpan creates a RequestHeader addressed at the specified key 433 // span. 434 func RequestHeaderFromSpan(s Span) RequestHeader { 435 return RequestHeader{Key: s.Key, EndKey: s.EndKey} 436 } 437 438 func (h *BatchResponse_Header) combine(o BatchResponse_Header) error { 439 if h.Error != nil || o.Error != nil { 440 return errors.Errorf( 441 "can't combine batch responses with errors, have errors %q and %q", 442 h.Error, o.Error, 443 ) 444 } 445 h.Timestamp.Forward(o.Timestamp) 446 if txn := o.Txn; txn != nil { 447 if h.Txn == nil { 448 h.Txn = txn.Clone() 449 } else { 450 h.Txn.Update(txn) 451 } 452 } 453 h.Now.Forward(o.Now) 454 h.CollectedSpans = append(h.CollectedSpans, o.CollectedSpans...) 455 return nil 456 } 457 458 // SetHeader implements the Response interface. 459 func (rh *ResponseHeader) SetHeader(other ResponseHeader) { 460 *rh = other 461 } 462 463 // Header implements the Response interface for ResponseHeader. 464 func (rh ResponseHeader) Header() ResponseHeader { 465 return rh 466 } 467 468 // Verify implements the Response interface for ResopnseHeader with a 469 // default noop. Individual response types should override this method 470 // if they contain checksummed data which can be verified. 471 func (rh *ResponseHeader) Verify(req Request) error { 472 return nil 473 } 474 475 // Verify verifies the integrity of the get response value. 476 func (gr *GetResponse) Verify(req Request) error { 477 if gr.Value != nil { 478 return gr.Value.Verify(req.Header().Key) 479 } 480 return nil 481 } 482 483 // Verify verifies the integrity of every value returned in the scan. 484 func (sr *ScanResponse) Verify(req Request) error { 485 for _, kv := range sr.Rows { 486 if err := kv.Value.Verify(kv.Key); err != nil { 487 return err 488 } 489 } 490 return nil 491 } 492 493 // Verify verifies the integrity of every value returned in the reverse scan. 494 func (sr *ReverseScanResponse) Verify(req Request) error { 495 for _, kv := range sr.Rows { 496 if err := kv.Value.Verify(kv.Key); err != nil { 497 return err 498 } 499 } 500 return nil 501 } 502 503 // MustSetInner sets the Request contained in the union. It panics if the 504 // request is not recognized by the union type. The RequestUnion is reset 505 // before being repopulated. 506 func (ru *RequestUnion) MustSetInner(args Request) { 507 ru.Reset() 508 if !ru.SetInner(args) { 509 panic(fmt.Sprintf("%T excludes %T", ru, args)) 510 } 511 } 512 513 // MustSetInner sets the Response contained in the union. It panics if the 514 // response is not recognized by the union type. The ResponseUnion is reset 515 // before being repopulated. 516 func (ru *ResponseUnion) MustSetInner(reply Response) { 517 ru.Reset() 518 if !ru.SetInner(reply) { 519 panic(fmt.Sprintf("%T excludes %T", ru, reply)) 520 } 521 } 522 523 // Method implements the Request interface. 524 func (*GetRequest) Method() Method { return Get } 525 526 // Method implements the Request interface. 527 func (*PutRequest) Method() Method { return Put } 528 529 // Method implements the Request interface. 530 func (*ConditionalPutRequest) Method() Method { return ConditionalPut } 531 532 // Method implements the Request interface. 533 func (*InitPutRequest) Method() Method { return InitPut } 534 535 // Method implements the Request interface. 536 func (*IncrementRequest) Method() Method { return Increment } 537 538 // Method implements the Request interface. 539 func (*DeleteRequest) Method() Method { return Delete } 540 541 // Method implements the Request interface. 542 func (*DeleteRangeRequest) Method() Method { return DeleteRange } 543 544 // Method implements the Request interface. 545 func (*ClearRangeRequest) Method() Method { return ClearRange } 546 547 // Method implements the Request interface. 548 func (*RevertRangeRequest) Method() Method { return RevertRange } 549 550 // Method implements the Request interface. 551 func (*ScanRequest) Method() Method { return Scan } 552 553 // Method implements the Request interface. 554 func (*ReverseScanRequest) Method() Method { return ReverseScan } 555 556 // Method implements the Request interface. 557 func (*CheckConsistencyRequest) Method() Method { return CheckConsistency } 558 559 // Method implements the Request interface. 560 func (*EndTxnRequest) Method() Method { return EndTxn } 561 562 // Method implements the Request interface. 563 func (*AdminSplitRequest) Method() Method { return AdminSplit } 564 565 // Method implements the Request interface. 566 func (*AdminUnsplitRequest) Method() Method { return AdminUnsplit } 567 568 // Method implements the Request interface. 569 func (*AdminMergeRequest) Method() Method { return AdminMerge } 570 571 // Method implements the Request interface. 572 func (*AdminTransferLeaseRequest) Method() Method { return AdminTransferLease } 573 574 // Method implements the Request interface. 575 func (*AdminChangeReplicasRequest) Method() Method { return AdminChangeReplicas } 576 577 // Method implements the Request interface. 578 func (*AdminRelocateRangeRequest) Method() Method { return AdminRelocateRange } 579 580 // Method implements the Request interface. 581 func (*HeartbeatTxnRequest) Method() Method { return HeartbeatTxn } 582 583 // Method implements the Request interface. 584 func (*GCRequest) Method() Method { return GC } 585 586 // Method implements the Request interface. 587 func (*PushTxnRequest) Method() Method { return PushTxn } 588 589 // Method implements the Request interface. 590 func (*RecoverTxnRequest) Method() Method { return RecoverTxn } 591 592 // Method implements the Request interface. 593 func (*QueryTxnRequest) Method() Method { return QueryTxn } 594 595 // Method implements the Request interface. 596 func (*QueryIntentRequest) Method() Method { return QueryIntent } 597 598 // Method implements the Request interface. 599 func (*ResolveIntentRequest) Method() Method { return ResolveIntent } 600 601 // Method implements the Request interface. 602 func (*ResolveIntentRangeRequest) Method() Method { return ResolveIntentRange } 603 604 // Method implements the Request interface. 605 func (*MergeRequest) Method() Method { return Merge } 606 607 // Method implements the Request interface. 608 func (*TruncateLogRequest) Method() Method { return TruncateLog } 609 610 // Method implements the Request interface. 611 func (*RequestLeaseRequest) Method() Method { return RequestLease } 612 613 // Method implements the Request interface. 614 func (*TransferLeaseRequest) Method() Method { return TransferLease } 615 616 // Method implements the Request interface. 617 func (*LeaseInfoRequest) Method() Method { return LeaseInfo } 618 619 // Method implements the Request interface. 620 func (*ComputeChecksumRequest) Method() Method { return ComputeChecksum } 621 622 // Method implements the Request interface. 623 func (*WriteBatchRequest) Method() Method { return WriteBatch } 624 625 // Method implements the Request interface. 626 func (*ExportRequest) Method() Method { return Export } 627 628 // Method implements the Request interface. 629 func (*ImportRequest) Method() Method { return Import } 630 631 // Method implements the Request interface. 632 func (*AdminScatterRequest) Method() Method { return AdminScatter } 633 634 // Method implements the Request interface. 635 func (*AddSSTableRequest) Method() Method { return AddSSTable } 636 637 // Method implements the Request interface. 638 func (*RecomputeStatsRequest) Method() Method { return RecomputeStats } 639 640 // Method implements the Request interface. 641 func (*RefreshRequest) Method() Method { return Refresh } 642 643 // Method implements the Request interface. 644 func (*RefreshRangeRequest) Method() Method { return RefreshRange } 645 646 // Method implements the Request interface. 647 func (*SubsumeRequest) Method() Method { return Subsume } 648 649 // Method implements the Request interface. 650 func (*RangeStatsRequest) Method() Method { return RangeStats } 651 652 // Method implements the Request interface. 653 func (*AdminVerifyProtectedTimestampRequest) Method() Method { return AdminVerifyProtectedTimestamp } 654 655 // ShallowCopy implements the Request interface. 656 func (gr *GetRequest) ShallowCopy() Request { 657 shallowCopy := *gr 658 return &shallowCopy 659 } 660 661 // ShallowCopy implements the Request interface. 662 func (pr *PutRequest) ShallowCopy() Request { 663 shallowCopy := *pr 664 return &shallowCopy 665 } 666 667 // ShallowCopy implements the Request interface. 668 func (cpr *ConditionalPutRequest) ShallowCopy() Request { 669 shallowCopy := *cpr 670 return &shallowCopy 671 } 672 673 // ShallowCopy implements the Request interface. 674 func (pr *InitPutRequest) ShallowCopy() Request { 675 shallowCopy := *pr 676 return &shallowCopy 677 } 678 679 // ShallowCopy implements the Request interface. 680 func (ir *IncrementRequest) ShallowCopy() Request { 681 shallowCopy := *ir 682 return &shallowCopy 683 } 684 685 // ShallowCopy implements the Request interface. 686 func (dr *DeleteRequest) ShallowCopy() Request { 687 shallowCopy := *dr 688 return &shallowCopy 689 } 690 691 // ShallowCopy implements the Request interface. 692 func (drr *DeleteRangeRequest) ShallowCopy() Request { 693 shallowCopy := *drr 694 return &shallowCopy 695 } 696 697 // ShallowCopy implements the Request interface. 698 func (crr *ClearRangeRequest) ShallowCopy() Request { 699 shallowCopy := *crr 700 return &shallowCopy 701 } 702 703 // ShallowCopy implements the Request interface. 704 func (crr *RevertRangeRequest) ShallowCopy() Request { 705 shallowCopy := *crr 706 return &shallowCopy 707 } 708 709 // ShallowCopy implements the Request interface. 710 func (sr *ScanRequest) ShallowCopy() Request { 711 shallowCopy := *sr 712 return &shallowCopy 713 } 714 715 // ShallowCopy implements the Request interface. 716 func (rsr *ReverseScanRequest) ShallowCopy() Request { 717 shallowCopy := *rsr 718 return &shallowCopy 719 } 720 721 // ShallowCopy implements the Request interface. 722 func (ccr *CheckConsistencyRequest) ShallowCopy() Request { 723 shallowCopy := *ccr 724 return &shallowCopy 725 } 726 727 // ShallowCopy implements the Request interface. 728 func (etr *EndTxnRequest) ShallowCopy() Request { 729 shallowCopy := *etr 730 return &shallowCopy 731 } 732 733 // ShallowCopy implements the Request interface. 734 func (asr *AdminSplitRequest) ShallowCopy() Request { 735 shallowCopy := *asr 736 return &shallowCopy 737 } 738 739 // ShallowCopy implements the Request interface. 740 func (aur *AdminUnsplitRequest) ShallowCopy() Request { 741 shallowCopy := *aur 742 return &shallowCopy 743 } 744 745 // ShallowCopy implements the Request interface. 746 func (amr *AdminMergeRequest) ShallowCopy() Request { 747 shallowCopy := *amr 748 return &shallowCopy 749 } 750 751 // ShallowCopy implements the Request interface. 752 func (atlr *AdminTransferLeaseRequest) ShallowCopy() Request { 753 shallowCopy := *atlr 754 return &shallowCopy 755 } 756 757 // ShallowCopy implements the Request interface. 758 func (acrr *AdminChangeReplicasRequest) ShallowCopy() Request { 759 shallowCopy := *acrr 760 return &shallowCopy 761 } 762 763 // ShallowCopy implements the Request interface. 764 func (acrr *AdminRelocateRangeRequest) ShallowCopy() Request { 765 shallowCopy := *acrr 766 return &shallowCopy 767 } 768 769 // ShallowCopy implements the Request interface. 770 func (htr *HeartbeatTxnRequest) ShallowCopy() Request { 771 shallowCopy := *htr 772 return &shallowCopy 773 } 774 775 // ShallowCopy implements the Request interface. 776 func (gcr *GCRequest) ShallowCopy() Request { 777 shallowCopy := *gcr 778 return &shallowCopy 779 } 780 781 // ShallowCopy implements the Request interface. 782 func (ptr *PushTxnRequest) ShallowCopy() Request { 783 shallowCopy := *ptr 784 return &shallowCopy 785 } 786 787 // ShallowCopy implements the Request interface. 788 func (rtr *RecoverTxnRequest) ShallowCopy() Request { 789 shallowCopy := *rtr 790 return &shallowCopy 791 } 792 793 // ShallowCopy implements the Request interface. 794 func (qtr *QueryTxnRequest) ShallowCopy() Request { 795 shallowCopy := *qtr 796 return &shallowCopy 797 } 798 799 // ShallowCopy implements the Request interface. 800 func (pir *QueryIntentRequest) ShallowCopy() Request { 801 shallowCopy := *pir 802 return &shallowCopy 803 } 804 805 // ShallowCopy implements the Request interface. 806 func (rir *ResolveIntentRequest) ShallowCopy() Request { 807 shallowCopy := *rir 808 return &shallowCopy 809 } 810 811 // ShallowCopy implements the Request interface. 812 func (rirr *ResolveIntentRangeRequest) ShallowCopy() Request { 813 shallowCopy := *rirr 814 return &shallowCopy 815 } 816 817 // ShallowCopy implements the Request interface. 818 func (mr *MergeRequest) ShallowCopy() Request { 819 shallowCopy := *mr 820 return &shallowCopy 821 } 822 823 // ShallowCopy implements the Request interface. 824 func (tlr *TruncateLogRequest) ShallowCopy() Request { 825 shallowCopy := *tlr 826 return &shallowCopy 827 } 828 829 // ShallowCopy implements the Request interface. 830 func (rlr *RequestLeaseRequest) ShallowCopy() Request { 831 shallowCopy := *rlr 832 return &shallowCopy 833 } 834 835 // ShallowCopy implements the Request interface. 836 func (tlr *TransferLeaseRequest) ShallowCopy() Request { 837 shallowCopy := *tlr 838 return &shallowCopy 839 } 840 841 // ShallowCopy implements the Request interface. 842 func (lt *LeaseInfoRequest) ShallowCopy() Request { 843 shallowCopy := *lt 844 return &shallowCopy 845 } 846 847 // ShallowCopy implements the Request interface. 848 func (ccr *ComputeChecksumRequest) ShallowCopy() Request { 849 shallowCopy := *ccr 850 return &shallowCopy 851 } 852 853 // ShallowCopy implements the Request interface. 854 func (r *WriteBatchRequest) ShallowCopy() Request { 855 shallowCopy := *r 856 return &shallowCopy 857 } 858 859 // ShallowCopy implements the Request interface. 860 func (ekr *ExportRequest) ShallowCopy() Request { 861 shallowCopy := *ekr 862 return &shallowCopy 863 } 864 865 // ShallowCopy implements the Request interface. 866 func (r *ImportRequest) ShallowCopy() Request { 867 shallowCopy := *r 868 return &shallowCopy 869 } 870 871 // ShallowCopy implements the Request interface. 872 func (r *AdminScatterRequest) ShallowCopy() Request { 873 shallowCopy := *r 874 return &shallowCopy 875 } 876 877 // ShallowCopy implements the Request interface. 878 func (r *AddSSTableRequest) ShallowCopy() Request { 879 shallowCopy := *r 880 return &shallowCopy 881 } 882 883 // ShallowCopy implements the Request interface. 884 func (r *RecomputeStatsRequest) ShallowCopy() Request { 885 shallowCopy := *r 886 return &shallowCopy 887 } 888 889 // ShallowCopy implements the Request interface. 890 func (r *RefreshRequest) ShallowCopy() Request { 891 shallowCopy := *r 892 return &shallowCopy 893 } 894 895 // ShallowCopy implements the Request interface. 896 func (r *RefreshRangeRequest) ShallowCopy() Request { 897 shallowCopy := *r 898 return &shallowCopy 899 } 900 901 // ShallowCopy implements the Request interface. 902 func (r *SubsumeRequest) ShallowCopy() Request { 903 shallowCopy := *r 904 return &shallowCopy 905 } 906 907 // ShallowCopy implements the Request interface. 908 func (r *RangeStatsRequest) ShallowCopy() Request { 909 shallowCopy := *r 910 return &shallowCopy 911 } 912 913 // ShallowCopy implements the Request interface. 914 func (r *AdminVerifyProtectedTimestampRequest) ShallowCopy() Request { 915 shallowCopy := *r 916 return &shallowCopy 917 } 918 919 // NewGet returns a Request initialized to get the value at key. 920 func NewGet(key Key) Request { 921 return &GetRequest{ 922 RequestHeader: RequestHeader{ 923 Key: key, 924 }, 925 } 926 } 927 928 // NewIncrement returns a Request initialized to increment the value at 929 // key by increment. 930 func NewIncrement(key Key, increment int64) Request { 931 return &IncrementRequest{ 932 RequestHeader: RequestHeader{ 933 Key: key, 934 }, 935 Increment: increment, 936 } 937 } 938 939 // NewPut returns a Request initialized to put the value at key. 940 func NewPut(key Key, value Value) Request { 941 value.InitChecksum(key) 942 return &PutRequest{ 943 RequestHeader: RequestHeader{ 944 Key: key, 945 }, 946 Value: value, 947 } 948 } 949 950 // NewPutInline returns a Request initialized to put the value at key 951 // using an inline value. 952 func NewPutInline(key Key, value Value) Request { 953 value.InitChecksum(key) 954 return &PutRequest{ 955 RequestHeader: RequestHeader{ 956 Key: key, 957 }, 958 Value: value, 959 Inline: true, 960 } 961 } 962 963 // NewConditionalPut returns a Request initialized to put value as a byte 964 // slice at key if the existing value at key equals expValueBytes. 965 func NewConditionalPut(key Key, value, expValue Value, allowNotExist bool) Request { 966 value.InitChecksum(key) 967 var expValuePtr *Value 968 if expValue.RawBytes != nil { 969 // Make a copy to avoid forcing expValue itself on to the heap. 970 expValueTmp := expValue 971 expValuePtr = &expValueTmp 972 expValue.InitChecksum(key) 973 } 974 return &ConditionalPutRequest{ 975 RequestHeader: RequestHeader{ 976 Key: key, 977 }, 978 Value: value, 979 ExpValue: expValuePtr, 980 AllowIfDoesNotExist: allowNotExist, 981 } 982 } 983 984 // NewInitPut returns a Request initialized to put the value at key, as long as 985 // the key doesn't exist, returning a ConditionFailedError if the key exists and 986 // the existing value is different from value. If failOnTombstones is set to 987 // true, tombstones count as mismatched values and will cause a 988 // ConditionFailedError. 989 func NewInitPut(key Key, value Value, failOnTombstones bool) Request { 990 value.InitChecksum(key) 991 return &InitPutRequest{ 992 RequestHeader: RequestHeader{ 993 Key: key, 994 }, 995 Value: value, 996 FailOnTombstones: failOnTombstones, 997 } 998 } 999 1000 // NewDelete returns a Request initialized to delete the value at key. 1001 func NewDelete(key Key) Request { 1002 return &DeleteRequest{ 1003 RequestHeader: RequestHeader{ 1004 Key: key, 1005 }, 1006 } 1007 } 1008 1009 // NewDeleteRange returns a Request initialized to delete the values in 1010 // the given key range (excluding the endpoint). 1011 func NewDeleteRange(startKey, endKey Key, returnKeys bool) Request { 1012 return &DeleteRangeRequest{ 1013 RequestHeader: RequestHeader{ 1014 Key: startKey, 1015 EndKey: endKey, 1016 }, 1017 ReturnKeys: returnKeys, 1018 } 1019 } 1020 1021 // NewScan returns a Request initialized to scan from start to end keys. 1022 // If forUpdate is true, unreplicated, exclusive locks are acquired on 1023 // each of the resulting keys. 1024 func NewScan(key, endKey Key, forUpdate bool) Request { 1025 return &ScanRequest{ 1026 RequestHeader: RequestHeader{ 1027 Key: key, 1028 EndKey: endKey, 1029 }, 1030 KeyLocking: scanLockStrength(forUpdate), 1031 } 1032 } 1033 1034 // NewReverseScan returns a Request initialized to reverse scan from end. 1035 // If forUpdate is true, unreplicated, exclusive locks are acquired on 1036 // each of the resulting keys. 1037 func NewReverseScan(key, endKey Key, forUpdate bool) Request { 1038 return &ReverseScanRequest{ 1039 RequestHeader: RequestHeader{ 1040 Key: key, 1041 EndKey: endKey, 1042 }, 1043 KeyLocking: scanLockStrength(forUpdate), 1044 } 1045 } 1046 1047 func scanLockStrength(forUpdate bool) lock.Strength { 1048 if forUpdate { 1049 return lock.Exclusive 1050 } 1051 return lock.None 1052 } 1053 1054 func (*GetRequest) flags() int { 1055 return isRead | isTxn | updatesTSCache | needsRefresh 1056 } 1057 1058 func (*PutRequest) flags() int { 1059 return isWrite | isTxn | isLocking | isIntentWrite | consultsTSCache | canBackpressure 1060 } 1061 1062 // ConditionalPut effectively reads without writing if it hits a 1063 // ConditionFailedError, so it must update the timestamp cache in this case. 1064 // ConditionalPuts do not require a refresh because on write-too-old errors, 1065 // they return an error immediately instead of continuing a serializable 1066 // transaction to be retried at end transaction. 1067 func (*ConditionalPutRequest) flags() int { 1068 return isRead | isWrite | isTxn | isLocking | isIntentWrite | consultsTSCache | updatesTSCache | updatesTSCacheOnErr | canBackpressure 1069 } 1070 1071 // InitPut, like ConditionalPut, effectively reads without writing if it hits a 1072 // ConditionFailedError, so it must update the timestamp cache in this case. 1073 // InitPuts do not require a refresh because on write-too-old errors, they 1074 // return an error immediately instead of continuing a serializable transaction 1075 // to be retried at end transaction. 1076 func (*InitPutRequest) flags() int { 1077 return isRead | isWrite | isTxn | isLocking | isIntentWrite | consultsTSCache | updatesTSCache | updatesTSCacheOnErr | canBackpressure 1078 } 1079 1080 // Increment reads the existing value, but always leaves an intent so 1081 // it does not need to update the timestamp cache. Increments do not 1082 // require a refresh because on write-too-old errors, they return an 1083 // error immediately instead of continuing a serializable transaction 1084 // to be retried at end transaction. 1085 func (*IncrementRequest) flags() int { 1086 return isRead | isWrite | isTxn | isLocking | isIntentWrite | consultsTSCache | canBackpressure 1087 } 1088 1089 func (*DeleteRequest) flags() int { 1090 return isWrite | isTxn | isLocking | isIntentWrite | consultsTSCache | canBackpressure 1091 } 1092 1093 func (drr *DeleteRangeRequest) flags() int { 1094 // DeleteRangeRequest has different properties if the "inline" flag is set. 1095 // This flag indicates that the request is deleting inline MVCC values, 1096 // which cannot be deleted transactionally - inline DeleteRange will thus 1097 // fail if executed as part of a transaction. This alternate flag set 1098 // is needed to prevent the command from being automatically wrapped into a 1099 // transaction by TxnCoordSender, which can occur if the command spans 1100 // multiple ranges. 1101 // 1102 // TODO(mrtracy): The behavior of DeleteRangeRequest with "inline" set has 1103 // likely diverged enough that it should be promoted into its own command. 1104 // However, it is complicated to plumb a new command through the system, 1105 // while this special case in flags() fixes all current issues succinctly. 1106 // This workaround does not preclude us from creating a separate 1107 // "DeleteInlineRange" command at a later date. 1108 if drr.Inline { 1109 return isWrite | isRange | isAlone 1110 } 1111 // DeleteRange updates the timestamp cache as it doesn't leave intents or 1112 // tombstones for keys which don't yet exist, but still wants to prevent 1113 // anybody from writing under it. Note that, even if we didn't update the ts 1114 // cache, deletes of keys that exist would not be lost (since the DeleteRange 1115 // leaves intents on those keys), but deletes of "empty space" would. 1116 return isWrite | isTxn | isLocking | isIntentWrite | isRange | consultsTSCache | updatesTSCache | needsRefresh | canBackpressure 1117 } 1118 1119 // Note that ClearRange commands cannot be part of a transaction as 1120 // they clear all MVCC versions. 1121 func (*ClearRangeRequest) flags() int { return isWrite | isRange | isAlone } 1122 1123 // Note that RevertRange commands cannot be part of a transaction as 1124 // they clear all MVCC versions above their target time. 1125 func (*RevertRangeRequest) flags() int { return isWrite | isRange } 1126 1127 func (sr *ScanRequest) flags() int { 1128 maybeLocking := 0 1129 if sr.KeyLocking != lock.None { 1130 maybeLocking = isLocking 1131 } 1132 return isRead | isRange | isTxn | maybeLocking | updatesTSCache | needsRefresh 1133 } 1134 1135 func (rsr *ReverseScanRequest) flags() int { 1136 maybeLocking := 0 1137 if rsr.KeyLocking != lock.None { 1138 maybeLocking = isLocking 1139 } 1140 return isRead | isRange | isReverse | isTxn | maybeLocking | updatesTSCache | needsRefresh 1141 } 1142 1143 // EndTxn updates the timestamp cache to prevent replays. 1144 // Replays for the same transaction key and timestamp will have 1145 // Txn.WriteTooOld=true and must retry on EndTxn. 1146 func (*EndTxnRequest) flags() int { return isWrite | isTxn | isAlone | updatesTSCache } 1147 func (*AdminSplitRequest) flags() int { return isAdmin | isAlone } 1148 func (*AdminUnsplitRequest) flags() int { return isAdmin | isAlone } 1149 func (*AdminMergeRequest) flags() int { return isAdmin | isAlone } 1150 func (*AdminTransferLeaseRequest) flags() int { return isAdmin | isAlone } 1151 func (*AdminChangeReplicasRequest) flags() int { return isAdmin | isAlone } 1152 func (*AdminRelocateRangeRequest) flags() int { return isAdmin | isAlone } 1153 func (*HeartbeatTxnRequest) flags() int { return isWrite | isTxn } 1154 func (*GCRequest) flags() int { return isWrite | isRange } 1155 1156 // PushTxnRequest updates different marker keys in the timestamp cache when 1157 // pushing a transaction's timestamp and when aborting a transaction. 1158 func (*PushTxnRequest) flags() int { 1159 return isWrite | isAlone | updatesTSCache | updatesTSCache 1160 } 1161 func (*RecoverTxnRequest) flags() int { return isWrite | isAlone | updatesTSCache } 1162 func (*QueryTxnRequest) flags() int { return isRead | isAlone } 1163 1164 // QueryIntent only updates the timestamp cache when attempting to prevent an 1165 // intent that is found missing from ever being written in the future. See 1166 // QueryIntentRequest_PREVENT. 1167 func (*QueryIntentRequest) flags() int { 1168 return isRead | isPrefix | updatesTSCache | updatesTSCacheOnErr 1169 } 1170 func (*ResolveIntentRequest) flags() int { return isWrite } 1171 func (*ResolveIntentRangeRequest) flags() int { return isWrite | isRange } 1172 func (*TruncateLogRequest) flags() int { return isWrite } 1173 func (*MergeRequest) flags() int { return isWrite | canBackpressure } 1174 func (*RequestLeaseRequest) flags() int { return isWrite | isAlone | skipLeaseCheck } 1175 1176 // LeaseInfoRequest is usually executed in an INCONSISTENT batch, which has the 1177 // effect of the `skipLeaseCheck` flag that lease write operations have. 1178 func (*LeaseInfoRequest) flags() int { return isRead | isAlone } 1179 func (*TransferLeaseRequest) flags() int { 1180 // TransferLeaseRequest requires the lease, which is checked in 1181 // `AdminTransferLease()` before the TransferLeaseRequest is created and sent 1182 // for evaluation and in the usual way at application time (i.e. 1183 // replica.processRaftCommand() checks that the lease hasn't changed since the 1184 // command resulting from the evaluation of TransferLeaseRequest was 1185 // proposed). 1186 // 1187 // But we're marking it with skipLeaseCheck because `redirectOnOrAcquireLease` 1188 // can't be used before evaluation as, by the time that call would be made, 1189 // the store has registered that a transfer is in progress and 1190 // `redirectOnOrAcquireLease` would already tentatively redirect to the future 1191 // lease holder. 1192 return isWrite | isAlone | skipLeaseCheck 1193 } 1194 func (*RecomputeStatsRequest) flags() int { return isWrite | isAlone } 1195 func (*ComputeChecksumRequest) flags() int { return isWrite } 1196 func (*CheckConsistencyRequest) flags() int { return isAdmin | isRange } 1197 func (*WriteBatchRequest) flags() int { return isWrite | isRange } 1198 func (*ExportRequest) flags() int { return isRead | isRange | updatesTSCache } 1199 func (*ImportRequest) flags() int { return isAdmin | isAlone } 1200 func (*AdminScatterRequest) flags() int { return isAdmin | isRange | isAlone } 1201 func (*AdminVerifyProtectedTimestampRequest) flags() int { return isAdmin | isRange | isAlone } 1202 func (*AddSSTableRequest) flags() int { 1203 return isWrite | isRange | isAlone | isUnsplittable | canBackpressure 1204 } 1205 1206 // RefreshRequest and RefreshRangeRequest both determine which timestamp cache 1207 // they update based on their Write parameter. 1208 func (r *RefreshRequest) flags() int { 1209 return isRead | isTxn | updatesTSCache 1210 } 1211 func (r *RefreshRangeRequest) flags() int { 1212 return isRead | isTxn | isRange | updatesTSCache 1213 } 1214 1215 func (*SubsumeRequest) flags() int { return isRead | isAlone | updatesTSCache } 1216 func (*RangeStatsRequest) flags() int { return isRead } 1217 1218 // IsParallelCommit returns whether the EndTxn request is attempting to perform 1219 // a parallel commit. See txn_interceptor_committer.go for a discussion about 1220 // parallel commits. 1221 func (etr *EndTxnRequest) IsParallelCommit() bool { 1222 return etr.Commit && len(etr.InFlightWrites) > 0 1223 } 1224 1225 // Keys returns credentials in an aws.Config. 1226 func (b *ExternalStorage_S3) Keys() *aws.Config { 1227 return &aws.Config{ 1228 Credentials: credentials.NewStaticCredentials(b.AccessKey, b.Secret, b.TempToken), 1229 } 1230 } 1231 1232 // InsertRangeInfo inserts ri into a slice of RangeInfo's if a descriptor for 1233 // the same range is not already present. If it is present, it's overwritten; 1234 // the rationale being that ri is newer information than what we had before. 1235 func InsertRangeInfo(ris []RangeInfo, ri RangeInfo) []RangeInfo { 1236 for i := range ris { 1237 if ris[i].Desc.RangeID == ri.Desc.RangeID { 1238 ris[i] = ri 1239 return ris 1240 } 1241 } 1242 return append(ris, ri) 1243 } 1244 1245 // BulkOpSummaryID returns the key within a BulkOpSummary's EntryCounts map for 1246 // the given table and index ID. This logic is mirrored in c++ in rowcounter.cc. 1247 func BulkOpSummaryID(tableID, indexID uint64) uint64 { 1248 return (tableID << 32) | indexID 1249 } 1250 1251 // Add combines the values from other, for use on an accumulator BulkOpSummary. 1252 func (b *BulkOpSummary) Add(other BulkOpSummary) { 1253 b.DataSize += other.DataSize 1254 b.DeprecatedRows += other.DeprecatedRows 1255 b.DeprecatedIndexEntries += other.DeprecatedIndexEntries 1256 1257 if other.EntryCounts != nil && b.EntryCounts == nil { 1258 b.EntryCounts = make(map[uint64]int64, len(other.EntryCounts)) 1259 } 1260 for i := range other.EntryCounts { 1261 b.EntryCounts[i] += other.EntryCounts[i] 1262 } 1263 } 1264 1265 // MustSetValue is like SetValue, except it resets the enum and panics if the 1266 // provided value is not a valid variant type. 1267 func (e *RangeFeedEvent) MustSetValue(value interface{}) { 1268 e.Reset() 1269 if !e.SetValue(value) { 1270 panic(fmt.Sprintf("%T excludes %T", e, value)) 1271 } 1272 } 1273 1274 // ShallowCopy returns a shallow copy of the receiver and its variant type. 1275 func (e *RangeFeedEvent) ShallowCopy() *RangeFeedEvent { 1276 cpy := *e 1277 switch t := cpy.GetValue().(type) { 1278 case *RangeFeedValue: 1279 cpyVal := *t 1280 cpy.MustSetValue(&cpyVal) 1281 case *RangeFeedCheckpoint: 1282 cpyChk := *t 1283 cpy.MustSetValue(&cpyChk) 1284 case *RangeFeedError: 1285 cpyErr := *t 1286 cpy.MustSetValue(&cpyErr) 1287 default: 1288 panic(fmt.Sprintf("unexpected RangeFeedEvent variant: %v", t)) 1289 } 1290 return &cpy 1291 } 1292 1293 // MakeReplicationChanges returns a slice of changes of the given type with an 1294 // item for each target. 1295 func MakeReplicationChanges( 1296 changeType ReplicaChangeType, targets ...ReplicationTarget, 1297 ) []ReplicationChange { 1298 chgs := make([]ReplicationChange, 0, len(targets)) 1299 for _, target := range targets { 1300 chgs = append(chgs, ReplicationChange{ 1301 ChangeType: changeType, 1302 Target: target, 1303 }) 1304 } 1305 return chgs 1306 } 1307 1308 // AddChanges adds a batch of changes to the request in a backwards-compatible 1309 // way. 1310 func (acrr *AdminChangeReplicasRequest) AddChanges(chgs ...ReplicationChange) { 1311 acrr.InternalChanges = append(acrr.InternalChanges, chgs...) 1312 1313 acrr.DeprecatedChangeType = chgs[0].ChangeType 1314 for _, chg := range chgs { 1315 acrr.DeprecatedTargets = append(acrr.DeprecatedTargets, chg.Target) 1316 } 1317 } 1318 1319 // ReplicationChanges is a slice of ReplicationChange. 1320 type ReplicationChanges []ReplicationChange 1321 1322 func (rc ReplicationChanges) byType(typ ReplicaChangeType) []ReplicationTarget { 1323 var sl []ReplicationTarget 1324 for _, chg := range rc { 1325 if chg.ChangeType == typ { 1326 sl = append(sl, chg.Target) 1327 } 1328 } 1329 return sl 1330 } 1331 1332 // Additions returns a slice of all contained replication changes that add replicas. 1333 func (rc ReplicationChanges) Additions() []ReplicationTarget { 1334 return rc.byType(ADD_REPLICA) 1335 } 1336 1337 // Removals returns a slice of all contained replication changes that remove replicas. 1338 func (rc ReplicationChanges) Removals() []ReplicationTarget { 1339 return rc.byType(REMOVE_REPLICA) 1340 } 1341 1342 // Changes returns the changes requested by this AdminChangeReplicasRequest, taking 1343 // the deprecated method of doing so into account. 1344 func (acrr *AdminChangeReplicasRequest) Changes() []ReplicationChange { 1345 if len(acrr.InternalChanges) > 0 { 1346 return acrr.InternalChanges 1347 } 1348 1349 sl := make([]ReplicationChange, len(acrr.DeprecatedTargets)) 1350 for _, target := range acrr.DeprecatedTargets { 1351 sl = append(sl, ReplicationChange{ 1352 ChangeType: acrr.DeprecatedChangeType, 1353 Target: target, 1354 }) 1355 } 1356 return sl 1357 } 1358 1359 // AsLockUpdate creates a lock update message corresponding to the given resolve 1360 // intent request. 1361 func (rir *ResolveIntentRequest) AsLockUpdate() LockUpdate { 1362 return LockUpdate{ 1363 Span: rir.Span(), 1364 Txn: rir.IntentTxn, 1365 Status: rir.Status, 1366 IgnoredSeqNums: rir.IgnoredSeqNums, 1367 } 1368 } 1369 1370 // AsLockUpdate creates a lock update message corresponding to the given resolve 1371 // intent range request. 1372 func (rirr *ResolveIntentRangeRequest) AsLockUpdate() LockUpdate { 1373 return LockUpdate{ 1374 Span: rirr.Span(), 1375 Txn: rirr.IntentTxn, 1376 Status: rirr.Status, 1377 IgnoredSeqNums: rirr.IgnoredSeqNums, 1378 } 1379 }