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  import org.apache.hadoop.hbase.util.Bytes;
27  
28  /**
29   * Helper class for custom client scanners.
30   */
31  @InterfaceAudience.Private
32  public abstract class AbstractClientScanner implements ResultScanner {
33  
34    protected ScanMetrics scanMetrics;
35  
36    /**
37     * Check and initialize if application wants to collect scan metrics
38     */
39    protected void initScanMetrics(Scan scan) {
40      // check if application wants to collect scan metrics
41      byte[] enableMetrics = scan.getAttribute(
42        Scan.SCAN_ATTRIBUTES_METRICS_ENABLE);
43      if (enableMetrics != null && Bytes.toBoolean(enableMetrics)) {
44        scanMetrics = new ScanMetrics();
45      }
46    }
47  
48    // TODO: should this be at ResultScanner? ScanMetrics is not public API it seems.
49    public ScanMetrics getScanMetrics() {
50      return scanMetrics;
51    }
52  
53    /**
54     * Get <param>nbRows</param> rows.
55     * How many RPCs are made is determined by the {@link Scan#setCaching(int)}
56     * setting (or hbase.client.scanner.caching in hbase-site.xml).
57     * @param nbRows number of rows to return
58     * @return Between zero and <param>nbRows</param> RowResults.  Scan is done
59     * if returned array is of zero-length (We never return null).
60     * @throws IOException
61     */
62    @Override
63    public Result [] next(int nbRows) throws IOException {
64      // Collect values to be returned here
65      ArrayList<Result> resultSets = new ArrayList<Result>(nbRows);
66      for(int i = 0; i < nbRows; i++) {
67        Result next = next();
68        if (next != null) {
69          resultSets.add(next);
70        } else {
71          break;
72        }
73      }
74      return resultSets.toArray(new Result[resultSets.size()]);
75    }
76  
77    @Override
78    public Iterator<Result> iterator() {
79      return new Iterator<Result>() {
80        // The next RowResult, possibly pre-read
81        Result next = null;
82  
83        // return true if there is another item pending, false if there isn't.
84        // this method is where the actual advancing takes place, but you need
85        // to call next() to consume it. hasNext() will only advance if there
86        // isn't a pending next().
87        @Override
88        public boolean hasNext() {
89          if (next == null) {
90            try {
91              next = AbstractClientScanner.this.next();
92              return next != null;
93            } catch (IOException e) {
94              throw new RuntimeException(e);
95            }
96          }
97          return true;
98        }
99  
100       // get the pending next item and advance the iterator. returns null if
101       // there is no next item.
102       @Override
103       public Result next() {
104         // since hasNext() does the real advancing, we call this to determine
105         // if there is a next before proceeding.
106         if (!hasNext()) {
107           return null;
108         }
109 
110         // if we get to here, then hasNext() has given us an item to return.
111         // we want to return the item and then null out the next pointer, so
112         // we use a temporary variable.
113         Result temp = next;
114         next = null;
115         return temp;
116       }
117 
118       @Override
119       public void remove() {
120         throw new UnsupportedOperationException();
121       }
122     };
123   }
124 }