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 enable collection of metrics on a Scanner,
46 * call {@link Scan#setScanMetricsEnabled(boolean)}.
47 * @return Returns the running {@link ScanMetrics} instance or null if scan metrics not enabled.
48 */
49 @Override
50 public ScanMetrics getScanMetrics() {
51 return scanMetrics;
52 }
53
54 /**
55 * Get nbRows rows.
56 * How many RPCs are made is determined by the {@link Scan#setCaching(int)}
57 * setting (or hbase.client.scanner.caching in hbase-site.xml).
58 * @param nbRows number of rows to return
59 * @return Between zero and nbRows rowResults. Scan is done
60 * if returned array is of zero-length (We never return null).
61 * @throws IOException
62 */
63 @Override
64 public Result[] next(int nbRows) throws IOException {
65 // Collect values to be returned here
66 ArrayList<Result> resultSets = new ArrayList<Result>(nbRows);
67 for(int i = 0; i < nbRows; i++) {
68 Result next = next();
69 if (next != null) {
70 resultSets.add(next);
71 } else {
72 break;
73 }
74 }
75 return resultSets.toArray(new Result[resultSets.size()]);
76 }
77
78 @Override
79 public Iterator<Result> iterator() {
80 return new Iterator<Result>() {
81 // The next RowResult, possibly pre-read
82 Result next = null;
83
84 // return true if there is another item pending, false if there isn't.
85 // this method is where the actual advancing takes place, but you need
86 // to call next() to consume it. hasNext() will only advance if there
87 // isn't a pending next().
88 @Override
89 public boolean hasNext() {
90 if (next == null) {
91 try {
92 next = AbstractClientScanner.this.next();
93 return next != null;
94 } catch (IOException e) {
95 throw new RuntimeException(e);
96 }
97 }
98 return true;
99 }
100
101 // get the pending next item and advance the iterator. returns null if
102 // there is no next item.
103 @Override
104 public Result next() {
105 // since hasNext() does the real advancing, we call this to determine
106 // if there is a next before proceeding.
107 if (!hasNext()) {
108 return null;
109 }
110
111 // if we get to here, then hasNext() has given us an item to return.
112 // we want to return the item and then null out the next pointer, so
113 // we use a temporary variable.
114 Result temp = next;
115 next = null;
116 return temp;
117 }
118
119 @Override
120 public void remove() {
121 throw new UnsupportedOperationException();
122 }
123 };
124 }
125 }