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.HConstants;
31 import org.apache.hadoop.hbase.client.Scan;
32 import org.apache.hadoop.hbase.util.Bytes;
33 import org.apache.hadoop.io.Writable;
34 import org.apache.hadoop.io.WritableUtils;
35 import org.apache.hadoop.mapreduce.InputSplit;
36
37
38
39
40
41 @InterfaceAudience.Public
42 @InterfaceStability.Evolving
43 public class TableSplit extends InputSplit
44 implements Writable, Comparable<TableSplit> {
45 public static final Log LOG = LogFactory.getLog(TableSplit.class);
46
47
48
49 enum Version {
50 UNVERSIONED(0),
51
52 INITIAL(-1);
53
54 final int code;
55 static final Version[] byCode;
56 static {
57 byCode = Version.values();
58 for (int i = 0; i < byCode.length; i++) {
59 if (byCode[i].code != -1 * i) {
60 throw new AssertionError("Values in this enum should be descending by one");
61 }
62 }
63 }
64
65 Version(int code) {
66 this.code = code;
67 }
68
69 boolean atLeast(Version other) {
70 return code <= other.code;
71 }
72
73 static Version fromCode(int code) {
74 return byCode[code * -1];
75 }
76 }
77
78 private static final Version VERSION = Version.INITIAL;
79 private byte [] tableName;
80 private byte [] startRow;
81 private byte [] endRow;
82 private String regionLocation;
83 private String scan = "";
84
85
86 public TableSplit() {
87 this(HConstants.EMPTY_BYTE_ARRAY, null, HConstants.EMPTY_BYTE_ARRAY,
88 HConstants.EMPTY_BYTE_ARRAY, "");
89 }
90
91
92
93
94
95
96
97
98
99
100 public TableSplit(byte [] tableName, Scan scan, byte [] startRow, byte [] endRow,
101 final String location) {
102 this.tableName = tableName;
103 try {
104 this.scan =
105 (null == scan) ? "" : TableMapReduceUtil.convertScanToString(scan);
106 } catch (IOException e) {
107 LOG.warn("Failed to convert Scan to String", e);
108 }
109 this.startRow = startRow;
110 this.endRow = endRow;
111 this.regionLocation = location;
112 }
113
114
115
116
117
118
119
120
121
122 public TableSplit(byte[] tableName, byte[] startRow, byte[] endRow,
123 final String location) {
124 this(tableName, null, startRow, endRow, location);
125 }
126
127
128
129
130
131
132
133 public Scan getScan() throws IOException {
134 return TableMapReduceUtil.convertStringToScan(this.scan);
135 }
136
137
138
139
140
141
142 public byte [] getTableName() {
143 return tableName;
144 }
145
146
147
148
149
150
151 public byte [] getStartRow() {
152 return startRow;
153 }
154
155
156
157
158
159
160 public byte [] getEndRow() {
161 return endRow;
162 }
163
164
165
166
167
168
169 public String getRegionLocation() {
170 return regionLocation;
171 }
172
173
174
175
176
177
178
179 @Override
180 public String[] getLocations() {
181 return new String[] {regionLocation};
182 }
183
184
185
186
187
188
189
190 @Override
191 public long getLength() {
192
193 return 0;
194 }
195
196
197
198
199
200
201
202 @Override
203 public void readFields(DataInput in) throws IOException {
204 Version version = Version.UNVERSIONED;
205
206
207
208
209
210
211
212
213 int len = WritableUtils.readVInt(in);
214 if (len < 0) {
215
216 version = Version.fromCode(len);
217 len = WritableUtils.readVInt(in);
218 }
219 tableName = new byte[len];
220 in.readFully(tableName);
221 startRow = Bytes.readByteArray(in);
222 endRow = Bytes.readByteArray(in);
223 regionLocation = Bytes.toString(Bytes.readByteArray(in));
224 if (version.atLeast(Version.INITIAL)) {
225 scan = Bytes.toString(Bytes.readByteArray(in));
226 }
227 }
228
229
230
231
232
233
234
235 @Override
236 public void write(DataOutput out) throws IOException {
237 WritableUtils.writeVInt(out, VERSION.code);
238 Bytes.writeByteArray(out, tableName);
239 Bytes.writeByteArray(out, startRow);
240 Bytes.writeByteArray(out, endRow);
241 Bytes.writeByteArray(out, Bytes.toBytes(regionLocation));
242 Bytes.writeByteArray(out, Bytes.toBytes(scan));
243 }
244
245
246
247
248
249
250
251 @Override
252 public String toString() {
253 return regionLocation + ":" +
254 Bytes.toStringBinary(startRow) + "," + Bytes.toStringBinary(endRow);
255 }
256
257
258
259
260
261
262
263
264 @Override
265 public int compareTo(TableSplit split) {
266
267
268 int tableNameComparison =
269 Bytes.compareTo(getTableName(), split.getTableName());
270 return tableNameComparison != 0 ? tableNameComparison : Bytes.compareTo(
271 getStartRow(), split.getStartRow());
272 }
273
274 @Override
275 public boolean equals(Object o) {
276 if (o == null || !(o instanceof TableSplit)) {
277 return false;
278 }
279 return Bytes.equals(tableName, ((TableSplit)o).tableName) &&
280 Bytes.equals(startRow, ((TableSplit)o).startRow) &&
281 Bytes.equals(endRow, ((TableSplit)o).endRow) &&
282 regionLocation.equals(((TableSplit)o).regionLocation);
283 }
284
285 @Override
286 public int hashCode() {
287 int result = tableName != null ? Arrays.hashCode(tableName) : 0;
288 result = 31 * result + (scan != null ? scan.hashCode() : 0);
289 result = 31 * result + (startRow != null ? Arrays.hashCode(startRow) : 0);
290 result = 31 * result + (endRow != null ? Arrays.hashCode(endRow) : 0);
291 result = 31 * result + (regionLocation != null ? regionLocation.hashCode() : 0);
292 return result;
293 }
294 }