code: func (c *RawKVClient) sendDeleteRangeReq(startKey []byte, endKey []byte) (*tikvrpc.Response, []byte, error) {
  	bo := NewBackoffer(context.Background(), rawkvMaxBackoff)
  	sender := NewRegionRequestSender(c.regionCache, c.rpcClient)
  	for {
  		loc, err := c.regionCache.LocateKey(bo, startKey)
  		if err != nil {
  			return nil, nil, errors.Trace(err)
  		}
  
  		actualEndKey := endKey
  		if len(loc.EndKey) > 0 && bytes.Compare(loc.EndKey, endKey) < 0 {
  			actualEndKey = loc.EndKey
  		}
  
  		req := &tikvrpc.Request{
  			Type: tikvrpc.CmdRawDeleteRange,
  			RawDeleteRange: &kvrpcpb.RawDeleteRangeRequest{
  				StartKey: startKey,
  				EndKey:   actualEndKey,
  			},
  		}
  
  		resp, err := sender.SendReq(bo, req, loc.Region, readTimeoutShort)
  		if err != nil {
  			return nil, nil, errors.Trace(err)
  		}
  		regionErr, err := resp.GetRegionError()
  		if err != nil {
  			return nil, nil, errors.Trace(err)
  		}
  		if regionErr != nil {
  			err := bo.Backoff(BoRegionMiss, errors.New(regionErr.String()))
  			if err != nil {
  				return nil, nil, errors.Trace(err)
  			}
  			continue
  		}
  		return resp, actualEndKey, nil
  	}
  }
docs: // sendDeleteRangeReq sends a raw delete range request and returns the response and the actual endKey.
  // If the given range spans over more than one regions, the actual endKey is the end of the first region.
  // We can't use sendReq directly, because we need to know the end of the region before we send the request
  // TODO: Is there any better way to avoid duplicating code with func `sendReq` ?