1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.mapreduce;
20
21 import java.io.DataInput;
22 import java.io.DataOutput;
23 import java.io.IOException;
24 import java.util.Arrays;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.hadoop.hbase.classification.InterfaceAudience;
29 import org.apache.hadoop.hbase.classification.InterfaceStability;
30 import org.apache.hadoop.hbase.TableName;
31 import org.apache.hadoop.hbase.HConstants;
32 import org.apache.hadoop.hbase.client.Scan;
33 import org.apache.hadoop.hbase.util.Bytes;
34 import org.apache.hadoop.io.Writable;
35 import org.apache.hadoop.io.WritableUtils;
36 import org.apache.hadoop.mapreduce.InputSplit;
37
38
39
40
41
42 @InterfaceAudience.Public
43 @InterfaceStability.Evolving
44 public class TableSplit extends InputSplit
45 implements Writable, Comparable<TableSplit> {
46
47 @Deprecated
48 public static final Log LOG = LogFactory.getLog(TableSplit.class);
49
50
51
52 enum Version {
53 UNVERSIONED(0),
54
55 INITIAL(-1),
56
57 WITH_ENCODED_REGION_NAME(-2);
58
59 final int code;
60 static final Version[] byCode;
61 static {
62 byCode = Version.values();
63 for (int i = 0; i < byCode.length; i++) {
64 if (byCode[i].code != -1 * i) {
65 throw new AssertionError("Values in this enum should be descending by one");
66 }
67 }
68 }
69
70 Version(int code) {
71 this.code = code;
72 }
73
74 boolean atLeast(Version other) {
75 return code <= other.code;
76 }
77
78 static Version fromCode(int code) {
79 return byCode[code * -1];
80 }
81 }
82
83 private static final Version VERSION = Version.WITH_ENCODED_REGION_NAME;
84 private TableName tableName;
85 private byte [] startRow;
86 private byte [] endRow;
87 private String regionLocation;
88 private String encodedRegionName = "";
89 private String scan = "";
90 private long length;
91
92
93 public TableSplit() {
94 this((TableName)null, null, HConstants.EMPTY_BYTE_ARRAY,
95 HConstants.EMPTY_BYTE_ARRAY, "");
96 }
97
98
99
100
101
102
103
104 @Deprecated
105 public TableSplit(final byte [] tableName, Scan scan, byte [] startRow, byte [] endRow,
106 final String location) {
107 this(TableName.valueOf(tableName), scan, startRow, endRow, location);
108 }
109
110
111
112
113
114
115
116
117
118
119
120
121 public TableSplit(TableName tableName, Scan scan, byte [] startRow, byte [] endRow,
122 final String location) {
123 this(tableName, scan, startRow, endRow, location, 0L);
124 }
125
126
127
128
129
130
131
132
133
134
135
136 public TableSplit(TableName tableName, Scan scan, byte [] startRow, byte [] endRow,
137 final String location, long length) {
138 this(tableName, scan, startRow, endRow, location, "", length);
139 }
140
141
142
143
144
145
146
147
148
149
150
151 public TableSplit(TableName tableName, Scan scan, byte [] startRow, byte [] endRow,
152 final String location, final String encodedRegionName, long length) {
153 this.tableName = tableName;
154 try {
155 this.scan =
156 (null == scan) ? "" : TableMapReduceUtil.convertScanToString(scan);
157 } catch (IOException e) {
158 LOG.warn("Failed to convert Scan to String", e);
159 }
160 this.startRow = startRow;
161 this.endRow = endRow;
162 this.regionLocation = location;
163 this.encodedRegionName = encodedRegionName;
164 this.length = length;
165 }
166
167
168
169
170
171
172
173 @Deprecated
174 public TableSplit(final byte [] tableName, byte[] startRow, byte[] endRow,
175 final String location) {
176 this(TableName.valueOf(tableName), startRow, endRow, location);
177 }
178
179
180
181
182
183
184
185
186
187
188 public TableSplit(TableName tableName, byte[] startRow, byte[] endRow,
189 final String location) {
190 this(tableName, null, startRow, endRow, location);
191 }
192
193
194
195
196
197
198
199
200
201
202 public TableSplit(TableName tableName, byte[] startRow, byte[] endRow,
203 final String location, long length) {
204 this(tableName, null, startRow, endRow, location, length);
205 }
206
207
208
209
210
211
212
213 public Scan getScan() throws IOException {
214 return TableMapReduceUtil.convertStringToScan(this.scan);
215 }
216
217
218
219
220
221
222 public byte [] getTableName() {
223 return tableName.getName();
224 }
225
226
227
228
229
230
231 public TableName getTable() {
232
233
234
235 return tableName;
236 }
237
238
239
240
241
242
243 public byte [] getStartRow() {
244 return startRow;
245 }
246
247
248
249
250
251
252 public byte [] getEndRow() {
253 return endRow;
254 }
255
256
257
258
259
260
261 public String getRegionLocation() {
262 return regionLocation;
263 }
264
265
266
267
268
269
270
271 @Override
272 public String[] getLocations() {
273 return new String[] {regionLocation};
274 }
275
276
277
278
279
280
281 public String getEncodedRegionName() {
282 return encodedRegionName;
283 }
284
285
286
287
288
289
290
291 @Override
292 public long getLength() {
293 return length;
294 }
295
296
297
298
299
300
301
302 @Override
303 public void readFields(DataInput in) throws IOException {
304 Version version = Version.UNVERSIONED;
305
306
307
308
309
310
311
312
313 int len = WritableUtils.readVInt(in);
314 if (len < 0) {
315
316 version = Version.fromCode(len);
317 len = WritableUtils.readVInt(in);
318 }
319 byte[] tableNameBytes = new byte[len];
320 in.readFully(tableNameBytes);
321 tableName = TableName.valueOf(tableNameBytes);
322 startRow = Bytes.readByteArray(in);
323 endRow = Bytes.readByteArray(in);
324 regionLocation = Bytes.toString(Bytes.readByteArray(in));
325 if (version.atLeast(Version.INITIAL)) {
326 scan = Bytes.toString(Bytes.readByteArray(in));
327 }
328 length = WritableUtils.readVLong(in);
329 if (version.atLeast(Version.WITH_ENCODED_REGION_NAME)) {
330 encodedRegionName = Bytes.toString(Bytes.readByteArray(in));
331 }
332 }
333
334
335
336
337
338
339
340 @Override
341 public void write(DataOutput out) throws IOException {
342 WritableUtils.writeVInt(out, VERSION.code);
343 Bytes.writeByteArray(out, tableName.getName());
344 Bytes.writeByteArray(out, startRow);
345 Bytes.writeByteArray(out, endRow);
346 Bytes.writeByteArray(out, Bytes.toBytes(regionLocation));
347 Bytes.writeByteArray(out, Bytes.toBytes(scan));
348 WritableUtils.writeVLong(out, length);
349 Bytes.writeByteArray(out, Bytes.toBytes(encodedRegionName));
350 }
351
352
353
354
355
356
357
358 @Override
359 public String toString() {
360 StringBuilder sb = new StringBuilder();
361 sb.append("HBase table split(");
362 sb.append("table name: ").append(tableName);
363
364 String printScan = "";
365 if (!scan.equals("")) {
366 try {
367
368 printScan = TableMapReduceUtil.convertStringToScan(scan).toString();
369 }
370 catch (IOException e) {
371 printScan = "";
372 }
373 }
374 sb.append(", scan: ").append(printScan);
375 sb.append(", start row: ").append(Bytes.toStringBinary(startRow));
376 sb.append(", end row: ").append(Bytes.toStringBinary(endRow));
377 sb.append(", region location: ").append(regionLocation);
378 sb.append(", encoded region name: ").append(encodedRegionName);
379 sb.append(")");
380 return sb.toString();
381 }
382
383
384
385
386
387
388
389
390 @Override
391 public int compareTo(TableSplit split) {
392
393
394 int tableNameComparison =
395 getTable().compareTo(split.getTable());
396 return tableNameComparison != 0 ? tableNameComparison : Bytes.compareTo(
397 getStartRow(), split.getStartRow());
398 }
399
400 @Override
401 public boolean equals(Object o) {
402 if (o == null || !(o instanceof TableSplit)) {
403 return false;
404 }
405 return tableName.equals(((TableSplit)o).tableName) &&
406 Bytes.equals(startRow, ((TableSplit)o).startRow) &&
407 Bytes.equals(endRow, ((TableSplit)o).endRow) &&
408 regionLocation.equals(((TableSplit)o).regionLocation);
409 }
410
411 @Override
412 public int hashCode() {
413 int result = tableName != null ? tableName.hashCode() : 0;
414 result = 31 * result + (scan != null ? scan.hashCode() : 0);
415 result = 31 * result + (startRow != null ? Arrays.hashCode(startRow) : 0);
416 result = 31 * result + (endRow != null ? Arrays.hashCode(endRow) : 0);
417 result = 31 * result + (regionLocation != null ? regionLocation.hashCode() : 0);
418 result = 31 * result + (encodedRegionName != null ? encodedRegionName.hashCode() : 0);
419 return result;
420 }
421 }