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.Cell;
29 import org.apache.hadoop.hbase.KeyValue;
30 import org.apache.hadoop.hbase.UnknownScannerException;
31 import org.apache.hadoop.hbase.client.HTableInterface;
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<Cell> rowI;
56 private Cell 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 HTableInterface table = RESTServlet.getInstance().getTable(tableName);
68 try {
69 Scan scan;
70 if (rowspec.hasEndRow()) {
71 scan = new Scan(rowspec.getStartRow(), rowspec.getEndRow());
72 } else {
73 scan = new Scan(rowspec.getStartRow());
74 }
75 if (rowspec.hasColumns()) {
76 byte[][] columns = rowspec.getColumns();
77 for (byte[] column: columns) {
78 byte[][] split = KeyValue.parseColumn(column);
79 if (split.length == 1) {
80 scan.addFamily(split[0]);
81 } else if (split.length == 2) {
82 scan.addColumn(split[0], split[1]);
83 } else {
84 throw new IllegalArgumentException("Invalid familyAndQualifier provided.");
85 }
86 }
87 }
88 scan.setTimeRange(rowspec.getStartTime(), rowspec.getEndTime());
89 scan.setMaxVersions(rowspec.getMaxVersions());
90 if (filter != null) {
91 scan.setFilter(filter);
92 }
93
94 scan.setCacheBlocks(false);
95 if (caching > 0 ) {
96 scan.setCaching(caching);
97 }
98 scanner = table.getScanner(scan);
99 cached = null;
100 id = Long.toString(System.currentTimeMillis()) +
101 Integer.toHexString(scanner.hashCode());
102 } finally {
103 table.close();
104 }
105 }
106
107 public String getID() {
108 return id;
109 }
110
111 public void close() {
112 if (scanner != null) {
113 scanner.close();
114 scanner = null;
115 }
116 }
117
118 public boolean hasNext() {
119 if (cache != null) {
120 return true;
121 }
122 if (rowI != null && rowI.hasNext()) {
123 return true;
124 }
125 if (cached != null) {
126 return true;
127 }
128 try {
129 Result result = scanner.next();
130 if (result != null && !result.isEmpty()) {
131 cached = result;
132 }
133 } catch (UnknownScannerException e) {
134 throw new IllegalArgumentException(e);
135 } catch (IOException e) {
136 LOG.error(StringUtils.stringifyException(e));
137 }
138 return cached != null;
139 }
140
141 public Cell next() {
142 if (cache != null) {
143 Cell kv = cache;
144 cache = null;
145 return kv;
146 }
147 boolean loop;
148 do {
149 loop = false;
150 if (rowI != null) {
151 if (rowI.hasNext()) {
152 return rowI.next();
153 } else {
154 rowI = null;
155 }
156 }
157 if (cached != null) {
158 rowI = cached.listCells().iterator();
159 loop = true;
160 cached = null;
161 } else {
162 Result result = null;
163 try {
164 result = scanner.next();
165 } catch (UnknownScannerException e) {
166 throw new IllegalArgumentException(e);
167 } catch (IOException e) {
168 LOG.error(StringUtils.stringifyException(e));
169 }
170 if (result != null && !result.isEmpty()) {
171 rowI = result.listCells().iterator();
172 loop = true;
173 }
174 }
175 } while (loop);
176 return null;
177 }
178
179 public void putBack(Cell kv) {
180 this.cache = kv;
181 }
182
183 public void remove() {
184 throw new UnsupportedOperationException("remove not supported");
185 }
186 }