http://git-wip-us.apache.org/repos/asf/hbase-site/blob/e5c3dcd1/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/RSRpcServices.RegionScannersCloseCallBack.html
----------------------------------------------------------------------
diff --git
a/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/RSRpcServices.RegionScannersCloseCallBack.html
b/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/RSRpcServices.RegionScannersCloseCallBack.html
index be615ae..9d47569 100644
---
a/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/RSRpcServices.RegionScannersCloseCallBack.html
+++
b/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/RSRpcServices.RegionScannersCloseCallBack.html
@@ -2526,324 +2526,327 @@
<span class="sourceLineNo">2518</span> }<a name="line.2518"></a>
<span class="sourceLineNo">2519</span> assert scanner != null;<a
name="line.2519"></a>
<span class="sourceLineNo">2520</span> if (request.hasRenew() &&
request.getRenew()) {<a name="line.2520"></a>
-<span class="sourceLineNo">2521</span> lease =
regionServer.leases.removeLease(scannerName);<a name="line.2521"></a>
-<span class="sourceLineNo">2522</span> if (lease != null &&
scanners.containsKey(scannerName)) {<a name="line.2522"></a>
-<span class="sourceLineNo">2523</span>
regionServer.leases.addLease(lease);<a name="line.2523"></a>
-<span class="sourceLineNo">2524</span> }<a name="line.2524"></a>
-<span class="sourceLineNo">2525</span> return builder.build();<a
name="line.2525"></a>
-<span class="sourceLineNo">2526</span> }<a name="line.2526"></a>
-<span class="sourceLineNo">2527</span> RpcCallContext context =
RpcServer.getCurrentCall();<a name="line.2527"></a>
-<span class="sourceLineNo">2528</span> Object lastBlock = null;<a
name="line.2528"></a>
-<span class="sourceLineNo">2529</span><a name="line.2529"></a>
-<span class="sourceLineNo">2530</span> quota =
getQuotaManager().checkQuota(region, OperationQuota.OperationType.SCAN);<a
name="line.2530"></a>
-<span class="sourceLineNo">2531</span> long maxQuotaResultSize =
Math.min(maxScannerResultSize, quota.getReadAvailable());<a
name="line.2531"></a>
+<span class="sourceLineNo">2521</span> rsh =
scanners.get(scannerName);<a name="line.2521"></a>
+<span class="sourceLineNo">2522</span> lease =
regionServer.leases.removeLease(scannerName);<a name="line.2522"></a>
+<span class="sourceLineNo">2523</span> if (lease != null && rsh
!= null) {<a name="line.2523"></a>
+<span class="sourceLineNo">2524</span>
regionServer.leases.addLease(lease);<a name="line.2524"></a>
+<span class="sourceLineNo">2525</span> // Increment the nextCallSeq
value which is the next expected from client.<a name="line.2525"></a>
+<span class="sourceLineNo">2526</span> rsh.incNextCallSeq();<a
name="line.2526"></a>
+<span class="sourceLineNo">2527</span> }<a name="line.2527"></a>
+<span class="sourceLineNo">2528</span> return builder.build();<a
name="line.2528"></a>
+<span class="sourceLineNo">2529</span> }<a name="line.2529"></a>
+<span class="sourceLineNo">2530</span> RpcCallContext context =
RpcServer.getCurrentCall();<a name="line.2530"></a>
+<span class="sourceLineNo">2531</span> Object lastBlock = null;<a
name="line.2531"></a>
<span class="sourceLineNo">2532</span><a name="line.2532"></a>
-<span class="sourceLineNo">2533</span> if (rows > 0) {<a
name="line.2533"></a>
-<span class="sourceLineNo">2534</span> // if nextCallSeq does not match
throw Exception straight away. This needs to be<a name="line.2534"></a>
-<span class="sourceLineNo">2535</span> // performed even before
checking of Lease.<a name="line.2535"></a>
-<span class="sourceLineNo">2536</span> // See HBASE-5974<a
name="line.2536"></a>
-<span class="sourceLineNo">2537</span> if (request.hasNextCallSeq())
{<a name="line.2537"></a>
-<span class="sourceLineNo">2538</span> if (rsh != null) {<a
name="line.2538"></a>
-<span class="sourceLineNo">2539</span> if (request.getNextCallSeq()
!= rsh.getNextCallSeq()) {<a name="line.2539"></a>
-<span class="sourceLineNo">2540</span> throw new
OutOfOrderScannerNextException(<a name="line.2540"></a>
-<span class="sourceLineNo">2541</span> "Expected nextCallSeq: "
+ rsh.getNextCallSeq()<a name="line.2541"></a>
-<span class="sourceLineNo">2542</span> + " But the nextCallSeq
got from client: " + request.getNextCallSeq() +<a name="line.2542"></a>
-<span class="sourceLineNo">2543</span> "; request=" +
TextFormat.shortDebugString(request));<a name="line.2543"></a>
-<span class="sourceLineNo">2544</span> }<a name="line.2544"></a>
-<span class="sourceLineNo">2545</span> // Increment the nextCallSeq
value which is the next expected from client.<a name="line.2545"></a>
-<span class="sourceLineNo">2546</span> rsh.incNextCallSeq();<a
name="line.2546"></a>
-<span class="sourceLineNo">2547</span> }<a name="line.2547"></a>
-<span class="sourceLineNo">2548</span> }<a name="line.2548"></a>
-<span class="sourceLineNo">2549</span> try {<a name="line.2549"></a>
-<span class="sourceLineNo">2550</span> // Remove lease while its
being processed in server; protects against case<a name="line.2550"></a>
-<span class="sourceLineNo">2551</span> // where processing of request
takes > lease expiration time.<a name="line.2551"></a>
-<span class="sourceLineNo">2552</span> lease =
regionServer.leases.removeLease(scannerName);<a name="line.2552"></a>
-<span class="sourceLineNo">2553</span> List<Result> results =
new ArrayList<Result>();<a name="line.2553"></a>
-<span class="sourceLineNo">2554</span><a name="line.2554"></a>
-<span class="sourceLineNo">2555</span> boolean done = false;<a
name="line.2555"></a>
-<span class="sourceLineNo">2556</span> // Call coprocessor. Get
region info from scanner.<a name="line.2556"></a>
-<span class="sourceLineNo">2557</span> if (region != null &&
region.getCoprocessorHost() != null) {<a name="line.2557"></a>
-<span class="sourceLineNo">2558</span> Boolean bypass =
region.getCoprocessorHost().preScannerNext(<a name="line.2558"></a>
-<span class="sourceLineNo">2559</span> scanner, results, rows);<a
name="line.2559"></a>
-<span class="sourceLineNo">2560</span> if (!results.isEmpty()) {<a
name="line.2560"></a>
-<span class="sourceLineNo">2561</span> for (Result r : results)
{<a name="line.2561"></a>
-<span class="sourceLineNo">2562</span> lastBlock =
addSize(context, r, lastBlock);<a name="line.2562"></a>
-<span class="sourceLineNo">2563</span> }<a name="line.2563"></a>
-<span class="sourceLineNo">2564</span> }<a name="line.2564"></a>
-<span class="sourceLineNo">2565</span> if (bypass != null
&& bypass.booleanValue()) {<a name="line.2565"></a>
-<span class="sourceLineNo">2566</span> done = true;<a
name="line.2566"></a>
+<span class="sourceLineNo">2533</span> quota =
getQuotaManager().checkQuota(region, OperationQuota.OperationType.SCAN);<a
name="line.2533"></a>
+<span class="sourceLineNo">2534</span> long maxQuotaResultSize =
Math.min(maxScannerResultSize, quota.getReadAvailable());<a
name="line.2534"></a>
+<span class="sourceLineNo">2535</span><a name="line.2535"></a>
+<span class="sourceLineNo">2536</span> if (rows > 0) {<a
name="line.2536"></a>
+<span class="sourceLineNo">2537</span> // if nextCallSeq does not match
throw Exception straight away. This needs to be<a name="line.2537"></a>
+<span class="sourceLineNo">2538</span> // performed even before
checking of Lease.<a name="line.2538"></a>
+<span class="sourceLineNo">2539</span> // See HBASE-5974<a
name="line.2539"></a>
+<span class="sourceLineNo">2540</span> if (request.hasNextCallSeq())
{<a name="line.2540"></a>
+<span class="sourceLineNo">2541</span> if (rsh != null) {<a
name="line.2541"></a>
+<span class="sourceLineNo">2542</span> if (request.getNextCallSeq()
!= rsh.getNextCallSeq()) {<a name="line.2542"></a>
+<span class="sourceLineNo">2543</span> throw new
OutOfOrderScannerNextException(<a name="line.2543"></a>
+<span class="sourceLineNo">2544</span> "Expected nextCallSeq: "
+ rsh.getNextCallSeq()<a name="line.2544"></a>
+<span class="sourceLineNo">2545</span> + " But the nextCallSeq
got from client: " + request.getNextCallSeq() +<a name="line.2545"></a>
+<span class="sourceLineNo">2546</span> "; request=" +
TextFormat.shortDebugString(request));<a name="line.2546"></a>
+<span class="sourceLineNo">2547</span> }<a name="line.2547"></a>
+<span class="sourceLineNo">2548</span> // Increment the nextCallSeq
value which is the next expected from client.<a name="line.2548"></a>
+<span class="sourceLineNo">2549</span> rsh.incNextCallSeq();<a
name="line.2549"></a>
+<span class="sourceLineNo">2550</span> }<a name="line.2550"></a>
+<span class="sourceLineNo">2551</span> }<a name="line.2551"></a>
+<span class="sourceLineNo">2552</span> try {<a name="line.2552"></a>
+<span class="sourceLineNo">2553</span> // Remove lease while its
being processed in server; protects against case<a name="line.2553"></a>
+<span class="sourceLineNo">2554</span> // where processing of request
takes > lease expiration time.<a name="line.2554"></a>
+<span class="sourceLineNo">2555</span> lease =
regionServer.leases.removeLease(scannerName);<a name="line.2555"></a>
+<span class="sourceLineNo">2556</span> List<Result> results =
new ArrayList<Result>();<a name="line.2556"></a>
+<span class="sourceLineNo">2557</span><a name="line.2557"></a>
+<span class="sourceLineNo">2558</span> boolean done = false;<a
name="line.2558"></a>
+<span class="sourceLineNo">2559</span> // Call coprocessor. Get
region info from scanner.<a name="line.2559"></a>
+<span class="sourceLineNo">2560</span> if (region != null &&
region.getCoprocessorHost() != null) {<a name="line.2560"></a>
+<span class="sourceLineNo">2561</span> Boolean bypass =
region.getCoprocessorHost().preScannerNext(<a name="line.2561"></a>
+<span class="sourceLineNo">2562</span> scanner, results, rows);<a
name="line.2562"></a>
+<span class="sourceLineNo">2563</span> if (!results.isEmpty()) {<a
name="line.2563"></a>
+<span class="sourceLineNo">2564</span> for (Result r : results)
{<a name="line.2564"></a>
+<span class="sourceLineNo">2565</span> lastBlock =
addSize(context, r, lastBlock);<a name="line.2565"></a>
+<span class="sourceLineNo">2566</span> }<a name="line.2566"></a>
<span class="sourceLineNo">2567</span> }<a name="line.2567"></a>
-<span class="sourceLineNo">2568</span> }<a name="line.2568"></a>
-<span class="sourceLineNo">2569</span><a name="line.2569"></a>
-<span class="sourceLineNo">2570</span> if (!done) {<a
name="line.2570"></a>
-<span class="sourceLineNo">2571</span> long maxResultSize =
Math.min(scanner.getMaxResultSize(), maxQuotaResultSize);<a
name="line.2571"></a>
-<span class="sourceLineNo">2572</span> if (maxResultSize <= 0)
{<a name="line.2572"></a>
-<span class="sourceLineNo">2573</span> maxResultSize =
maxQuotaResultSize;<a name="line.2573"></a>
-<span class="sourceLineNo">2574</span> }<a name="line.2574"></a>
-<span class="sourceLineNo">2575</span> // This is cells inside a
row. Default size is 10 so if many versions or many cfs,<a name="line.2575"></a>
-<span class="sourceLineNo">2576</span> // then we'll resize.
Resizings show in profiler. Set it higher than 10. For now<a
name="line.2576"></a>
-<span class="sourceLineNo">2577</span> // arbitrary 32. TODO: keep
record of general size of results being returned.<a name="line.2577"></a>
-<span class="sourceLineNo">2578</span> List<Cell> values =
new ArrayList<Cell>(32);<a name="line.2578"></a>
-<span class="sourceLineNo">2579</span>
region.startRegionOperation(Operation.SCAN);<a name="line.2579"></a>
-<span class="sourceLineNo">2580</span> try {<a name="line.2580"></a>
-<span class="sourceLineNo">2581</span> int i = 0;<a
name="line.2581"></a>
-<span class="sourceLineNo">2582</span> synchronized(scanner) {<a
name="line.2582"></a>
-<span class="sourceLineNo">2583</span> boolean stale =
(region.getRegionInfo().getReplicaId() != 0);<a name="line.2583"></a>
-<span class="sourceLineNo">2584</span> boolean
clientHandlesPartials =<a name="line.2584"></a>
-<span class="sourceLineNo">2585</span>
request.hasClientHandlesPartials() &&
request.getClientHandlesPartials();<a name="line.2585"></a>
-<span class="sourceLineNo">2586</span> boolean
clientHandlesHeartbeats =<a name="line.2586"></a>
-<span class="sourceLineNo">2587</span>
request.hasClientHandlesHeartbeats() &&
request.getClientHandlesHeartbeats();<a name="line.2587"></a>
-<span class="sourceLineNo">2588</span><a name="line.2588"></a>
-<span class="sourceLineNo">2589</span> // On the server side we
must ensure that the correct ordering of partial results is<a
name="line.2589"></a>
-<span class="sourceLineNo">2590</span> // returned to the
client to allow them to properly reconstruct the partial results.<a
name="line.2590"></a>
-<span class="sourceLineNo">2591</span> // If the coprocessor
host is adding to the result list, we cannot guarantee the<a
name="line.2591"></a>
-<span class="sourceLineNo">2592</span> // correct ordering of
partial results and so we prevent partial results from being<a
name="line.2592"></a>
-<span class="sourceLineNo">2593</span> // formed.<a
name="line.2593"></a>
-<span class="sourceLineNo">2594</span> boolean
serverGuaranteesOrderOfPartials = results.isEmpty();<a name="line.2594"></a>
-<span class="sourceLineNo">2595</span> boolean
allowPartialResults =<a name="line.2595"></a>
-<span class="sourceLineNo">2596</span>
clientHandlesPartials && serverGuaranteesOrderOfPartials &&
!isSmallScan;<a name="line.2596"></a>
-<span class="sourceLineNo">2597</span> boolean moreRows =
false;<a name="line.2597"></a>
-<span class="sourceLineNo">2598</span><a name="line.2598"></a>
-<span class="sourceLineNo">2599</span> // Heartbeat messages
occur when the processing of the ScanRequest is exceeds a<a
name="line.2599"></a>
-<span class="sourceLineNo">2600</span> // certain time
threshold on the server. When the time threshold is exceeded, the<a
name="line.2600"></a>
-<span class="sourceLineNo">2601</span> // server stops the scan
and sends back whatever Results it has accumulated within<a
name="line.2601"></a>
-<span class="sourceLineNo">2602</span> // that time period (may
be empty). Since heartbeat messages have the potential to<a
name="line.2602"></a>
-<span class="sourceLineNo">2603</span> // create partial
Results (in the event that the timeout occurs in the middle of a<a
name="line.2603"></a>
-<span class="sourceLineNo">2604</span> // row), we must only
generate heartbeat messages when the client can handle both<a
name="line.2604"></a>
-<span class="sourceLineNo">2605</span> // heartbeats AND
partials<a name="line.2605"></a>
-<span class="sourceLineNo">2606</span> boolean
allowHeartbeatMessages = clientHandlesHeartbeats &&
allowPartialResults;<a name="line.2606"></a>
-<span class="sourceLineNo">2607</span><a name="line.2607"></a>
-<span class="sourceLineNo">2608</span> // Default value of
timeLimit is negative to indicate no timeLimit should be<a name="line.2608"></a>
-<span class="sourceLineNo">2609</span> // enforced.<a
name="line.2609"></a>
-<span class="sourceLineNo">2610</span> long timeLimit = -1;<a
name="line.2610"></a>
-<span class="sourceLineNo">2611</span><a name="line.2611"></a>
-<span class="sourceLineNo">2612</span> // Set the time limit to
be half of the more restrictive timeout value (one of the<a
name="line.2612"></a>
-<span class="sourceLineNo">2613</span> // timeout values must
be positive). In the event that both values are positive, the<a
name="line.2613"></a>
-<span class="sourceLineNo">2614</span> // more restrictive of
the two is used to calculate the limit.<a name="line.2614"></a>
-<span class="sourceLineNo">2615</span> if
(allowHeartbeatMessages && (scannerLeaseTimeoutPeriod > 0 ||
rpcTimeout > 0)) {<a name="line.2615"></a>
-<span class="sourceLineNo">2616</span> long timeLimitDelta;<a
name="line.2616"></a>
-<span class="sourceLineNo">2617</span> if
(scannerLeaseTimeoutPeriod > 0 && rpcTimeout > 0) {<a
name="line.2617"></a>
-<span class="sourceLineNo">2618</span> timeLimitDelta =
Math.min(scannerLeaseTimeoutPeriod, rpcTimeout);<a name="line.2618"></a>
-<span class="sourceLineNo">2619</span> } else {<a
name="line.2619"></a>
-<span class="sourceLineNo">2620</span> timeLimitDelta =<a
name="line.2620"></a>
-<span class="sourceLineNo">2621</span>
scannerLeaseTimeoutPeriod > 0 ? scannerLeaseTimeoutPeriod : rpcTimeout;<a
name="line.2621"></a>
-<span class="sourceLineNo">2622</span> }<a
name="line.2622"></a>
-<span class="sourceLineNo">2623</span> // Use half of
whichever timeout value was more restrictive... But don't allow<a
name="line.2623"></a>
-<span class="sourceLineNo">2624</span> // the time limit to
be less than the allowable minimum (could cause an<a name="line.2624"></a>
-<span class="sourceLineNo">2625</span> // immediatate timeout
before scanning any data).<a name="line.2625"></a>
-<span class="sourceLineNo">2626</span> timeLimitDelta =
Math.max(timeLimitDelta / 2, minimumScanTimeLimitDelta);<a name="line.2626"></a>
-<span class="sourceLineNo">2627</span> timeLimit =
System.currentTimeMillis() + timeLimitDelta;<a name="line.2627"></a>
-<span class="sourceLineNo">2628</span> }<a name="line.2628"></a>
-<span class="sourceLineNo">2629</span><a name="line.2629"></a>
-<span class="sourceLineNo">2630</span> final LimitScope
sizeScope =<a name="line.2630"></a>
-<span class="sourceLineNo">2631</span> allowPartialResults
? LimitScope.BETWEEN_CELLS : LimitScope.BETWEEN_ROWS;<a name="line.2631"></a>
-<span class="sourceLineNo">2632</span> final LimitScope
timeScope =<a name="line.2632"></a>
-<span class="sourceLineNo">2633</span>
allowHeartbeatMessages ? LimitScope.BETWEEN_CELLS : LimitScope.BETWEEN_ROWS;<a
name="line.2633"></a>
-<span class="sourceLineNo">2634</span><a name="line.2634"></a>
-<span class="sourceLineNo">2635</span> boolean trackMetrics =<a
name="line.2635"></a>
-<span class="sourceLineNo">2636</span>
request.hasTrackScanMetrics() && request.getTrackScanMetrics();<a
name="line.2636"></a>
+<span class="sourceLineNo">2568</span> if (bypass != null
&& bypass.booleanValue()) {<a name="line.2568"></a>
+<span class="sourceLineNo">2569</span> done = true;<a
name="line.2569"></a>
+<span class="sourceLineNo">2570</span> }<a name="line.2570"></a>
+<span class="sourceLineNo">2571</span> }<a name="line.2571"></a>
+<span class="sourceLineNo">2572</span><a name="line.2572"></a>
+<span class="sourceLineNo">2573</span> if (!done) {<a
name="line.2573"></a>
+<span class="sourceLineNo">2574</span> long maxResultSize =
Math.min(scanner.getMaxResultSize(), maxQuotaResultSize);<a
name="line.2574"></a>
+<span class="sourceLineNo">2575</span> if (maxResultSize <= 0)
{<a name="line.2575"></a>
+<span class="sourceLineNo">2576</span> maxResultSize =
maxQuotaResultSize;<a name="line.2576"></a>
+<span class="sourceLineNo">2577</span> }<a name="line.2577"></a>
+<span class="sourceLineNo">2578</span> // This is cells inside a
row. Default size is 10 so if many versions or many cfs,<a name="line.2578"></a>
+<span class="sourceLineNo">2579</span> // then we'll resize.
Resizings show in profiler. Set it higher than 10. For now<a
name="line.2579"></a>
+<span class="sourceLineNo">2580</span> // arbitrary 32. TODO: keep
record of general size of results being returned.<a name="line.2580"></a>
+<span class="sourceLineNo">2581</span> List<Cell> values =
new ArrayList<Cell>(32);<a name="line.2581"></a>
+<span class="sourceLineNo">2582</span>
region.startRegionOperation(Operation.SCAN);<a name="line.2582"></a>
+<span class="sourceLineNo">2583</span> try {<a name="line.2583"></a>
+<span class="sourceLineNo">2584</span> int i = 0;<a
name="line.2584"></a>
+<span class="sourceLineNo">2585</span> synchronized(scanner) {<a
name="line.2585"></a>
+<span class="sourceLineNo">2586</span> boolean stale =
(region.getRegionInfo().getReplicaId() != 0);<a name="line.2586"></a>
+<span class="sourceLineNo">2587</span> boolean
clientHandlesPartials =<a name="line.2587"></a>
+<span class="sourceLineNo">2588</span>
request.hasClientHandlesPartials() &&
request.getClientHandlesPartials();<a name="line.2588"></a>
+<span class="sourceLineNo">2589</span> boolean
clientHandlesHeartbeats =<a name="line.2589"></a>
+<span class="sourceLineNo">2590</span>
request.hasClientHandlesHeartbeats() &&
request.getClientHandlesHeartbeats();<a name="line.2590"></a>
+<span class="sourceLineNo">2591</span><a name="line.2591"></a>
+<span class="sourceLineNo">2592</span> // On the server side we
must ensure that the correct ordering of partial results is<a
name="line.2592"></a>
+<span class="sourceLineNo">2593</span> // returned to the
client to allow them to properly reconstruct the partial results.<a
name="line.2593"></a>
+<span class="sourceLineNo">2594</span> // If the coprocessor
host is adding to the result list, we cannot guarantee the<a
name="line.2594"></a>
+<span class="sourceLineNo">2595</span> // correct ordering of
partial results and so we prevent partial results from being<a
name="line.2595"></a>
+<span class="sourceLineNo">2596</span> // formed.<a
name="line.2596"></a>
+<span class="sourceLineNo">2597</span> boolean
serverGuaranteesOrderOfPartials = results.isEmpty();<a name="line.2597"></a>
+<span class="sourceLineNo">2598</span> boolean
allowPartialResults =<a name="line.2598"></a>
+<span class="sourceLineNo">2599</span>
clientHandlesPartials && serverGuaranteesOrderOfPartials &&
!isSmallScan;<a name="line.2599"></a>
+<span class="sourceLineNo">2600</span> boolean moreRows =
false;<a name="line.2600"></a>
+<span class="sourceLineNo">2601</span><a name="line.2601"></a>
+<span class="sourceLineNo">2602</span> // Heartbeat messages
occur when the processing of the ScanRequest is exceeds a<a
name="line.2602"></a>
+<span class="sourceLineNo">2603</span> // certain time
threshold on the server. When the time threshold is exceeded, the<a
name="line.2603"></a>
+<span class="sourceLineNo">2604</span> // server stops the scan
and sends back whatever Results it has accumulated within<a
name="line.2604"></a>
+<span class="sourceLineNo">2605</span> // that time period (may
be empty). Since heartbeat messages have the potential to<a
name="line.2605"></a>
+<span class="sourceLineNo">2606</span> // create partial
Results (in the event that the timeout occurs in the middle of a<a
name="line.2606"></a>
+<span class="sourceLineNo">2607</span> // row), we must only
generate heartbeat messages when the client can handle both<a
name="line.2607"></a>
+<span class="sourceLineNo">2608</span> // heartbeats AND
partials<a name="line.2608"></a>
+<span class="sourceLineNo">2609</span> boolean
allowHeartbeatMessages = clientHandlesHeartbeats &&
allowPartialResults;<a name="line.2609"></a>
+<span class="sourceLineNo">2610</span><a name="line.2610"></a>
+<span class="sourceLineNo">2611</span> // Default value of
timeLimit is negative to indicate no timeLimit should be<a name="line.2611"></a>
+<span class="sourceLineNo">2612</span> // enforced.<a
name="line.2612"></a>
+<span class="sourceLineNo">2613</span> long timeLimit = -1;<a
name="line.2613"></a>
+<span class="sourceLineNo">2614</span><a name="line.2614"></a>
+<span class="sourceLineNo">2615</span> // Set the time limit to
be half of the more restrictive timeout value (one of the<a
name="line.2615"></a>
+<span class="sourceLineNo">2616</span> // timeout values must
be positive). In the event that both values are positive, the<a
name="line.2616"></a>
+<span class="sourceLineNo">2617</span> // more restrictive of
the two is used to calculate the limit.<a name="line.2617"></a>
+<span class="sourceLineNo">2618</span> if
(allowHeartbeatMessages && (scannerLeaseTimeoutPeriod > 0 ||
rpcTimeout > 0)) {<a name="line.2618"></a>
+<span class="sourceLineNo">2619</span> long timeLimitDelta;<a
name="line.2619"></a>
+<span class="sourceLineNo">2620</span> if
(scannerLeaseTimeoutPeriod > 0 && rpcTimeout > 0) {<a
name="line.2620"></a>
+<span class="sourceLineNo">2621</span> timeLimitDelta =
Math.min(scannerLeaseTimeoutPeriod, rpcTimeout);<a name="line.2621"></a>
+<span class="sourceLineNo">2622</span> } else {<a
name="line.2622"></a>
+<span class="sourceLineNo">2623</span> timeLimitDelta =<a
name="line.2623"></a>
+<span class="sourceLineNo">2624</span>
scannerLeaseTimeoutPeriod > 0 ? scannerLeaseTimeoutPeriod : rpcTimeout;<a
name="line.2624"></a>
+<span class="sourceLineNo">2625</span> }<a
name="line.2625"></a>
+<span class="sourceLineNo">2626</span> // Use half of
whichever timeout value was more restrictive... But don't allow<a
name="line.2626"></a>
+<span class="sourceLineNo">2627</span> // the time limit to
be less than the allowable minimum (could cause an<a name="line.2627"></a>
+<span class="sourceLineNo">2628</span> // immediatate timeout
before scanning any data).<a name="line.2628"></a>
+<span class="sourceLineNo">2629</span> timeLimitDelta =
Math.max(timeLimitDelta / 2, minimumScanTimeLimitDelta);<a name="line.2629"></a>
+<span class="sourceLineNo">2630</span> timeLimit =
System.currentTimeMillis() + timeLimitDelta;<a name="line.2630"></a>
+<span class="sourceLineNo">2631</span> }<a name="line.2631"></a>
+<span class="sourceLineNo">2632</span><a name="line.2632"></a>
+<span class="sourceLineNo">2633</span> final LimitScope
sizeScope =<a name="line.2633"></a>
+<span class="sourceLineNo">2634</span> allowPartialResults
? LimitScope.BETWEEN_CELLS : LimitScope.BETWEEN_ROWS;<a name="line.2634"></a>
+<span class="sourceLineNo">2635</span> final LimitScope
timeScope =<a name="line.2635"></a>
+<span class="sourceLineNo">2636</span>
allowHeartbeatMessages ? LimitScope.BETWEEN_CELLS : LimitScope.BETWEEN_ROWS;<a
name="line.2636"></a>
<span class="sourceLineNo">2637</span><a name="line.2637"></a>
-<span class="sourceLineNo">2638</span> // Configure with limits
for this RPC. Set keep progress true since size progress<a name="line.2638"></a>
-<span class="sourceLineNo">2639</span> // towards size limit
should be kept between calls to nextRaw<a name="line.2639"></a>
-<span class="sourceLineNo">2640</span> ScannerContext.Builder
contextBuilder = ScannerContext.newBuilder(true);<a name="line.2640"></a>
-<span class="sourceLineNo">2641</span>
contextBuilder.setSizeLimit(sizeScope, maxResultSize);<a name="line.2641"></a>
-<span class="sourceLineNo">2642</span>
contextBuilder.setBatchLimit(scanner.getBatch());<a name="line.2642"></a>
-<span class="sourceLineNo">2643</span>
contextBuilder.setTimeLimit(timeScope, timeLimit);<a name="line.2643"></a>
-<span class="sourceLineNo">2644</span>
contextBuilder.setTrackMetrics(trackMetrics);<a name="line.2644"></a>
-<span class="sourceLineNo">2645</span> ScannerContext
scannerContext = contextBuilder.build();<a name="line.2645"></a>
-<span class="sourceLineNo">2646</span> boolean limitReached =
false;<a name="line.2646"></a>
-<span class="sourceLineNo">2647</span> while (i < rows) {<a
name="line.2647"></a>
-<span class="sourceLineNo">2648</span> // Reset the batch
progress to 0 before every call to RegionScanner#nextRaw. The<a
name="line.2648"></a>
-<span class="sourceLineNo">2649</span> // batch limit is a
limit on the number of cells per Result. Thus, if progress is<a
name="line.2649"></a>
-<span class="sourceLineNo">2650</span> // being tracked (i.e.
scannerContext.keepProgress() is true) then we need to<a name="line.2650"></a>
-<span class="sourceLineNo">2651</span> // reset the batch
progress between nextRaw invocations since we don't want the<a
name="line.2651"></a>
-<span class="sourceLineNo">2652</span> // batch progress from
previous calls to affect future calls<a name="line.2652"></a>
-<span class="sourceLineNo">2653</span>
scannerContext.setBatchProgress(0);<a name="line.2653"></a>
-<span class="sourceLineNo">2654</span><a name="line.2654"></a>
-<span class="sourceLineNo">2655</span> // Collect values to
be returned here<a name="line.2655"></a>
-<span class="sourceLineNo">2656</span> moreRows =
scanner.nextRaw(values, scannerContext);<a name="line.2656"></a>
+<span class="sourceLineNo">2638</span> boolean trackMetrics =<a
name="line.2638"></a>
+<span class="sourceLineNo">2639</span>
request.hasTrackScanMetrics() && request.getTrackScanMetrics();<a
name="line.2639"></a>
+<span class="sourceLineNo">2640</span><a name="line.2640"></a>
+<span class="sourceLineNo">2641</span> // Configure with limits
for this RPC. Set keep progress true since size progress<a name="line.2641"></a>
+<span class="sourceLineNo">2642</span> // towards size limit
should be kept between calls to nextRaw<a name="line.2642"></a>
+<span class="sourceLineNo">2643</span> ScannerContext.Builder
contextBuilder = ScannerContext.newBuilder(true);<a name="line.2643"></a>
+<span class="sourceLineNo">2644</span>
contextBuilder.setSizeLimit(sizeScope, maxResultSize);<a name="line.2644"></a>
+<span class="sourceLineNo">2645</span>
contextBuilder.setBatchLimit(scanner.getBatch());<a name="line.2645"></a>
+<span class="sourceLineNo">2646</span>
contextBuilder.setTimeLimit(timeScope, timeLimit);<a name="line.2646"></a>
+<span class="sourceLineNo">2647</span>
contextBuilder.setTrackMetrics(trackMetrics);<a name="line.2647"></a>
+<span class="sourceLineNo">2648</span> ScannerContext
scannerContext = contextBuilder.build();<a name="line.2648"></a>
+<span class="sourceLineNo">2649</span> boolean limitReached =
false;<a name="line.2649"></a>
+<span class="sourceLineNo">2650</span> while (i < rows) {<a
name="line.2650"></a>
+<span class="sourceLineNo">2651</span> // Reset the batch
progress to 0 before every call to RegionScanner#nextRaw. The<a
name="line.2651"></a>
+<span class="sourceLineNo">2652</span> // batch limit is a
limit on the number of cells per Result. Thus, if progress is<a
name="line.2652"></a>
+<span class="sourceLineNo">2653</span> // being tracked (i.e.
scannerContext.keepProgress() is true) then we need to<a name="line.2653"></a>
+<span class="sourceLineNo">2654</span> // reset the batch
progress between nextRaw invocations since we don't want the<a
name="line.2654"></a>
+<span class="sourceLineNo">2655</span> // batch progress from
previous calls to affect future calls<a name="line.2655"></a>
+<span class="sourceLineNo">2656</span>
scannerContext.setBatchProgress(0);<a name="line.2656"></a>
<span class="sourceLineNo">2657</span><a name="line.2657"></a>
-<span class="sourceLineNo">2658</span> if (!values.isEmpty())
{<a name="line.2658"></a>
-<span class="sourceLineNo">2659</span> final boolean
partial = scannerContext.partialResultFormed();<a name="line.2659"></a>
-<span class="sourceLineNo">2660</span> Result r =
Result.create(values, null, stale, partial);<a name="line.2660"></a>
-<span class="sourceLineNo">2661</span> lastBlock =
addSize(context, r, lastBlock);<a name="line.2661"></a>
-<span class="sourceLineNo">2662</span> results.add(r);<a
name="line.2662"></a>
-<span class="sourceLineNo">2663</span> i++;<a
name="line.2663"></a>
-<span class="sourceLineNo">2664</span> }<a
name="line.2664"></a>
-<span class="sourceLineNo">2665</span><a name="line.2665"></a>
-<span class="sourceLineNo">2666</span> boolean
sizeLimitReached = scannerContext.checkSizeLimit(LimitScope.BETWEEN_ROWS);<a
name="line.2666"></a>
-<span class="sourceLineNo">2667</span> boolean
timeLimitReached = scannerContext.checkTimeLimit(LimitScope.BETWEEN_ROWS);<a
name="line.2667"></a>
-<span class="sourceLineNo">2668</span> boolean
rowLimitReached = i >= rows;<a name="line.2668"></a>
-<span class="sourceLineNo">2669</span> limitReached =
sizeLimitReached || timeLimitReached || rowLimitReached;<a name="line.2669"></a>
-<span class="sourceLineNo">2670</span><a name="line.2670"></a>
-<span class="sourceLineNo">2671</span> if (limitReached ||
!moreRows) {<a name="line.2671"></a>
-<span class="sourceLineNo">2672</span> if
(LOG.isTraceEnabled()) {<a name="line.2672"></a>
-<span class="sourceLineNo">2673</span> LOG.trace("Done
scanning. limitReached: " + limitReached + " moreRows: "<a name="line.2673"></a>
-<span class="sourceLineNo">2674</span> + moreRows + "
scannerContext: " + scannerContext);<a name="line.2674"></a>
-<span class="sourceLineNo">2675</span> }<a
name="line.2675"></a>
-<span class="sourceLineNo">2676</span> // We only want to
mark a ScanResponse as a heartbeat message in the event that<a
name="line.2676"></a>
-<span class="sourceLineNo">2677</span> // there are more
values to be read server side. If there aren't more values,<a
name="line.2677"></a>
-<span class="sourceLineNo">2678</span> // marking it as a
heartbeat is wasteful because the client will need to issue<a
name="line.2678"></a>
-<span class="sourceLineNo">2679</span> // another
ScanRequest only to realize that they already have all the values<a
name="line.2679"></a>
-<span class="sourceLineNo">2680</span> if (moreRows) {<a
name="line.2680"></a>
-<span class="sourceLineNo">2681</span> // Heartbeat
messages occur when the time limit has been reached.<a name="line.2681"></a>
-<span class="sourceLineNo">2682</span>
builder.setHeartbeatMessage(timeLimitReached);<a name="line.2682"></a>
-<span class="sourceLineNo">2683</span> }<a
name="line.2683"></a>
-<span class="sourceLineNo">2684</span> break;<a
name="line.2684"></a>
-<span class="sourceLineNo">2685</span> }<a
name="line.2685"></a>
-<span class="sourceLineNo">2686</span> values.clear();<a
name="line.2686"></a>
-<span class="sourceLineNo">2687</span> }<a name="line.2687"></a>
-<span class="sourceLineNo">2688</span><a name="line.2688"></a>
-<span class="sourceLineNo">2689</span> if (limitReached ||
moreRows) {<a name="line.2689"></a>
-<span class="sourceLineNo">2690</span> // We stopped
prematurely<a name="line.2690"></a>
-<span class="sourceLineNo">2691</span>
builder.setMoreResultsInRegion(true);<a name="line.2691"></a>
-<span class="sourceLineNo">2692</span> } else {<a
name="line.2692"></a>
-<span class="sourceLineNo">2693</span> // We didn't get a
single batch<a name="line.2693"></a>
-<span class="sourceLineNo">2694</span>
builder.setMoreResultsInRegion(false);<a name="line.2694"></a>
-<span class="sourceLineNo">2695</span> }<a name="line.2695"></a>
-<span class="sourceLineNo">2696</span><a name="line.2696"></a>
-<span class="sourceLineNo">2697</span> // Check to see if the
client requested that we track metrics server side. If the<a
name="line.2697"></a>
-<span class="sourceLineNo">2698</span> // client requested
metrics, retrieve the metrics from the scanner context.<a name="line.2698"></a>
-<span class="sourceLineNo">2699</span> if (trackMetrics) {<a
name="line.2699"></a>
-<span class="sourceLineNo">2700</span> Map<String,
Long> metrics = scannerContext.getMetrics().getMetricsMap();<a
name="line.2700"></a>
-<span class="sourceLineNo">2701</span> ScanMetrics.Builder
metricBuilder = ScanMetrics.newBuilder();<a name="line.2701"></a>
-<span class="sourceLineNo">2702</span> NameInt64Pair.Builder
pairBuilder = NameInt64Pair.newBuilder();<a name="line.2702"></a>
-<span class="sourceLineNo">2703</span><a name="line.2703"></a>
-<span class="sourceLineNo">2704</span> for (Entry<String,
Long> entry : metrics.entrySet()) {<a name="line.2704"></a>
-<span class="sourceLineNo">2705</span>
pairBuilder.setName(entry.getKey());<a name="line.2705"></a>
-<span class="sourceLineNo">2706</span>
pairBuilder.setValue(entry.getValue());<a name="line.2706"></a>
-<span class="sourceLineNo">2707</span>
metricBuilder.addMetrics(pairBuilder.build());<a name="line.2707"></a>
-<span class="sourceLineNo">2708</span> }<a
name="line.2708"></a>
-<span class="sourceLineNo">2709</span><a name="line.2709"></a>
-<span class="sourceLineNo">2710</span>
builder.setScanMetrics(metricBuilder.build());<a name="line.2710"></a>
-<span class="sourceLineNo">2711</span> }<a name="line.2711"></a>
-<span class="sourceLineNo">2712</span> }<a name="line.2712"></a>
-<span class="sourceLineNo">2713</span>
region.updateReadRequestsCount(i);<a name="line.2713"></a>
-<span class="sourceLineNo">2714</span> long responseCellSize =
context != null ? context.getResponseCellSize() : 0;<a name="line.2714"></a>
-<span class="sourceLineNo">2715</span>
region.getMetrics().updateScanNext(responseCellSize);<a name="line.2715"></a>
-<span class="sourceLineNo">2716</span> if
(regionServer.metricsRegionServer != null) {<a name="line.2716"></a>
-<span class="sourceLineNo">2717</span>
regionServer.metricsRegionServer.updateScannerNext(responseCellSize);<a
name="line.2717"></a>
-<span class="sourceLineNo">2718</span> }<a name="line.2718"></a>
-<span class="sourceLineNo">2719</span> } finally {<a
name="line.2719"></a>
-<span class="sourceLineNo">2720</span>
region.closeRegionOperation();<a name="line.2720"></a>
-<span class="sourceLineNo">2721</span> }<a name="line.2721"></a>
-<span class="sourceLineNo">2722</span> // coprocessor postNext
hook<a name="line.2722"></a>
-<span class="sourceLineNo">2723</span> if (region != null
&& region.getCoprocessorHost() != null) {<a name="line.2723"></a>
-<span class="sourceLineNo">2724</span>
region.getCoprocessorHost().postScannerNext(scanner, results, rows, true);<a
name="line.2724"></a>
-<span class="sourceLineNo">2725</span> }<a name="line.2725"></a>
-<span class="sourceLineNo">2726</span> }<a name="line.2726"></a>
-<span class="sourceLineNo">2727</span><a name="line.2727"></a>
-<span class="sourceLineNo">2728</span>
quota.addScanResult(results);<a name="line.2728"></a>
-<span class="sourceLineNo">2729</span><a name="line.2729"></a>
-<span class="sourceLineNo">2730</span> // If the scanner's filter -
if any - is done with the scan<a name="line.2730"></a>
-<span class="sourceLineNo">2731</span> // and wants to tell the
client to stop the scan. This is done by passing<a name="line.2731"></a>
-<span class="sourceLineNo">2732</span> // a null result, and setting
moreResults to false.<a name="line.2732"></a>
-<span class="sourceLineNo">2733</span> if (scanner.isFilterDone()
&& results.isEmpty()) {<a name="line.2733"></a>
-<span class="sourceLineNo">2734</span> moreResults = false;<a
name="line.2734"></a>
-<span class="sourceLineNo">2735</span> results = null;<a
name="line.2735"></a>
-<span class="sourceLineNo">2736</span> } else {<a
name="line.2736"></a>
-<span class="sourceLineNo">2737</span> addResults(builder, results,
controller,<a name="line.2737"></a>
-<span class="sourceLineNo">2738</span>
RegionReplicaUtil.isDefaultReplica(region.getRegionInfo()),<a
name="line.2738"></a>
-<span class="sourceLineNo">2739</span>
isClientCellBlockSupport(context));<a name="line.2739"></a>
-<span class="sourceLineNo">2740</span> }<a name="line.2740"></a>
-<span class="sourceLineNo">2741</span> } catch (IOException e) {<a
name="line.2741"></a>
-<span class="sourceLineNo">2742</span> // if we have an exception on
scanner next and we are using the callSeq<a name="line.2742"></a>
-<span class="sourceLineNo">2743</span> // we should rollback because
the client will retry with the same callSeq<a name="line.2743"></a>
-<span class="sourceLineNo">2744</span> // and get an
OutOfOrderScannerNextException if we don't do so.<a name="line.2744"></a>
-<span class="sourceLineNo">2745</span> if (rsh != null &&
request.hasNextCallSeq()) {<a name="line.2745"></a>
-<span class="sourceLineNo">2746</span> rsh.rollbackNextCallSeq();<a
name="line.2746"></a>
-<span class="sourceLineNo">2747</span> }<a name="line.2747"></a>
-<span class="sourceLineNo">2748</span> throw e;<a
name="line.2748"></a>
-<span class="sourceLineNo">2749</span> } finally {<a
name="line.2749"></a>
-<span class="sourceLineNo">2750</span> if (context != null) {<a
name="line.2750"></a>
-<span class="sourceLineNo">2751</span>
context.setCallBack(rsh.shippedCallback);<a name="line.2751"></a>
-<span class="sourceLineNo">2752</span> }<a name="line.2752"></a>
-<span class="sourceLineNo">2753</span> // Adding resets expiration
time on lease.<a name="line.2753"></a>
-<span class="sourceLineNo">2754</span> if
(scanners.containsKey(scannerName)) {<a name="line.2754"></a>
-<span class="sourceLineNo">2755</span> ttl =
this.scannerLeaseTimeoutPeriod;<a name="line.2755"></a>
-<span class="sourceLineNo">2756</span> // When context != null,
adding back the lease will be done in callback set above.<a
name="line.2756"></a>
-<span class="sourceLineNo">2757</span> if (context == null) {<a
name="line.2757"></a>
-<span class="sourceLineNo">2758</span> if (lease != null)
regionServer.leases.addLease(lease);<a name="line.2758"></a>
-<span class="sourceLineNo">2759</span> }<a name="line.2759"></a>
-<span class="sourceLineNo">2760</span> }<a name="line.2760"></a>
-<span class="sourceLineNo">2761</span> }<a name="line.2761"></a>
-<span class="sourceLineNo">2762</span> }<a name="line.2762"></a>
-<span class="sourceLineNo">2763</span><a name="line.2763"></a>
-<span class="sourceLineNo">2764</span> if (!moreResults || closeScanner)
{<a name="line.2764"></a>
-<span class="sourceLineNo">2765</span> ttl = 0;<a name="line.2765"></a>
-<span class="sourceLineNo">2766</span> moreResults = false;<a
name="line.2766"></a>
-<span class="sourceLineNo">2767</span> if (region != null &&
region.getCoprocessorHost() != null) {<a name="line.2767"></a>
-<span class="sourceLineNo">2768</span> if
(region.getCoprocessorHost().preScannerClose(scanner)) {<a name="line.2768"></a>
-<span class="sourceLineNo">2769</span> return builder.build(); //
bypass<a name="line.2769"></a>
-<span class="sourceLineNo">2770</span> }<a name="line.2770"></a>
-<span class="sourceLineNo">2771</span> }<a name="line.2771"></a>
-<span class="sourceLineNo">2772</span> rsh =
scanners.remove(scannerName);<a name="line.2772"></a>
-<span class="sourceLineNo">2773</span> if (rsh != null) {<a
name="line.2773"></a>
-<span class="sourceLineNo">2774</span> if (context != null) {<a
name="line.2774"></a>
-<span class="sourceLineNo">2775</span>
context.setCallBack(rsh.closeCallBack);<a name="line.2775"></a>
-<span class="sourceLineNo">2776</span> } else {<a
name="line.2776"></a>
-<span class="sourceLineNo">2777</span> rsh.s.close();<a
name="line.2777"></a>
-<span class="sourceLineNo">2778</span> }<a name="line.2778"></a>
-<span class="sourceLineNo">2779</span> try {<a name="line.2779"></a>
-<span class="sourceLineNo">2780</span>
regionServer.leases.cancelLease(scannerName);<a name="line.2780"></a>
-<span class="sourceLineNo">2781</span> } catch (LeaseException le)
{<a name="line.2781"></a>
-<span class="sourceLineNo">2782</span> // No problem, ignore<a
name="line.2782"></a>
-<span class="sourceLineNo">2783</span> if (LOG.isTraceEnabled())
{<a name="line.2783"></a>
-<span class="sourceLineNo">2784</span> LOG.trace("Un-able to
cancel lease of scanner. It could already be closed.");<a name="line.2784"></a>
-<span class="sourceLineNo">2785</span> }<a name="line.2785"></a>
-<span class="sourceLineNo">2786</span> }<a name="line.2786"></a>
-<span class="sourceLineNo">2787</span> if (region != null &&
region.getCoprocessorHost() != null) {<a name="line.2787"></a>
-<span class="sourceLineNo">2788</span>
region.getCoprocessorHost().postScannerClose(scanner);<a name="line.2788"></a>
+<span class="sourceLineNo">2658</span> // Collect values to
be returned here<a name="line.2658"></a>
+<span class="sourceLineNo">2659</span> moreRows =
scanner.nextRaw(values, scannerContext);<a name="line.2659"></a>
+<span class="sourceLineNo">2660</span><a name="line.2660"></a>
+<span class="sourceLineNo">2661</span> if (!values.isEmpty())
{<a name="line.2661"></a>
+<span class="sourceLineNo">2662</span> final boolean
partial = scannerContext.partialResultFormed();<a name="line.2662"></a>
+<span class="sourceLineNo">2663</span> Result r =
Result.create(values, null, stale, partial);<a name="line.2663"></a>
+<span class="sourceLineNo">2664</span> lastBlock =
addSize(context, r, lastBlock);<a name="line.2664"></a>
+<span class="sourceLineNo">2665</span> results.add(r);<a
name="line.2665"></a>
+<span class="sourceLineNo">2666</span> i++;<a
name="line.2666"></a>
+<span class="sourceLineNo">2667</span> }<a
name="line.2667"></a>
+<span class="sourceLineNo">2668</span><a name="line.2668"></a>
+<span class="sourceLineNo">2669</span> boolean
sizeLimitReached = scannerContext.checkSizeLimit(LimitScope.BETWEEN_ROWS);<a
name="line.2669"></a>
+<span class="sourceLineNo">2670</span> boolean
timeLimitReached = scannerContext.checkTimeLimit(LimitScope.BETWEEN_ROWS);<a
name="line.2670"></a>
+<span class="sourceLineNo">2671</span> boolean
rowLimitReached = i >= rows;<a name="line.2671"></a>
+<span class="sourceLineNo">2672</span> limitReached =
sizeLimitReached || timeLimitReached || rowLimitReached;<a name="line.2672"></a>
+<span class="sourceLineNo">2673</span><a name="line.2673"></a>
+<span class="sourceLineNo">2674</span> if (limitReached ||
!moreRows) {<a name="line.2674"></a>
+<span class="sourceLineNo">2675</span> if
(LOG.isTraceEnabled()) {<a name="line.2675"></a>
+<span class="sourceLineNo">2676</span> LOG.trace("Done
scanning. limitReached: " + limitReached + " moreRows: "<a name="line.2676"></a>
+<span class="sourceLineNo">2677</span> + moreRows + "
scannerContext: " + scannerContext);<a name="line.2677"></a>
+<span class="sourceLineNo">2678</span> }<a
name="line.2678"></a>
+<span class="sourceLineNo">2679</span> // We only want to
mark a ScanResponse as a heartbeat message in the event that<a
name="line.2679"></a>
+<span class="sourceLineNo">2680</span> // there are more
values to be read server side. If there aren't more values,<a
name="line.2680"></a>
+<span class="sourceLineNo">2681</span> // marking it as a
heartbeat is wasteful because the client will need to issue<a
name="line.2681"></a>
+<span class="sourceLineNo">2682</span> // another
ScanRequest only to realize that they already have all the values<a
name="line.2682"></a>
+<span class="sourceLineNo">2683</span> if (moreRows) {<a
name="line.2683"></a>
+<span class="sourceLineNo">2684</span> // Heartbeat
messages occur when the time limit has been reached.<a name="line.2684"></a>
+<span class="sourceLineNo">2685</span>
builder.setHeartbeatMessage(timeLimitReached);<a name="line.2685"></a>
+<span class="sourceLineNo">2686</span> }<a
name="line.2686"></a>
+<span class="sourceLineNo">2687</span> break;<a
name="line.2687"></a>
+<span class="sourceLineNo">2688</span> }<a
name="line.2688"></a>
+<span class="sourceLineNo">2689</span> values.clear();<a
name="line.2689"></a>
+<span class="sourceLineNo">2690</span> }<a name="line.2690"></a>
+<span class="sourceLineNo">2691</span><a name="line.2691"></a>
+<span class="sourceLineNo">2692</span> if (limitReached ||
moreRows) {<a name="line.2692"></a>
+<span class="sourceLineNo">2693</span> // We stopped
prematurely<a name="line.2693"></a>
+<span class="sourceLineNo">2694</span>
builder.setMoreResultsInRegion(true);<a name="line.2694"></a>
+<span class="sourceLineNo">2695</span> } else {<a
name="line.2695"></a>
+<span class="sourceLineNo">2696</span> // We didn't get a
single batch<a name="line.2696"></a>
+<span class="sourceLineNo">2697</span>
builder.setMoreResultsInRegion(false);<a name="line.2697"></a>
+<span class="sourceLineNo">2698</span> }<a name="line.2698"></a>
+<span class="sourceLineNo">2699</span><a name="line.2699"></a>
+<span class="sourceLineNo">2700</span> // Check to see if the
client requested that we track metrics server side. If the<a
name="line.2700"></a>
+<span class="sourceLineNo">2701</span> // client requested
metrics, retrieve the metrics from the scanner context.<a name="line.2701"></a>
+<span class="sourceLineNo">2702</span> if (trackMetrics) {<a
name="line.2702"></a>
+<span class="sourceLineNo">2703</span> Map<String,
Long> metrics = scannerContext.getMetrics().getMetricsMap();<a
name="line.2703"></a>
+<span class="sourceLineNo">2704</span> ScanMetrics.Builder
metricBuilder = ScanMetrics.newBuilder();<a name="line.2704"></a>
+<span class="sourceLineNo">2705</span> NameInt64Pair.Builder
pairBuilder = NameInt64Pair.newBuilder();<a name="line.2705"></a>
+<span class="sourceLineNo">2706</span><a name="line.2706"></a>
+<span class="sourceLineNo">2707</span> for (Entry<String,
Long> entry : metrics.entrySet()) {<a name="line.2707"></a>
+<span class="sourceLineNo">2708</span>
pairBuilder.setName(entry.getKey());<a name="line.2708"></a>
+<span class="sourceLineNo">2709</span>
pairBuilder.setValue(entry.getValue());<a name="line.2709"></a>
+<span class="sourceLineNo">2710</span>
metricBuilder.addMetrics(pairBuilder.build());<a name="line.2710"></a>
+<span class="sourceLineNo">2711</span> }<a
name="line.2711"></a>
+<span class="sourceLineNo">2712</span><a name="line.2712"></a>
+<span class="sourceLineNo">2713</span>
builder.setScanMetrics(metricBuilder.build());<a name="line.2713"></a>
+<span class="sourceLineNo">2714</span> }<a name="line.2714"></a>
+<span class="sourceLineNo">2715</span> }<a name="line.2715"></a>
+<span class="sourceLineNo">2716</span>
region.updateReadRequestsCount(i);<a name="line.2716"></a>
+<span class="sourceLineNo">2717</span> long responseCellSize =
context != null ? context.getResponseCellSize() : 0;<a name="line.2717"></a>
+<span class="sourceLineNo">2718</span>
region.getMetrics().updateScanNext(responseCellSize);<a name="line.2718"></a>
+<span class="sourceLineNo">2719</span> if
(regionServer.metricsRegionServer != null) {<a name="line.2719"></a>
+<span class="sourceLineNo">2720</span>
regionServer.metricsRegionServer.updateScannerNext(responseCellSize);<a
name="line.2720"></a>
+<span class="sourceLineNo">2721</span> }<a name="line.2721"></a>
+<span class="sourceLineNo">2722</span> } finally {<a
name="line.2722"></a>
+<span class="sourceLineNo">2723</span>
region.closeRegionOperation();<a name="line.2723"></a>
+<span class="sourceLineNo">2724</span> }<a name="line.2724"></a>
+<span class="sourceLineNo">2725</span> // coprocessor postNext
hook<a name="line.2725"></a>
+<span class="sourceLineNo">2726</span> if (region != null
&& region.getCoprocessorHost() != null) {<a name="line.2726"></a>
+<span class="sourceLineNo">2727</span>
region.getCoprocessorHost().postScannerNext(scanner, results, rows, true);<a
name="line.2727"></a>
+<span class="sourceLineNo">2728</span> }<a name="line.2728"></a>
+<span class="sourceLineNo">2729</span> }<a name="line.2729"></a>
+<span class="sourceLineNo">2730</span><a name="line.2730"></a>
+<span class="sourceLineNo">2731</span>
quota.addScanResult(results);<a name="line.2731"></a>
+<span class="sourceLineNo">2732</span><a name="line.2732"></a>
+<span class="sourceLineNo">2733</span> // If the scanner's filter -
if any - is done with the scan<a name="line.2733"></a>
+<span class="sourceLineNo">2734</span> // and wants to tell the
client to stop the scan. This is done by passing<a name="line.2734"></a>
+<span class="sourceLineNo">2735</span> // a null result, and setting
moreResults to false.<a name="line.2735"></a>
+<span class="sourceLineNo">2736</span> if (scanner.isFilterDone()
&& results.isEmpty()) {<a name="line.2736"></a>
+<span class="sourceLineNo">2737</span> moreResults = false;<a
name="line.2737"></a>
+<span class="sourceLineNo">2738</span> results = null;<a
name="line.2738"></a>
+<span class="sourceLineNo">2739</span> } else {<a
name="line.2739"></a>
+<span class="sourceLineNo">2740</span> addResults(builder, results,
controller,<a name="line.2740"></a>
+<span class="sourceLineNo">2741</span>
RegionReplicaUtil.isDefaultReplica(region.getRegionInfo()),<a
name="line.2741"></a>
+<span class="sourceLineNo">2742</span>
isClientCellBlockSupport(context));<a name="line.2742"></a>
+<span class="sourceLineNo">2743</span> }<a name="line.2743"></a>
+<span class="sourceLineNo">2744</span> } catch (IOException e) {<a
name="line.2744"></a>
+<span class="sourceLineNo">2745</span> // if we have an exception on
scanner next and we are using the callSeq<a name="line.2745"></a>
+<span class="sourceLineNo">2746</span> // we should rollback because
the client will retry with the same callSeq<a name="line.2746"></a>
+<span class="sourceLineNo">2747</span> // and get an
OutOfOrderScannerNextException if we don't do so.<a name="line.2747"></a>
+<span class="sourceLineNo">2748</span> if (rsh != null &&
request.hasNextCallSeq()) {<a name="line.2748"></a>
+<span class="sourceLineNo">2749</span> rsh.rollbackNextCallSeq();<a
name="line.2749"></a>
+<span class="sourceLineNo">2750</span> }<a name="line.2750"></a>
+<span class="sourceLineNo">2751</span> throw e;<a
name="line.2751"></a>
+<span class="sourceLineNo">2752</span> } finally {<a
name="line.2752"></a>
+<span class="sourceLineNo">2753</span> if (context != null) {<a
name="line.2753"></a>
+<span class="sourceLineNo">2754</span>
context.setCallBack(rsh.shippedCallback);<a name="line.2754"></a>
+<span class="sourceLineNo">2755</span> }<a name="line.2755"></a>
+<span class="sourceLineNo">2756</span> // Adding resets expiration
time on lease.<a name="line.2756"></a>
+<span class="sourceLineNo">2757</span> if
(scanners.containsKey(scannerName)) {<a name="line.2757"></a>
+<span class="sourceLineNo">2758</span> ttl =
this.scannerLeaseTimeoutPeriod;<a name="line.2758"></a>
+<span class="sourceLineNo">2759</span> // When context != null,
adding back the lease will be done in callback set above.<a
name="line.2759"></a>
+<span class="sourceLineNo">2760</span> if (context == null) {<a
name="line.2760"></a>
+<span class="sourceLineNo">2761</span> if (lease != null)
regionServer.leases.addLease(lease);<a name="line.2761"></a>
+<span class="sourceLineNo">2762</span> }<a name="line.2762"></a>
+<span class="sourceLineNo">2763</span> }<a name="line.2763"></a>
+<span class="sourceLineNo">2764</span> }<a name="line.2764"></a>
+<span class="sourceLineNo">2765</span> }<a name="line.2765"></a>
+<span class="sourceLineNo">2766</span><a name="line.2766"></a>
+<span class="sourceLineNo">2767</span> if (!moreResults || closeScanner)
{<a name="line.2767"></a>
+<span class="sourceLineNo">2768</span> ttl = 0;<a name="line.2768"></a>
+<span class="sourceLineNo">2769</span> moreResults = false;<a
name="line.2769"></a>
+<span class="sourceLineNo">2770</span> if (region != null &&
region.getCoprocessorHost() != null) {<a name="line.2770"></a>
+<span class="sourceLineNo">2771</span> if
(region.getCoprocessorHost().preScannerClose(scanner)) {<a name="line.2771"></a>
+<span class="sourceLineNo">2772</span> return builder.build(); //
bypass<a name="line.2772"></a>
+<span class="sourceLineNo">2773</span> }<a name="line.2773"></a>
+<span class="sourceLineNo">2774</span> }<a name="line.2774"></a>
+<span class="sourceLineNo">2775</span> rsh =
scanners.remove(scannerName);<a name="line.2775"></a>
+<span class="sourceLineNo">2776</span> if (rsh != null) {<a
name="line.2776"></a>
+<span class="sourceLineNo">2777</span> if (context != null) {<a
name="line.2777"></a>
+<span class="sourceLineNo">2778</span>
context.setCallBack(rsh.closeCallBack);<a name="line.2778"></a>
+<span class="sourceLineNo">2779</span> } else {<a
name="line.2779"></a>
+<span class="sourceLineNo">2780</span> rsh.s.close();<a
name="line.2780"></a>
+<span class="sourceLineNo">2781</span> }<a name="line.2781"></a>
+<span class="sourceLineNo">2782</span> try {<a name="line.2782"></a>
+<span class="sourceLineNo">2783</span>
regionServer.leases.cancelLease(scannerName);<a name="line.2783"></a>
+<span class="sourceLineNo">2784</span> } catch (LeaseException le)
{<a name="line.2784"></a>
+<span class="sourceLineNo">2785</span> // No problem, ignore<a
name="line.2785"></a>
+<span class="sourceLineNo">2786</span> if (LOG.isTraceEnabled())
{<a name="line.2786"></a>
+<span class="sourceLineNo">2787</span> LOG.trace("Un-able to
cancel lease of scanner. It could already be closed.");<a name="line.2787"></a>
+<span class="sourceLineNo">2788</span> }<a name="line.2788"></a>
<span class="sourceLineNo">2789</span> }<a name="line.2789"></a>
-<span class="sourceLineNo">2790</span> }<a name="line.2790"></a>
-<span class="sourceLineNo">2791</span> }<a name="line.2791"></a>
-<span class="sourceLineNo">2792</span><a name="line.2792"></a>
-<span class="sourceLineNo">2793</span> if (ttl > 0) {<a
name="line.2793"></a>
-<span class="sourceLineNo">2794</span> builder.setTtl(ttl);<a
name="line.2794"></a>
-<span class="sourceLineNo">2795</span> }<a name="line.2795"></a>
-<span class="sourceLineNo">2796</span> builder.setScannerId(scannerId);<a
name="line.2796"></a>
-<span class="sourceLineNo">2797</span>
builder.setMoreResults(moreResults);<a name="line.2797"></a>
-<span class="sourceLineNo">2798</span> return builder.build();<a
name="line.2798"></a>
-<span class="sourceLineNo">2799</span> } catch (IOException ie) {<a
name="line.2799"></a>
-<span class="sourceLineNo">2800</span> if (scannerName != null &&
ie instanceof NotServingRegionException) {<a name="line.2800"></a>
-<span class="sourceLineNo">2801</span> RegionScannerHolder rsh =
scanners.remove(scannerName);<a name="line.2801"></a>
-<span class="sourceLineNo">2802</span> if (rsh != null) {<a
name="line.2802"></a>
-<span class="sourceLineNo">2803</span> try {<a name="line.2803"></a>
-<span class="sourceLineNo">2804</span> RegionScanner scanner =
rsh.s;<a name="line.2804"></a>
-<span class="sourceLineNo">2805</span> LOG.warn(scannerName + "
encountered " + ie.getMessage() + ", closing ...");<a name="line.2805"></a>
-<span class="sourceLineNo">2806</span> scanner.close();<a
name="line.2806"></a>
-<span class="sourceLineNo">2807</span>
regionServer.leases.cancelLease(scannerName);<a name="line.2807"></a>
-<span class="sourceLineNo">2808</span> } catch (IOException e) {<a
name="line.2808"></a>
-<span class="sourceLineNo">2809</span> LOG.warn("Getting exception
closing " + scannerName, e);<a name="line.2809"></a>
-<span class="sourceLineNo">2810</span> }<a name="line.2810"></a>
-<span class="sourceLineNo">2811</span> }<a name="line.2811"></a>
-<span class="sourceLineNo">2812</span> }<a name="line.2812"></a>
-<span class="sourceLineNo">2813</span> throw new ServiceException(ie);<a
name="line.2813"></a>
-<span class="sourceLineNo">2814</span> } finally {<a name="line.2814"></a>
-<span class="sourceLineNo">2815</span> if (quota != null) {<a
name="line.2815"></a>
-<span class="sourceLineNo">2816</span> quota.close();<a
name="line.2816"></a>
-<span class="sourceLineNo">2817</span> }<a name="line.2817"></a>
-<span class="sourceLineNo">2818</span> }<a name="line.2818"></a>
-<span class="sourceLineNo">2819</span> }<a name="line.2819"></a>
-<span class="sourceLineNo">2820</span><a name="line.2820"></a>
-<span class="sourceLineNo">2821</span> @Override<a name="line.2821"></a>
-<span class="sourceLineNo">2822</span> public CoprocessorServiceResponse
execRegionServerService(RpcController controller,<a name="line.2822"></a>
-<span class="sourceLineNo">2823</span> CoprocessorServiceRequest request)
throws ServiceException {<a name="line.2823"></a>
-<span class="sourceLineNo">2824</span> return
regionServer.execRegionServerService(controller, request);<a
name="line.2824"></a>
-<span class="sourceLineNo">2825</span> }<a name="line.2825"></a>
-<span class="sourceLineNo">2826</span><a name="line.2826"></a>
-<span class="sourceLineNo">2827</span> @Override<a name="line.2827"></a>
-<span class="sourceLineNo">2828</span> public UpdateConfigurationResponse
updateConfiguration(<a name="line.2828"></a>
-<span class="sourceLineNo">2829</span> RpcController controller,
UpdateConfigurationRequest request)<a name="line.2829"></a>
-<span class="sourceLineNo">2830</span> throws ServiceException {<a
name="line.2830"></a>
-<span class="sourceLineNo">2831</span> try {<a name="line.2831"></a>
-<span class="sourceLineNo">2832</span>
this.regionServer.updateConfiguration();<a name="line.2832"></a>
-<span class="sourceLineNo">2833</span> } catch (Exception e) {<a
name="line.2833"></a>
-<span class="sourceLineNo">2834</span> throw new ServiceException(e);<a
name="line.2834"></a>
-<span class="sourceLineNo">2835</span> }<a name="line.2835"></a>
-<span class="sourceLineNo">2836</span> return
UpdateConfigurationResponse.getDefaultInstance();<a name="line.2836"></a>
-<span class="sourceLineNo">2837</span> }<a name="line.2837"></a>
-<span class="sourceLineNo">2838</span>}<a name="line.2838"></a>
+<span class="sourceLineNo">2790</span> if (region != null &&
region.getCoprocessorHost() != null) {<a name="line.2790"></a>
+<span class="sourceLineNo">2791</span>
region.getCoprocessorHost().postScannerClose(scanner);<a name="line.2791"></a>
+<span class="sourceLineNo">2792</span> }<a name="line.2792"></a>
+<span class="sourceLineNo">2793</span> }<a name="line.2793"></a>
+<span class="sourceLineNo">2794</span> }<a name="line.2794"></a>
+<span class="sourceLineNo">2795</span><a name="line.2795"></a>
+<span class="sourceLineNo">2796</span> if (ttl > 0) {<a
name="line.2796"></a>
+<span class="sourceLineNo">2797</span> builder.setTtl(ttl);<a
name="line.2797"></a>
+<span class="sourceLineNo">2798</span> }<a name="line.2798"></a>
+<span class="sourceLineNo">2799</span> builder.setScannerId(scannerId);<a
name="line.2799"></a>
+<span class="sourceLineNo">2800</span>
builder.setMoreResults(moreResults);<a name="line.2800"></a>
+<span class="sourceLineNo">2801</span> return builder.build();<a
name="line.2801"></a>
+<span class="sourceLineNo">2802</span> } catch (IOException ie) {<a
name="line.2802"></a>
+<span class="sourceLineNo">2803</span> if (scannerName != null &&
ie instanceof NotServingRegionException) {<a name="line.2803"></a>
+<span class="sourceLineNo">2804</span> RegionScannerHolder rsh =
scanners.remove(scannerName);<a name="line.2804"></a>
+<span class="sourceLineNo">2805</span> if (rsh != null) {<a
name="line.2805"></a>
+<span class="sourceLineNo">2806</span> try {<a name="line.2806"></a>
+<span class="sourceLineNo">2807</span> RegionScanner scanner =
rsh.s;<a name="line.2807"></a>
+<span class="sourceLineNo">2808</span> LOG.warn(scannerName + "
encountered " + ie.getMessage() + ", closing ...");<a name="line.2808"></a>
+<span class="sourceLineNo">2809</span> scanner.close();<a
name="line.2809"></a>
+<span class="sourceLineNo">2810</span>
regionServer.leases.cancelLease(scannerName);<a name="line.2810"></a>
+<span class="sourceLineNo">2811</span> } catch (IOException e) {<a
name="line.2811"></a>
+<span class="sourceLineNo">2812</span> LOG.warn("Getting exception
closing " + scannerName, e);<a name="line.2812"></a>
+<span class="sourceLineNo">2813</span> }<a name="line.2813"></a>
+<span class="sourceLineNo">2814</span> }<a name="line.2814"></a>
+<span class="sourceLineNo">2815</span> }<a name="line.2815"></a>
+<span class="sourceLineNo">2816</span> throw new ServiceException(ie);<a
name="line.2816"></a>
+<span class="sourceLineNo">2817</span> } finally {<a name="line.2817"></a>
+<span class="sourceLineNo">2818</span> if (quota != null) {<a
name="line.2818"></a>
+<span class="sourceLineNo">2819</span> quota.close();<a
name="line.2819"></a>
+<span class="sourceLineNo">2820</span> }<a name="line.2820"></a>
+<span class="sourceLineNo">2821</span> }<a name="line.2821"></a>
+<span class="sourceLineNo">2822</span> }<a name="line.2822"></a>
+<span class="sourceLineNo">2823</span><a name="line.2823"></a>
+<span class="sourceLineNo">2824</span> @Override<a name="line.2824"></a>
+<span class="sourceLineNo">2825</span> public CoprocessorServiceResponse
execRegionServerService(RpcController controller,<a name="line.2825"></a>
+<span class="sourceLineNo">2826</span> CoprocessorServiceRequest request)
throws ServiceException {<a name="line.2826"></a>
+<span class="sourceLineNo">2827</span> return
regionServer.execRegionServerService(controller, request);<a
name="line.2827"></a>
+<span class="sourceLineNo">2828</span> }<a name="line.2828"></a>
+<span class="sourceLineNo">2829</span><a name="line.2829"></a>
+<span class="sourceLineNo">2830</span> @Override<a name="line.2830"></a>
+<span class="sourceLineNo">2831</span> public UpdateConfigurationResponse
updateConfiguration(<a name="line.2831"></a>
+<span class="sourceLineNo">2832</span> RpcController controller,
UpdateConfigurationRequest request)<a name="line.2832"></a>
+<span class="sourceLineNo">2833</span> throws ServiceException {<a
name="line.2833"></a>
+<span class="sourceLineNo">2834</span> try {<a name="line.2834"></a>
+<span class="sourceLineNo">2835</span>
this.regionServer.updateConfiguration();<a name="line.2835"></a>
+<span class="sourceLineNo">2836</span> } catch (Exception e) {<a
name="line.2836"></a>
+<span class="sourceLineNo">2837</span> throw new ServiceException(e);<a
name="line.2837"></a>
+<span class="sourceLineNo">2838</span> }<a name="line.2838"></a>
+<span class="sourceLineNo">2839</span> return
UpdateConfigurationResponse.getDefaultInstance();<a name="line.2839"></a>
+<span class="sourceLineNo">2840</span> }<a name="line.2840"></a>
+<span class="sourceLineNo">2841</span>}<a name="line.2841"></a>