// getCachedRangeDescriptorLocked is a helper function to retrieve the // descriptor of the range which contains the given key, if present in the // cache. It is assumed that the caller holds a read lock on rdc.rangeCacheMu. func (rdc *rangeDescriptorCache) getCachedRangeDescriptorLocked(key roachpb.RKey, inclusive bool) ( rangeCacheKey, *roachpb.RangeDescriptor) { // The cache is indexed using the end-key of the range, but the // end-key is non-inclusive by default. var metaKey roachpb.RKey if !inclusive { metaKey = meta(key.Next()) } else { metaKey = meta(key) } k, v, ok := rdc.rangeCache.Ceil(rangeCacheKey(metaKey)) if !ok { return nil, nil } metaEndKey := k.(rangeCacheKey) rd := v.(*roachpb.RangeDescriptor) // Check that key actually belongs to the range. if !rd.ContainsKey(key) { // The key is the EndKey and we're inclusive, so just return the range descriptor. if inclusive && key.Equal(rd.EndKey) { return metaEndKey, rd } return nil, nil } // The key is the StartKey, but we're inclusive and thus need to return the // previous range descriptor, but it is not in the cache yet. if inclusive && key.Equal(rd.StartKey) { return nil, nil } return metaEndKey, rd }
// getCachedRangeDescriptorLocked is a helper function to retrieve the // descriptor of the range which contains the given key, if present in the // cache. It is assumed that the caller holds a read lock on rdc.rangeCache. func (rdc *rangeDescriptorCache) getCachedRangeDescriptorLocked(key roachpb.RKey, inclusive bool) (rangeCacheKey, *roachpb.RangeDescriptor, error) { // The cache is indexed using the end-key of the range, but the // end-key is non-inclusive by default. var metaKey roachpb.RKey var err error if !inclusive { metaKey, err = meta(key.Next()) } else { metaKey, err = meta(key) } if err != nil { return nil, nil, err } k, v, ok := rdc.rangeCache.cache.Ceil(rangeCacheKey(metaKey)) if !ok { return nil, nil, nil } metaEndKey := k.(rangeCacheKey) rd := v.(*roachpb.RangeDescriptor) // Return nil if the key does not belong to the range. if (!inclusive && !rd.ContainsKey(key)) || (inclusive && !rd.ContainsExclusiveEndKey(key)) { return nil, nil, nil } return metaEndKey, rd, nil }
func (db *testDescriptorDB) getDescriptors(key roachpb.RKey, considerIntents bool, useReverseScan bool) ([]roachpb.RangeDescriptor, []roachpb.RangeDescriptor, *roachpb.Error) { rs := make([]roachpb.RangeDescriptor, 0, 1) preRs := make([]roachpb.RangeDescriptor, 0, 2) for i := 0; i < 3; i++ { var endKey roachpb.RKey if useReverseScan { endKey = key } else { endKey = key.Next() } v := db.data.Ceil(testDescriptorNode{ &roachpb.RangeDescriptor{ EndKey: endKey, }, }) if v == nil { break } desc := *(v.(testDescriptorNode).RangeDescriptor) if i == 0 { rs = append(rs, desc) if considerIntents { desc.RangeID++ rs = append(rs, desc) break } else if db.disablePrefetch { break } } else { preRs = append(preRs, desc) } // Break to keep from skidding off the end of the available ranges. if desc.EndKey.Equal(roachpb.RKeyMax) { break } if useReverseScan { key = desc.StartKey } else { key = desc.EndKey } } return rs, preRs, nil }
// MetaScanBounds returns the range [start,end) within which the desired meta // record can be found by means of an engine scan. The given key must be a // valid RangeMetaKey as defined by validateRangeMetaKey. // TODO(tschottdorf): a lot of casting going on inside. func MetaScanBounds(key roachpb.RKey) (roachpb.Key, roachpb.Key, error) { if err := validateRangeMetaKey(key); err != nil { return nil, nil, err } if key.Equal(Meta2KeyMax) { return nil, nil, NewInvalidRangeMetaKeyError("Meta2KeyMax can't be used as the key of scan", key) } if key.Equal(roachpb.RKeyMin) { // Special case KeyMin: find the first entry in meta1. return Meta1Prefix, Meta1Prefix.PrefixEnd(), nil } if key.Equal(Meta1KeyMax) { // Special case Meta1KeyMax: this is the last key in Meta1, we don't want // to start at Next(). return Meta1KeyMax, Meta1Prefix.PrefixEnd(), nil } // Otherwise find the first entry greater than the given key in the same meta prefix. return key.Next().AsRawKey(), key[:len(Meta1Prefix)].PrefixEnd().AsRawKey(), nil }
// MetaReverseScanBounds returns the range [start,end) within which the desired // meta record can be found by means of a reverse engine scan. The given key // must be a valid RangeMetaKey as defined by validateRangeMetaKey. func MetaReverseScanBounds(key roachpb.RKey) (roachpb.Key, roachpb.Key, error) { if err := validateRangeMetaKey(key); err != nil { return nil, nil, err } if key.Equal(roachpb.RKeyMin) || key.Equal(Meta1Prefix) { return nil, nil, NewInvalidRangeMetaKeyError("KeyMin and Meta1Prefix can't be used as the key of reverse scan", key) } if key.Equal(Meta2Prefix) { // Special case Meta2Prefix: this is the first key in Meta2, and the scan // interval covers all of Meta1. return Meta1Prefix, key.Next().AsRawKey(), nil } // Otherwise find the first entry greater than the given key and find the last entry // in the same prefix. For MVCCReverseScan the endKey is exclusive, if we want to find // the range descriptor the given key specified,we need to set the key.Next() as the // MVCCReverseScan`s endKey. For example: // If we have ranges [a,f) and [f,z), then we'll have corresponding meta records // at f and z. If you're looking for the meta record for key f, then you want the // second record (exclusive in MVCCReverseScan), hence key.Next() below. return key[:len(Meta1Prefix)].AsRawKey(), key.Next().AsRawKey(), nil }