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 java.io.IOException;
21  import java.util.ArrayList;
22  import java.util.Iterator;
23  
24  import org.apache.hadoop.hbase.classification.InterfaceAudience;
25  import org.apache.hadoop.hbase.client.metrics.ScanMetrics;
26  
27  /**
28   * Helper class for custom client scanners.
29   */
30  @InterfaceAudience.Private
31  public abstract class AbstractClientScanner implements ResultScanner {
32    protected ScanMetrics scanMetrics;
33  
34    /**
35     * Check and initialize if application wants to collect scan metrics
36     */
37    protected void initScanMetrics(Scan scan) {
38      // check if application wants to collect scan metrics
39      if (scan.isScanMetricsEnabled()) {
40        scanMetrics = new ScanMetrics();
41      }
42    }
43  
44    /**
45     * Used internally accumulating metrics on scan. To
46     * enable collection of metrics on a Scanner, call {@link Scan#setScanMetricsEnabled(boolean)}.
47     * These metrics are cleared at key transition points. Metrics are accumulated in the
48     * {@link Scan} object itself.
49     * @see Scan#getScanMetrics()
50     * @return Returns the running {@link ScanMetrics} instance or null if scan metrics not enabled.
51     */
52    public ScanMetrics getScanMetrics() {
53      return scanMetrics;
54    }
55  
56    /**
57     * Get nbRows rows.
58     * How many RPCs are made is determined by the {@link Scan#setCaching(int)}
59     * setting (or hbase.client.scanner.caching in hbase-site.xml).
60     * @param nbRows number of rows to return
61     * @return Between zero and nbRows rowResults.  Scan is done
62     * if returned array is of zero-length (We never return null).
63     * @throws IOException
64     */
65    @Override
66    public Result [] next(int nbRows) throws IOException {
67      // Collect values to be returned here
68      ArrayList<Result> resultSets = new ArrayList<Result>(nbRows);
69      for(int i = 0; i < nbRows; i++) {
70        Result next = next();
71        if (next != null) {
72          resultSets.add(next);
73        } else {
74          break;
75        }
76      }
77      return resultSets.toArray(new Result[resultSets.size()]);
78    }
79  
80    @Override
81    public Iterator<Result> iterator() {
82      return new Iterator<Result>() {
83        // The next RowResult, possibly pre-read
84        Result next = null;
85  
86        // return true if there is another item pending, false if there isn't.
87        // this method is where the actual advancing takes place, but you need
88        // to call next() to consume it. hasNext() will only advance if there
89        // isn't a pending next().
90        @Override
91        public boolean hasNext() {
92          if (next == null) {
93            try {
94              next = AbstractClientScanner.this.next();
95              return next != null;
96            } catch (IOException e) {
97              throw new RuntimeException(e);
98            }
99          }
100         return true;
101       }
102 
103       // get the pending next item and advance the iterator. returns null if
104       // there is no next item.
105       @Override
106       public Result next() {
107         // since hasNext() does the real advancing, we call this to determine
108         // if there is a next before proceeding.
109         if (!hasNext()) {
110           return null;
111         }
112 
113         // if we get to here, then hasNext() has given us an item to return.
114         // we want to return the item and then null out the next pointer, so
115         // we use a temporary variable.
116         Result temp = next;
117         next = null;
118         return temp;
119       }
120 
121       @Override
122       public void remove() {
123         throw new UnsupportedOperationException();
124       }
125     };
126   }
127   /**
128    * Allow the client to renew the scanner's lease on the server.
129    * @return true if the lease was successfully renewed, false otherwise.
130    */
131   // Note that this method should be on ResultScanner, but that is marked stable.
132   // Callers have to cast their instance of ResultScanner to AbstractClientScanner to use this.
133   public abstract boolean renewLease();
134 }