View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.client;
19  
20  import static org.apache.hadoop.hbase.client.ConnectionUtils.filterCells;
21  
22  import java.io.IOException;
23  import java.util.List;
24  
25  import org.apache.hadoop.hbase.Cell;
26  import org.apache.hadoop.hbase.CellUtil;
27  import org.apache.hadoop.hbase.classification.InterfaceAudience;
28  
29  /**
30   * A ScanResultCache that may return partial result.
31   * <p>
32   * As we can only scan from the starting of a row when error, so here we also implement the logic
33   * that skips the cells that have already been returned.
34   */
35  @InterfaceAudience.Private
36  class AllowPartialScanResultCache extends ScanResultCache {
37  
38    // used to filter out the cells that already returned to user as we always start from the
39    // beginning of a row when retry.
40    private Cell lastCell;
41  
42    private boolean lastResultPartial;
43  
44    public AllowPartialScanResultCache(List<Result> cache) {
45      super(cache);
46    }
47  
48    private void recordLastResult(Result result) {
49      lastCell = result.rawCells()[result.rawCells().length - 1];
50      lastResultPartial = result.mayHaveMoreCellsInRow();
51    }
52  
53    @Override
54    public void loadResultsToCache(Result[] results, boolean isHeartbeatMessage) throws IOException {
55      if (results.length == 0) {
56        if (!isHeartbeatMessage && lastResultPartial) {
57          // An empty non heartbeat result indicate that there must be a row change. So if the
58          // lastResultPartial is true then we need to increase numberOfCompleteRows.
59          numberOfCompleteRows++;
60        }
61        return;
62      }
63      int i;
64      for (i = 0; i < results.length; i++) {
65        Result r = filterCells(results[i], lastCell);
66        if (r != null) {
67          results[i] = r;
68          break;
69        }
70      }
71      if (i == results.length) {
72        return;
73      }
74      if (lastResultPartial && !CellUtil.matchingRow(lastCell, results[0].getRow())) {
75        // there is a row change, so increase numberOfCompleteRows
76        numberOfCompleteRows++;
77      }
78      recordLastResult(results[results.length - 1]);
79      addResultArrayToCache(results, i, results.length);
80    }
81  
82    @Override
83    protected void checkUpdateNumberOfCompleteRowsAndCache(Result rs) {
84      if (!rs.mayHaveMoreCellsInRow()) {
85        numberOfCompleteRows++;
86      }
87      addResultToCache(rs);
88    }
89  
90    @Override
91    public void clear() {
92      // we do not cache anything
93      super.clear();
94    }
95  }