private void internalRegionScan(final Region region, final byte[] subStartKey, final byte[] subEndKey,
                                    final boolean reverse, final boolean readOnlySafe, final boolean returnValue,
                                    final CompletableFuture<List<KVEntry>> future, final int retriesLeft,
                                    final Errors lastCause, final boolean requireLeader) {
        final RegionEngine regionEngine = getRegionEngine(region.getId(), requireLeader);
        // require leader on retry
        final RetryRunner retryRunner = retryCause -> internalRegionScan(region, subStartKey, subEndKey, reverse, readOnlySafe,
                returnValue, future, retriesLeft - 1, retryCause, true);
        final FailoverClosure<List<KVEntry>> closure = new FailoverClosureImpl<>(future, false,
                retriesLeft, retryRunner);
        if (regionEngine != null) {
            if (ensureOnValidEpoch(region, regionEngine, closure)) {
                final RawKVStore rawKVStore = getRawKVStore(regionEngine);
                if (reverse) {
                    if (this.kvDispatcher == null) {
                        rawKVStore.reverseScan(subStartKey, subEndKey, readOnlySafe, returnValue, closure);
                    } else {
                        this.kvDispatcher.execute(
                                () -> rawKVStore.reverseScan(subStartKey, subEndKey, readOnlySafe, returnValue, closure));
                    }
                } else {
                    if (this.kvDispatcher == null) {
                        rawKVStore.scan(subStartKey, subEndKey, readOnlySafe, returnValue, closure);
                    } else {
                        this.kvDispatcher.execute(
                                () -> rawKVStore.scan(subStartKey, subEndKey, readOnlySafe, returnValue, closure));
                    }
                }
            }
        } else {
            final ScanRequest request = new ScanRequest();
            request.setStartKey(subStartKey);
            request.setEndKey(subEndKey);
            request.setReadOnlySafe(readOnlySafe);
            request.setReturnValue(returnValue);
            request.setRegionId(region.getId());
            request.setRegionEpoch(region.getRegionEpoch());
            request.setReverse(reverse);
            this.rheaKVRpcService.callAsyncWithRpc(request, closure, lastCause, requireLeader);
        }
    }
Returns a heap-allocated iterator over the contents of the
database.
<p>
Caller should close the iterator when it is no longer needed.
The returned iterator should be closed before this db is closed.
<p>
<pre>
    KVIterator it = unsafeLocalIterator();
    try {
        // do something
    } finally {
        it.close();
    }
<pre/>
jraft-rheakv/rheakv-core/src/main/java/com/alipay/sofa/jraft/rhea/client/DefaultRheaKVStore.java