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