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.HConstants;
29 import org.apache.hadoop.hbase.TableName;
30 import org.apache.hadoop.hbase.classification.InterfaceAudience;
31 import org.apache.hadoop.hbase.classification.InterfaceStability;
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
90
91
92
93
94
95
96
97
98
99 private String scan = "";
100
101 private long length;
102
103
104 public TableSplit() {
105 this((TableName)null, null, HConstants.EMPTY_BYTE_ARRAY,
106 HConstants.EMPTY_BYTE_ARRAY, "");
107 }
108
109
110
111
112
113
114
115 @Deprecated
116 public TableSplit(final byte [] tableName, Scan scan, byte [] startRow, byte [] endRow,
117 final String location) {
118 this(TableName.valueOf(tableName), scan, startRow, endRow, location);
119 }
120
121
122
123
124
125
126
127
128
129
130
131
132 public TableSplit(TableName tableName, Scan scan, byte [] startRow, byte [] endRow,
133 final String location) {
134 this(tableName, scan, startRow, endRow, location, 0L);
135 }
136
137
138
139
140
141
142
143
144
145
146
147 public TableSplit(TableName tableName, Scan scan, byte [] startRow, byte [] endRow,
148 final String location, long length) {
149 this(tableName, scan, startRow, endRow, location, "", length);
150 }
151
152
153
154
155
156
157
158
159
160
161
162 public TableSplit(TableName tableName, Scan scan, byte [] startRow, byte [] endRow,
163 final String location, final String encodedRegionName, long length) {
164 this.tableName = tableName;
165 try {
166 this.scan =
167 (null == scan) ? "" : TableMapReduceUtil.convertScanToString(scan);
168 } catch (IOException e) {
169 LOG.warn("Failed to convert Scan to String", e);
170 }
171 this.startRow = startRow;
172 this.endRow = endRow;
173 this.regionLocation = location;
174 this.encodedRegionName = encodedRegionName;
175 this.length = length;
176 }
177
178
179
180
181
182
183
184 @Deprecated
185 public TableSplit(final byte [] tableName, byte[] startRow, byte[] endRow,
186 final String location) {
187 this(TableName.valueOf(tableName), startRow, endRow, location);
188 }
189
190
191
192
193
194
195
196
197
198
199 public TableSplit(TableName tableName, byte[] startRow, byte[] endRow,
200 final String location) {
201 this(tableName, null, startRow, endRow, location);
202 }
203
204
205
206
207
208
209
210
211
212
213 public TableSplit(TableName tableName, byte[] startRow, byte[] endRow,
214 final String location, long length) {
215 this(tableName, null, startRow, endRow, location, length);
216 }
217
218
219
220
221
222
223
224 public Scan getScan() throws IOException {
225 return TableMapReduceUtil.convertStringToScan(this.scan);
226 }
227
228
229
230
231
232
233
234 @InterfaceAudience.Private
235 public String getScanAsString() {
236 return this.scan;
237 }
238
239
240
241
242
243
244 public byte [] getTableName() {
245 return tableName.getName();
246 }
247
248
249
250
251
252
253 public TableName getTable() {
254
255
256
257 return tableName;
258 }
259
260
261
262
263
264
265 public byte [] getStartRow() {
266 return startRow;
267 }
268
269
270
271
272
273
274 public byte [] getEndRow() {
275 return endRow;
276 }
277
278
279
280
281
282
283 public String getRegionLocation() {
284 return regionLocation;
285 }
286
287
288
289
290
291
292
293 @Override
294 public String[] getLocations() {
295 return new String[] {regionLocation};
296 }
297
298
299
300
301
302
303 public String getEncodedRegionName() {
304 return encodedRegionName;
305 }
306
307
308
309
310
311
312
313 @Override
314 public long getLength() {
315 return length;
316 }
317
318
319
320
321
322
323
324 @Override
325 public void readFields(DataInput in) throws IOException {
326 Version version = Version.UNVERSIONED;
327
328
329
330
331
332
333
334
335 int len = WritableUtils.readVInt(in);
336 if (len < 0) {
337
338 version = Version.fromCode(len);
339 len = WritableUtils.readVInt(in);
340 }
341 byte[] tableNameBytes = new byte[len];
342 in.readFully(tableNameBytes);
343 tableName = TableName.valueOf(tableNameBytes);
344 startRow = Bytes.readByteArray(in);
345 endRow = Bytes.readByteArray(in);
346 regionLocation = Bytes.toString(Bytes.readByteArray(in));
347 if (version.atLeast(Version.INITIAL)) {
348 scan = Bytes.toString(Bytes.readByteArray(in));
349 }
350 length = WritableUtils.readVLong(in);
351 if (version.atLeast(Version.WITH_ENCODED_REGION_NAME)) {
352 encodedRegionName = Bytes.toString(Bytes.readByteArray(in));
353 }
354 }
355
356
357
358
359
360
361
362 @Override
363 public void write(DataOutput out) throws IOException {
364 WritableUtils.writeVInt(out, VERSION.code);
365 Bytes.writeByteArray(out, tableName.getName());
366 Bytes.writeByteArray(out, startRow);
367 Bytes.writeByteArray(out, endRow);
368 Bytes.writeByteArray(out, Bytes.toBytes(regionLocation));
369 Bytes.writeByteArray(out, Bytes.toBytes(scan));
370 WritableUtils.writeVLong(out, length);
371 Bytes.writeByteArray(out, Bytes.toBytes(encodedRegionName));
372 }
373
374
375
376
377
378
379
380 @Override
381 public String toString() {
382 StringBuilder sb = new StringBuilder();
383 sb.append("HBase table split(");
384 sb.append("table name: ").append(tableName);
385
386 String printScan = "";
387 if (!scan.equals("")) {
388 try {
389
390 printScan = TableMapReduceUtil.convertStringToScan(scan).toString();
391 }
392 catch (IOException e) {
393 printScan = "";
394 }
395 }
396 sb.append(", scan: ").append(printScan);
397 sb.append(", start row: ").append(Bytes.toStringBinary(startRow));
398 sb.append(", end row: ").append(Bytes.toStringBinary(endRow));
399 sb.append(", region location: ").append(regionLocation);
400 sb.append(", encoded region name: ").append(encodedRegionName);
401 sb.append(")");
402 return sb.toString();
403 }
404
405
406
407
408
409
410
411
412 @Override
413 public int compareTo(TableSplit split) {
414
415
416 int tableNameComparison =
417 getTable().compareTo(split.getTable());
418 return tableNameComparison != 0 ? tableNameComparison : Bytes.compareTo(
419 getStartRow(), split.getStartRow());
420 }
421
422 @Override
423 public boolean equals(Object o) {
424 if (o == null || !(o instanceof TableSplit)) {
425 return false;
426 }
427 return tableName.equals(((TableSplit)o).tableName) &&
428 Bytes.equals(startRow, ((TableSplit)o).startRow) &&
429 Bytes.equals(endRow, ((TableSplit)o).endRow) &&
430 regionLocation.equals(((TableSplit)o).regionLocation);
431 }
432
433 @Override
434 public int hashCode() {
435 int result = tableName != null ? tableName.hashCode() : 0;
436 result = 31 * result + (scan != null ? scan.hashCode() : 0);
437 result = 31 * result + (startRow != null ? Arrays.hashCode(startRow) : 0);
438 result = 31 * result + (endRow != null ? Arrays.hashCode(endRow) : 0);
439 result = 31 * result + (regionLocation != null ? regionLocation.hashCode() : 0);
440 result = 31 * result + (encodedRegionName != null ? encodedRegionName.hashCode() : 0);
441 return result;
442 }
443 }