1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.rest;
21
22 import java.io.IOException;
23 import java.util.Iterator;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.apache.hadoop.classification.InterfaceAudience;
28 import org.apache.hadoop.hbase.KeyValue;
29 import org.apache.hadoop.hbase.UnknownScannerException;
30 import org.apache.hadoop.hbase.client.HTableInterface;
31 import org.apache.hadoop.hbase.client.HTablePool;
32 import org.apache.hadoop.hbase.client.Result;
33 import org.apache.hadoop.hbase.client.ResultScanner;
34 import org.apache.hadoop.hbase.client.Scan;
35 import org.apache.hadoop.hbase.filter.Filter;
36 import org.apache.hadoop.hbase.rest.model.ScannerModel;
37 import org.apache.hadoop.util.StringUtils;
38
39 @InterfaceAudience.Private
40 public class ScannerResultGenerator extends ResultGenerator {
41
42 private static final Log LOG =
43 LogFactory.getLog(ScannerResultGenerator.class);
44
45 public static Filter buildFilterFromModel(final ScannerModel model)
46 throws Exception {
47 String filter = model.getFilter();
48 if (filter == null || filter.length() == 0) {
49 return null;
50 }
51 return buildFilter(filter);
52 }
53
54 private String id;
55 private Iterator<KeyValue> rowI;
56 private KeyValue cache;
57 private ResultScanner scanner;
58 private Result cached;
59
60 public ScannerResultGenerator(final String tableName, final RowSpec rowspec,
61 final Filter filter) throws IllegalArgumentException, IOException {
62 this(tableName, rowspec, filter, -1);
63 }
64
65 public ScannerResultGenerator(final String tableName, final RowSpec rowspec,
66 final Filter filter, final int caching) throws IllegalArgumentException, IOException {
67 HTablePool pool = RESTServlet.getInstance().getTablePool();
68 HTableInterface table = pool.getTable(tableName);
69 try {
70 Scan scan;
71 if (rowspec.hasEndRow()) {
72 scan = new Scan(rowspec.getStartRow(), rowspec.getEndRow());
73 } else {
74 scan = new Scan(rowspec.getStartRow());
75 }
76 if (rowspec.hasColumns()) {
77 byte[][] columns = rowspec.getColumns();
78 for (byte[] column: columns) {
79 byte[][] split = KeyValue.parseColumn(column);
80 if (split.length > 1 && (split[1] != null && split[1].length != 0)) {
81 scan.addColumn(split[0], split[1]);
82 } else {
83 scan.addFamily(split[0]);
84 }
85 }
86 }
87 scan.setTimeRange(rowspec.getStartTime(), rowspec.getEndTime());
88 scan.setMaxVersions(rowspec.getMaxVersions());
89 if (filter != null) {
90 scan.setFilter(filter);
91 }
92
93 scan.setCacheBlocks(false);
94 if (caching > 0 ) {
95 scan.setCaching(caching);
96 }
97 scanner = table.getScanner(scan);
98 cached = null;
99 id = Long.toString(System.currentTimeMillis()) +
100 Integer.toHexString(scanner.hashCode());
101 } finally {
102 table.close();
103 }
104 }
105
106 public String getID() {
107 return id;
108 }
109
110 public void close() {
111 }
112
113 public boolean hasNext() {
114 if (cache != null) {
115 return true;
116 }
117 if (rowI != null && rowI.hasNext()) {
118 return true;
119 }
120 if (cached != null) {
121 return true;
122 }
123 try {
124 Result result = scanner.next();
125 if (result != null && !result.isEmpty()) {
126 cached = result;
127 }
128 } catch (UnknownScannerException e) {
129 throw new IllegalArgumentException(e);
130 } catch (IOException e) {
131 LOG.error(StringUtils.stringifyException(e));
132 }
133 return cached != null;
134 }
135
136 public KeyValue next() {
137 if (cache != null) {
138 KeyValue kv = cache;
139 cache = null;
140 return kv;
141 }
142 boolean loop;
143 do {
144 loop = false;
145 if (rowI != null) {
146 if (rowI.hasNext()) {
147 return rowI.next();
148 } else {
149 rowI = null;
150 }
151 }
152 if (cached != null) {
153 rowI = cached.list().iterator();
154 loop = true;
155 cached = null;
156 } else {
157 Result result = null;
158 try {
159 result = scanner.next();
160 } catch (UnknownScannerException e) {
161 throw new IllegalArgumentException(e);
162 } catch (IOException e) {
163 LOG.error(StringUtils.stringifyException(e));
164 }
165 if (result != null && !result.isEmpty()) {
166 rowI = result.list().iterator();
167 loop = true;
168 }
169 }
170 } while (loop);
171 return null;
172 }
173
174 public void putBack(KeyValue kv) {
175 this.cache = kv;
176 }
177
178 public void remove() {
179 throw new UnsupportedOperationException("remove not supported");
180 }
181 }