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.classification.InterfaceAudience;
29 import org.apache.hadoop.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
86
87 public TableSplit() {
88 this((TableName)null, null, HConstants.EMPTY_BYTE_ARRAY,
89 HConstants.EMPTY_BYTE_ARRAY, "");
90 }
91
92
93
94
95 @Deprecated
96 public TableSplit(final byte [] tableName, Scan scan, byte [] startRow, byte [] endRow,
97 final String location) {
98 this(TableName.valueOf(tableName), scan, startRow, endRow, location);
99 }
100
101
102
103
104
105
106
107
108
109
110 public TableSplit(TableName tableName, Scan scan, byte [] startRow, byte [] endRow,
111 final String location) {
112 this.tableName = tableName;
113 try {
114 this.scan =
115 (null == scan) ? "" : TableMapReduceUtil.convertScanToString(scan);
116 } catch (IOException e) {
117 LOG.warn("Failed to convert Scan to String", e);
118 }
119 this.startRow = startRow;
120 this.endRow = endRow;
121 this.regionLocation = location;
122 }
123
124
125
126
127 @Deprecated
128 public TableSplit(final byte [] tableName, byte[] startRow, byte[] endRow,
129 final String location) {
130 this(TableName.valueOf(tableName), startRow, endRow, location);
131 }
132
133
134
135
136
137
138
139
140
141 public TableSplit(TableName tableName, byte[] startRow, byte[] endRow,
142 final String location) {
143 this(tableName, null, startRow, endRow, location);
144 }
145
146
147
148
149
150
151
152 public Scan getScan() throws IOException {
153 return TableMapReduceUtil.convertStringToScan(this.scan);
154 }
155
156
157
158
159
160
161 public byte [] getTableName() {
162 return tableName.getName();
163 }
164
165
166
167
168
169
170 public TableName getTable() {
171
172
173
174 return tableName;
175 }
176
177
178
179
180
181
182 public byte [] getStartRow() {
183 return startRow;
184 }
185
186
187
188
189
190
191 public byte [] getEndRow() {
192 return endRow;
193 }
194
195
196
197
198
199
200 public String getRegionLocation() {
201 return regionLocation;
202 }
203
204
205
206
207
208
209
210 @Override
211 public String[] getLocations() {
212 return new String[] {regionLocation};
213 }
214
215
216
217
218
219
220
221 @Override
222 public long getLength() {
223
224 return 0;
225 }
226
227
228
229
230
231
232
233 @Override
234 public void readFields(DataInput in) throws IOException {
235 Version version = Version.UNVERSIONED;
236
237
238
239
240
241
242
243
244 int len = WritableUtils.readVInt(in);
245 if (len < 0) {
246
247 version = Version.fromCode(len);
248 len = WritableUtils.readVInt(in);
249 }
250 byte[] tableNameBytes = new byte[len];
251 in.readFully(tableNameBytes);
252 tableName = TableName.valueOf(tableNameBytes);
253 startRow = Bytes.readByteArray(in);
254 endRow = Bytes.readByteArray(in);
255 regionLocation = Bytes.toString(Bytes.readByteArray(in));
256 if (version.atLeast(Version.INITIAL)) {
257 scan = Bytes.toString(Bytes.readByteArray(in));
258 }
259 }
260
261
262
263
264
265
266
267 @Override
268 public void write(DataOutput out) throws IOException {
269 WritableUtils.writeVInt(out, VERSION.code);
270 Bytes.writeByteArray(out, tableName.getName());
271 Bytes.writeByteArray(out, startRow);
272 Bytes.writeByteArray(out, endRow);
273 Bytes.writeByteArray(out, Bytes.toBytes(regionLocation));
274 Bytes.writeByteArray(out, Bytes.toBytes(scan));
275 }
276
277
278
279
280
281
282
283 @Override
284 public String toString() {
285 return regionLocation + ":" +
286 Bytes.toStringBinary(startRow) + "," + Bytes.toStringBinary(endRow);
287 }
288
289
290
291
292
293
294
295
296 @Override
297 public int compareTo(TableSplit split) {
298
299
300 int tableNameComparison =
301 getTable().compareTo(split.getTable());
302 return tableNameComparison != 0 ? tableNameComparison : Bytes.compareTo(
303 getStartRow(), split.getStartRow());
304 }
305
306 @Override
307 public boolean equals(Object o) {
308 if (o == null || !(o instanceof TableSplit)) {
309 return false;
310 }
311 return tableName.equals(((TableSplit)o).tableName) &&
312 Bytes.equals(startRow, ((TableSplit)o).startRow) &&
313 Bytes.equals(endRow, ((TableSplit)o).endRow) &&
314 regionLocation.equals(((TableSplit)o).regionLocation);
315 }
316
317 @Override
318 public int hashCode() {
319 int result = tableName != null ? tableName.hashCode() : 0;
320 result = 31 * result + (scan != null ? scan.hashCode() : 0);
321 result = 31 * result + (startRow != null ? Arrays.hashCode(startRow) : 0);
322 result = 31 * result + (endRow != null ? Arrays.hashCode(endRow) : 0);
323 result = 31 * result + (regionLocation != null ? regionLocation.hashCode() : 0);
324 return result;
325 }
326 }