const (
// This is almost the same as 'tikv_gc_safe_point' in the table 'mysql.tidb',
// save this to pd instead of tikv, because we can't use interface of table
// if the safepoint on tidb is expired.GcSavedSafePoint = "/tidb/store/gcworker/saved_safe_point"
GcSafePointCacheInterval = time.Second * 100
)

var (
// MaxRawKVScanLimit is the maximum scan limit for rawkv Scan.MaxRawKVScanLimit = 10240
// ErrMaxScanLimitExceeded is returned when the limit for rawkv Scan is to large.ErrMaxScanLimitExceeded = errors.New("limit should be less than MaxRawKVScanLimit")
)

ShuttingDown is a flag to indicate tidb-server is exiting (Ctrl+C signal
receved for example). If this flag is set, tikv client should not retry on
network error because tidb-server expect tikv client to exit as soon as possible.

NewDeleteRangeTask creates a DeleteRangeTask. Deleting will be performed when `Execute` method is invoked.
Be careful while using this API. This API doesn't keep recent MVCC versions, but will delete all versions of all keys
in the range immediately. Also notice that frequent invocation to this API may cause performance problems to TiKV.

NewNotifyDeleteRangeTask creates a task that sends delete range requests to all regions in the range, but with the
flag `notifyOnly` set. TiKV will not actually delete the range after receiving request, but it will be replicated via
raft. This is used to notify the involved regions before sending UnsafeDestroyRange requests.

GetTxnStatus queries tikv-server for a txn's status (commit/rollback).
If the primary key is still locked, it will launch a Rollback to abort it.
To avoid unnecessarily aborting too many txns, it is wiser to wait a few
seconds before calling it after Prewrite.

ResolveLocks tries to resolve Locks. The resolving process is in 3 steps:
1) Use the `lockTTL` to pick up all expired locks. Only locks that are too

old are considered orphan locks and will be handled later. If all locks
are expired then all locks will be resolved so the returned `ok` will be
true, otherwise caller should sleep a while before retry.

2) For each lock, query the primary key to get txn(which left the lock)'s

commit status.

3) Send `ResolveLock` cmd to the lock's region to resolve all locks belong to

RangeTaskHandler is the type of functions that processes a task of a key range.
The function should calculate Regions that succeeded or failed to the task.
Returning error from the handler means the error caused the whole task should be stopped.

RangeTaskRunner splits a range into many ranges to process concurrently, and convenient to send requests to all
regions in the range. Because of merging and splitting, it's possible that multiple requests for disjoint ranges are
sent to the same region.

`requestCreator` is the function used to create RPC request according to the given range.
`responseHandler` is the function to process responses of errors. If `responseHandler` returns error, the whole job
will be canceled.

ReverseScan queries continuous kv pairs in range [endKey, startKey), up to limit pairs.
Direction is different from Scan, upper to lower.
If endKey is empty, it means unbounded.
If you want to include the startKey or exclude the endKey, append a '\0' to the key. For example, to scan
(endKey, startKey], you can write:
`ReverseScan(append(startKey, '\0'), append(endKey, '\0'), limit)`.
It doesn't support Scanning from "", because locating the last Region is not yet implemented.

Scan queries continuous kv pairs in range [startKey, endKey), up to limit pairs.
If endKey is empty, it means unbounded.
If you want to exclude the startKey or include the endKey, append a '\0' to the key. For example, to scan
(startKey, endKey], you can write:
`Scan(append(startKey, '\0'), append(endKey, '\0'), limit)`.

BatchLoadRegionsFromKey loads at most given numbers of regions to the RegionCache, from the given startKey. Returns
the endKey of the last loaded region. If some of the regions has no leader, their entries in RegionCache will not be
updated.

GroupKeysByRegion separates keys into groups by their belonging Regions.
Specially it also returns the first key's region which may be used as the
'PrimaryLockKey' and should be committed ahead of others.
filter is used to filter some unwanted keys.

Typically, a KV/Cop request is bind to a region, all keys that are involved
in the request should be located in the region.
The sending process begins with looking for the address of leader store's
address of the target region from cache, and the request is then sent to the
destination tikv server over TCP connection.
If region is updated, can be caused by leader transfer, region split, region
merge, or region balance, tikv server may not able to process request and
send back a RegionError.
RegionRequestSender takes care of errors that does not relevant to region
range, such as 'I/O timeout', 'NotLeader', and 'ServerIsBusy'. For other
errors, since region range have changed, the request may need to split, so we
simply return the error to caller.