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