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 final int code;
58 static final Version[] byCode;
59 static {
60 byCode = Version.values();
61 for (int i = 0; i < byCode.length; i++) {
62 if (byCode[i].code != -1 * i) {
63 throw new AssertionError("Values in this enum should be descending by one");
64 }
65 }
66 }
67
68 Version(int code) {
69 this.code = code;
70 }
71
72 boolean atLeast(Version other) {
73 return code <= other.code;
74 }
75
76 static Version fromCode(int code) {
77 return byCode[code * -1];
78 }
79 }
80
81 private static final Version VERSION = Version.INITIAL;
82 private TableName tableName;
83 private byte [] startRow;
84 private byte [] endRow;
85 private String regionLocation;
86 private String scan = "";
87 private long length;
88
89
90 public TableSplit() {
91 this((TableName)null, null, HConstants.EMPTY_BYTE_ARRAY,
92 HConstants.EMPTY_BYTE_ARRAY, "");
93 }
94
95
96
97
98
99
100
101 @Deprecated
102 public TableSplit(final byte [] tableName, Scan scan, byte [] startRow, byte [] endRow,
103 final String location) {
104 this(TableName.valueOf(tableName), scan, startRow, endRow, location);
105 }
106
107
108
109
110
111
112
113
114
115
116
117 public TableSplit(TableName tableName, Scan scan, byte [] startRow, byte [] endRow,
118 final String location) {
119 this(tableName, scan, startRow, endRow, location, 0L);
120 }
121
122
123
124
125
126
127
128
129
130
131 public TableSplit(TableName tableName, Scan scan, byte [] startRow, byte [] endRow,
132 final String location, long length) {
133 this.tableName = tableName;
134 try {
135 this.scan =
136 (null == scan) ? "" : TableMapReduceUtil.convertScanToString(scan);
137 } catch (IOException e) {
138 LOG.warn("Failed to convert Scan to String", e);
139 }
140 this.startRow = startRow;
141 this.endRow = endRow;
142 this.regionLocation = location;
143 this.length = length;
144 }
145
146
147
148
149
150
151
152 @Deprecated
153 public TableSplit(final byte [] tableName, byte[] startRow, byte[] endRow,
154 final String location) {
155 this(TableName.valueOf(tableName), startRow, endRow, location);
156 }
157
158
159
160
161
162
163
164
165
166 public TableSplit(TableName tableName, byte[] startRow, byte[] endRow,
167 final String location) {
168 this(tableName, null, startRow, endRow, location);
169 }
170
171
172
173
174
175
176
177
178
179
180 public TableSplit(TableName tableName, byte[] startRow, byte[] endRow,
181 final String location, long length) {
182 this(tableName, null, startRow, endRow, location, length);
183 }
184
185
186
187
188
189
190
191 public Scan getScan() throws IOException {
192 return TableMapReduceUtil.convertStringToScan(this.scan);
193 }
194
195
196
197
198
199
200 public byte [] getTableName() {
201 return tableName.getName();
202 }
203
204
205
206
207
208
209 public TableName getTable() {
210
211
212
213 return tableName;
214 }
215
216
217
218
219
220
221 public byte [] getStartRow() {
222 return startRow;
223 }
224
225
226
227
228
229
230 public byte [] getEndRow() {
231 return endRow;
232 }
233
234
235
236
237
238
239 public String getRegionLocation() {
240 return regionLocation;
241 }
242
243
244
245
246
247
248
249 @Override
250 public String[] getLocations() {
251 return new String[] {regionLocation};
252 }
253
254
255
256
257
258
259
260 @Override
261 public long getLength() {
262 return length;
263 }
264
265
266
267
268
269
270
271 @Override
272 public void readFields(DataInput in) throws IOException {
273 Version version = Version.UNVERSIONED;
274
275
276
277
278
279
280
281
282 int len = WritableUtils.readVInt(in);
283 if (len < 0) {
284
285 version = Version.fromCode(len);
286 len = WritableUtils.readVInt(in);
287 }
288 byte[] tableNameBytes = new byte[len];
289 in.readFully(tableNameBytes);
290 tableName = TableName.valueOf(tableNameBytes);
291 startRow = Bytes.readByteArray(in);
292 endRow = Bytes.readByteArray(in);
293 regionLocation = Bytes.toString(Bytes.readByteArray(in));
294 if (version.atLeast(Version.INITIAL)) {
295 scan = Bytes.toString(Bytes.readByteArray(in));
296 }
297 length = WritableUtils.readVLong(in);
298 }
299
300
301
302
303
304
305
306 @Override
307 public void write(DataOutput out) throws IOException {
308 WritableUtils.writeVInt(out, VERSION.code);
309 Bytes.writeByteArray(out, tableName.getName());
310 Bytes.writeByteArray(out, startRow);
311 Bytes.writeByteArray(out, endRow);
312 Bytes.writeByteArray(out, Bytes.toBytes(regionLocation));
313 Bytes.writeByteArray(out, Bytes.toBytes(scan));
314 WritableUtils.writeVLong(out, length);
315 }
316
317
318
319
320
321
322
323 @Override
324 public String toString() {
325 StringBuilder sb = new StringBuilder();
326 sb.append("HBase table split(");
327 sb.append("table name: ").append(tableName);
328 sb.append(", scan: ").append(scan);
329 sb.append(", start row: ").append(Bytes.toStringBinary(startRow));
330 sb.append(", end row: ").append(Bytes.toStringBinary(endRow));
331 sb.append(", region location: ").append(regionLocation);
332 sb.append(")");
333 return sb.toString();
334 }
335
336
337
338
339
340
341
342
343 @Override
344 public int compareTo(TableSplit split) {
345
346
347 int tableNameComparison =
348 getTable().compareTo(split.getTable());
349 return tableNameComparison != 0 ? tableNameComparison : Bytes.compareTo(
350 getStartRow(), split.getStartRow());
351 }
352
353 @Override
354 public boolean equals(Object o) {
355 if (o == null || !(o instanceof TableSplit)) {
356 return false;
357 }
358 return tableName.equals(((TableSplit)o).tableName) &&
359 Bytes.equals(startRow, ((TableSplit)o).startRow) &&
360 Bytes.equals(endRow, ((TableSplit)o).endRow) &&
361 regionLocation.equals(((TableSplit)o).regionLocation);
362 }
363
364 @Override
365 public int hashCode() {
366 int result = tableName != null ? tableName.hashCode() : 0;
367 result = 31 * result + (scan != null ? scan.hashCode() : 0);
368 result = 31 * result + (startRow != null ? Arrays.hashCode(startRow) : 0);
369 result = 31 * result + (endRow != null ? Arrays.hashCode(endRow) : 0);
370 result = 31 * result + (regionLocation != null ? regionLocation.hashCode() : 0);
371 return result;
372 }
373 }