You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: range_iter.go
    path of file: ./repos/cockroach/pkg/kv/kvclient/kvcoord
    
    the code of the file until where you have to start completion: // Copyright 2016 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

package kvcoord

import (
	"context"

	"github.com/cockroachdb/cockroach/pkg/kv/kvclient/rangecache"
	"github.com/cockroachdb/cockroach/pkg/roachpb"
	"git
    
func (ri *RangeIterator) Seek(ctx context.Context, key roachpb.RKey, scanDir ScanDirection) {
	logEvents := log.HasSpan(ctx)
	if logEvents {
		rev := ""
		if scanDir == Descending {
			rev = " (rev)"
		}
		log.Eventf(ctx, "querying next range at %s%s", key, rev)
	}
	ri.scanDir = scanDir
	ri.init = true // the iterator is now initialized
	ri.err = nil   // clear any prior error
	ri.key = key   // set the key

	if (scanDir == Ascending && key.Equal(roachpb.RKeyMax)) ||
		(scanDir == Descending && key.Equal(roachpb.RKeyMin)) {
		ri.err = errors.Errorf("RangeIterator seek to invalid key %s", key)
		return
	}

	// Retry loop for looking up next range in the span. The retry loop
	// deals with retryable range descriptor lookups.
	var err error
	for r := retry.StartWithCtx(ctx, ri.ds.rpcRetryOptions); r.Next(); {
		// Note that we pass an empty eviction token here because ri.token
		// corresponds to the previous range.
		var rngInfo rangecache.EvictionToken
		rngInfo, err = ri.ds.getRoutingInfo(
			ctx, ri.key, rangecache.EvictionToken{}, ri.scanDir == Descending,
		)

		// getRoutingInfo 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.VEventf(ctx, 1, "range descriptor lookup failed: %s", err)
			if !rangecache.IsRangeLookupErrorRetryable(err) {
				break
			}
			continue
		}
		if logEvents {
			log.Eventf(ctx, "key: %s, desc: %s", ri.key, rngInfo.Desc())
		}

		ri.token = rngInfo
		return
	}

	// Check for an early exit from the retry loop.
	if deducedErr := ri.ds.deduceRetryEarlyExitError(ctx, err); deducedErr != nil {
		ri.err = deducedErr
	} else {
		ri.err = errors.Wrapf(err, "RangeIterator failed to seek to %s", key)
	}
}