本文整理汇总了Golang中github.com/cockroachdb/cockroach/roachpb.RangeDescriptor.ContainsExclusiveEndKey方法的典型用法代码示例。如果您正苦于以下问题:Golang RangeDescriptor.ContainsExclusiveEndKey方法的具体用法?Golang RangeDescriptor.ContainsExclusiveEndKey怎么用?Golang RangeDescriptor.ContainsExclusiveEndKey使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类github.com/cockroachdb/cockroach/roachpb.RangeDescriptor
的用法示例。
在下文中一共展示了RangeDescriptor.ContainsExclusiveEndKey方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: testRangeCacheHandleDoubleSplit
func testRangeCacheHandleDoubleSplit(t *testing.T, useReverseScan bool) {
db := initTestDescriptorDB(t)
db.disablePrefetch = true
// A request initially looks up the range descriptor ["a"-"b").
doLookup(t, db.cache, "aa")
db.assertLookupCountEq(t, 2, "aa")
// A split breaks up the range into ["a"-"an"), ["an"-"at"), ["at"-"b").
db.splitRange(t, roachpb.RKey("an"))
db.splitRange(t, roachpb.RKey("at"))
// A request is sent to the stale descriptor on the right half
// such that a RangeKeyMismatchError is returned.
_, evictToken := doLookup(t, db.cache, "az")
// mismatchErrRange mocks out a RangeKeyMismatchError.Range response.
ranges, _, pErr := db.getDescriptors(roachpb.RKey("aa"), false, false)
if pErr != nil {
t.Fatal(pErr)
}
mismatchErrRange := ranges[0]
// The stale descriptor is evicted, the new descriptor from the error is
// replaced, and a new lookup is initialized.
if err := evictToken.EvictAndReplace(context.Background(), mismatchErrRange); err != nil {
t.Fatal(err)
}
// Requests to all parts of the split are sent:
// [reverse case]
// - "aa" and "an" will hit the cache
// - all others will join a coalesced request to "az"
// + will lookup the meta2 desc
// + will lookup the ["at"-"b") desc
// - "az" will get the right range back
// - "at" will make a second lookup
// + will lookup the ["an"-"at") desc
//
// [non-reverse case]
// - "aa" will hit the cache
// - all others will join a coalesced request to "an"
// + will lookup the meta2 desc
// + will lookup the ["an"-"at") desc
// - "an" and "ao" will get the right range back
// - "at" and "az" will make a second lookup
// + will lookup the ["at"-"b") desc
var wg, waitJoin sync.WaitGroup
db.pauseRangeLookups()
numRetries := int64(0)
for _, k := range []string{"aa", "an", "ao", "at", "az"} {
wg.Add(1)
waitJoin.Add(1)
go func(key roachpb.RKey) {
reqEvictToken := evictToken
waitJoinCopied := &waitJoin
var desc *roachpb.RangeDescriptor
for {
// Each request goes to a different key.
var err error
if desc, reqEvictToken, err = db.cache.lookupRangeDescriptorInternal(
context.Background(), key, reqEvictToken, false, /* considerIntents */
useReverseScan, waitJoinCopied); err != nil {
waitJoinCopied = nil
atomic.AddInt64(&numRetries, 1)
continue
}
break
}
if useReverseScan {
if !desc.ContainsExclusiveEndKey(key) {
t.Errorf("desc %s does not contain exclusive end key %s", desc, key)
}
} else {
if !desc.ContainsKey(key) {
t.Errorf("desc %s does not contain key %s", desc, key)
}
}
wg.Done()
}(roachpb.RKey(k))
}
// Wait until all lookup requests hit the cache or join into a coalesced request.
waitJoin.Wait()
db.resumeRangeLookups()
wg.Wait()
db.assertLookupCountEq(t, 3, "an and az")
if numRetries == 0 {
t.Error("expected retry on desc lookup")
}
// All three descriptors are now correctly cached.
doLookup(t, db.cache, "aa")
db.assertLookupCountEq(t, 0, "aa")
doLookup(t, db.cache, "ao")
db.assertLookupCountEq(t, 0, "ao")
doLookup(t, db.cache, "az")
db.assertLookupCountEq(t, 0, "az")
}
示例2: sendChunk
//.........这里部分代码省略.........
pErr = roachpb.NewError(err)
continue
}
if needAnother && br == nil {
// TODO(tschottdorf): we should have a mechanism for discovering
// range merges (descriptor staleness will mostly go unnoticed),
// or we'll be turning single-range queries into multi-range
// queries for no good reason.
// If there's no transaction and op spans ranges, possibly
// re-run as part of a transaction for consistency. The
// case where we don't need to re-run is if the read
// consistency is not required.
if ba.Txn == nil && ba.IsPossibleTransaction() &&
ba.ReadConsistency != roachpb.INCONSISTENT {
return nil, roachpb.NewError(&roachpb.OpRequiresTxnError{}), false
}
// If the request is more than but ends with EndTransaction, we
// want the caller to come again with the EndTransaction in an
// extra call.
if l := len(ba.Requests) - 1; l > 0 && ba.Requests[l].GetInner().Method() == roachpb.EndTransaction {
return nil, roachpb.NewError(errors.New("cannot send 1PC txn to multiple ranges")), true /* shouldSplitET */
}
}
// It's possible that the returned descriptor misses parts of the
// keys it's supposed to scan after it's truncated to match the
// descriptor. Example revscan [a,g), first desc lookup for "g"
// returns descriptor [c,d) -> [d,g) is never scanned.
// We evict and retry in such a case.
includesFrontOfCurSpan := func(rd *roachpb.RangeDescriptor) bool {
if isReverse {
return desc.ContainsExclusiveEndKey(rs.EndKey)
}
return desc.ContainsKey(rs.Key)
}
if !includesFrontOfCurSpan(desc) {
if err := evictToken.Evict(ctx); err != nil {
return nil, roachpb.NewError(err), false
}
// On addressing errors, don't backoff; retry immediately.
r.Reset()
continue
}
curReply, pErr = func() (*roachpb.BatchResponse, *roachpb.Error) {
// Truncate the request to our current key range.
intersected, iErr := rs.Intersect(desc)
if iErr != nil {
return nil, roachpb.NewError(iErr)
}
truncBA, numActive, trErr := truncate(ba, intersected)
if numActive == 0 && trErr == nil {
// This shouldn't happen in the wild, but some tests
// exercise it.
return nil, roachpb.NewErrorf("truncation resulted in empty batch on [%s,%s): %s",
rs.Key, rs.EndKey, ba)
}
if trErr != nil {
return nil, roachpb.NewError(trErr)
}
return ds.sendSingleRange(ctx, truncBA, desc)
}()
// If sending succeeded, break this loop.
if pErr == nil {
示例3: sendChunk
// sendChunk is in charge of sending an "admissible" piece of batch, i.e. one
// which doesn't need to be subdivided further before going to a range (so no
// mixing of forward and reverse scans, etc). The parameters and return values
// correspond to client.Sender with the exception of the returned boolean,
// which is true when indicating that the caller should retry but needs to send
// EndTransaction in a separate request.
func (ds *DistSender) sendChunk(ctx context.Context, ba roachpb.BatchRequest) (*roachpb.BatchResponse, *roachpb.Error, bool) {
isReverse := ba.IsReverse()
ctx, cleanup := tracing.EnsureContext(ctx, ds.Tracer)
defer cleanup()
// The minimal key range encompassing all requests contained within.
// Local addressing has already been resolved.
// TODO(tschottdorf): consider rudimentary validation of the batch here
// (for example, non-range requests with EndKey, or empty key ranges).
rs, err := keys.Range(ba)
if err != nil {
return nil, roachpb.NewError(err), false
}
var br *roachpb.BatchResponse
// Send the request to one range per iteration.
for {
// Increase the sequence counter only once before sending RPCs to
// the ranges involved in this chunk of the batch (as opposed to for
// each RPC individually). On RPC errors, there's no guarantee that
// the request hasn't made its way to the target regardless of the
// error; we'd like the second execution to be caught by the sequence
// cache if that happens. There is a small chance that that we address
// a range twice in this chunk (stale/suboptimal descriptors due to
// splits/merges) which leads to a transaction retry.
// TODO(tschottdorf): it's possible that if we don't evict from the
// cache we could be in for a busy loop.
ba.SetNewRequest()
var curReply *roachpb.BatchResponse
var desc *roachpb.RangeDescriptor
var evictToken *evictionToken
var needAnother bool
var pErr *roachpb.Error
var finished bool
for r := retry.Start(ds.rpcRetryOptions); r.Next(); {
// Get range descriptor (or, when spanning range, descriptors). Our
// error handling below may clear them on certain errors, so we
// refresh (likely from the cache) on every retry.
log.Trace(ctx, "meta descriptor lookup")
var err error
desc, needAnother, evictToken, err = ds.getDescriptors(ctx, rs, evictToken, isReverse)
// getDescriptors may fail retryably if, for example, the first
// range isn't available via Gossip. Assume that all errors at
// this level are retryable. Non-retryable errors would be for
// things like malformed requests which we should have checked
// for before reaching this point.
if err != nil {
log.Trace(ctx, "range descriptor lookup failed: "+err.Error())
if log.V(1) {
log.Warning(err)
}
pErr = roachpb.NewError(err)
continue
}
if needAnother && br == nil {
// TODO(tschottdorf): we should have a mechanism for discovering
// range merges (descriptor staleness will mostly go unnoticed),
// or we'll be turning single-range queries into multi-range
// queries for no good reason.
// If there's no transaction and op spans ranges, possibly
// re-run as part of a transaction for consistency. The
// case where we don't need to re-run is if the read
// consistency is not required.
if ba.Txn == nil && ba.IsPossibleTransaction() &&
ba.ReadConsistency != roachpb.INCONSISTENT {
return nil, roachpb.NewError(&roachpb.OpRequiresTxnError{}), false
}
// If the request is more than but ends with EndTransaction, we
// want the caller to come again with the EndTransaction in an
// extra call.
if l := len(ba.Requests) - 1; l > 0 && ba.Requests[l].GetInner().Method() == roachpb.EndTransaction {
return nil, roachpb.NewError(errors.New("cannot send 1PC txn to multiple ranges")), true /* shouldSplitET */
}
}
// It's possible that the returned descriptor misses parts of the
// keys it's supposed to scan after it's truncated to match the
// descriptor. Example revscan [a,g), first desc lookup for "g"
// returns descriptor [c,d) -> [d,g) is never scanned.
// We evict and retry in such a case.
includesFrontOfCurSpan := func(rd *roachpb.RangeDescriptor) bool {
if isReverse {
return desc.ContainsExclusiveEndKey(rs.EndKey)
}
return desc.ContainsKey(rs.Key)
}
if !includesFrontOfCurSpan(desc) {
if err := evictToken.Evict(ctx); err != nil {
return nil, roachpb.NewError(err), false
//.........这里部分代码省略.........